import * as React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { ComponentClassNames } from '../../shared'; import { DEFAULT_ROW_COUNT, TextAreaField } from '../TextAreaField'; import { testFlexProps, expectFlexContainerStyleProps, } from '../../Flex/__tests__/Flex.test'; import { AUTO_GENERATED_ID_PREFIX } from '../../utils/useStableId'; const label = 'Field'; const testId = 'testId'; describe('TextAreaField component', () => { describe('wrapper Flex', () => { it('should render default and custom classname', async () => { const customClassName = 'my-textareafield'; render( ); const field = await screen.findByTestId(testId); expect(field).toHaveClass(customClassName); expect(field).toHaveClass(ComponentClassNames.Field); expect(field).toHaveClass(ComponentClassNames.TextAreaField); }); it('should render all flex style props', async () => { render( ); const field = await screen.findByTestId('testId'); expectFlexContainerStyleProps(field); }); }); describe('Label', () => { it('should render expected field classname', async () => { render(); const label = await screen.findByText('Field'); expect(label).toHaveClass(ComponentClassNames.Label); }); it('should have `amplify-visually-hidden` class when labelHidden is true', async () => { render(); const label = await screen.findByText('Search'); expect(label).toHaveClass('amplify-visually-hidden'); }); }); describe('TextArea field', () => { it('should render labeled textarea when id is provided', async () => { render( ); const field = await screen.findByLabelText(label); expect(field.tagName).toBe('TEXTAREA'); expect(field).toHaveClass(ComponentClassNames.Textarea); expect(field.id).toBe('testField'); }); it('should forward ref to DOM element', async () => { const ref = React.createRef(); render(); await screen.findByLabelText(label); expect(ref?.current?.nodeName).toBe('TEXTAREA'); }); it('should render labeled input when id is not provided, and is autogenerated', async () => { render(); const field = await screen.findByLabelText(label); expect(field.id.startsWith(AUTO_GENERATED_ID_PREFIX)).toBe(true); expect(field).toHaveClass(ComponentClassNames.Textarea); }); it('should render the state attributes', async () => { render( ); const field = await screen.findByRole('textbox'); expect(field).toHaveAttribute('disabled', ''); expect(field).toHaveAttribute('readonly', ''); expect(field).toHaveAttribute('required', ''); expect(field).toHaveAttribute('rows', DEFAULT_ROW_COUNT.toString()); }); it('should render the rows attributes', async () => { const rowCount = 10; render(); const field = await screen.findByRole('textbox'); expect(field).toHaveAttribute('rows', String(rowCount)); }); it('should set size and variation data attributes', async () => { render( ); const textAreaField = await screen.findByTestId('testField'); const textArea = await screen.findByRole('textbox'); expect(textAreaField).toHaveAttribute('data-size', 'small'); expect(textArea).toHaveAttribute('data-variation', 'quiet'); }); it('should render size classes for TextAreaField', async () => { render(
); const small = await screen.findByTestId('small'); const large = await screen.findByTestId('large'); expect(small.classList).toContain( `${ComponentClassNames['Field']}--small` ); expect(large.classList).toContain( `${ComponentClassNames['Field']}--large` ); }); it('can set defaultValue', async () => { render(); const field = await screen.findByRole('textbox'); expect(field.value).toBe('test'); }); it('show add aria-invalid attribute to textarea when hasError', async () => { render( ); const field = await screen.findByRole('textbox'); expect(field).toHaveAttribute('aria-invalid'); }); it('should set resize style property', async () => { render(); const field = await screen.findByRole('textbox'); expect(field).toHaveStyle('resize: horizontal'); }); it('should fire event handlers', async () => { const onChange = jest.fn(); const onInput = jest.fn(); const onPaste = jest.fn(); render( ); const field = await screen.findByRole('textbox'); userEvent.type(field, 'hello'); userEvent.paste(field, 'there'); expect(onChange).toHaveBeenCalled(); expect(onInput).toHaveBeenCalled(); expect(onPaste).toHaveBeenCalled(); }); }); describe('error messages', () => { const errorMessage = 'This is an error message'; it("don't show when hasError is false", () => { render( ); const errorText = screen.queryByText(errorMessage); expect(errorText).not.toBeInTheDocument(); }); it('show when hasError and errorMessage', () => { render( ); const errorText = screen.queryByText(errorMessage); expect(errorText?.innerHTML).toContain(errorMessage); }); }); describe('descriptive message', () => { it('renders when descriptiveText is provided', () => { render( ); const descriptiveText = screen.queryByText('Description'); expect(descriptiveText?.innerHTML).toContain('Description'); }); it('should map to descriptive text correctly', async () => { const descriptiveText = 'Description'; render( ); const field = await screen.findByRole('textbox'); expect(field).toHaveAccessibleDescription(descriptiveText); }); }); });