import * as React from 'react'; import Checkbox from './Checkbox'; import {render, waitFor} from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import {testA11y} from '../../../axe'; describe('', () => { // @ts-ignore TS7006 const renderCheckbox = props => render( jest.fn()} {...props} />); it('renders unchecked checkbox input, without label', () => { const checkbox = renderCheckbox({}); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; expect(checkboxInput.checked).toBe(false); expect(checkbox.queryByLabelText('my label')).toBeNull(); }); it('has an accessible name when children provided', () => { const label = 'label'; const checkbox = renderCheckbox({ children: label, }); expect( checkbox.getByRole('checkbox', { name: label, }) ).toBeTruthy(); }); it('has an accessible name when no children provided but is wrapped in a custom label', () => { const label = 'label'; const checkbox = render( ); expect( checkbox.getByRole('checkbox', { name: label, }) ).toBeTruthy(); }); it('checks/unchecks when either checkbox, input or label is clicked or space is pressed', () => { const checkbox = renderCheckbox({ children: 'my label', }); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; expect(checkboxInput.checked).toBe(false); userEvent.click(checkbox.getByLabelText('my label')); expect(checkboxInput).toEqual(document.activeElement); expect(checkboxInput.checked).toBe(true); userEvent.keyboard('{space}'); expect(checkboxInput.checked).toBe(false); userEvent.click(checkbox.getByText('my label')); expect(checkboxInput.checked).toBe(true); }); it('it renders as initially checked', () => { const checkbox = renderCheckbox({ defaultChecked: true, }); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; expect(checkboxInput.checked).toBe(true); }); it('it renders as initially unchecked', () => { const checkbox = renderCheckbox({ defaultChecked: false, }); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; expect(checkboxInput.checked).toBe(false); }); it('it displays error message and description', () => { const descriptionText = 'Cool checkbox it is'; const errorMessageText = 'Oops.'; const checkbox = renderCheckbox({ id: 'myid', description: descriptionText, invalid: true, errorMessage: errorMessageText, children: 'Click me pls', }); const checkboxInput = checkbox.getByRole('checkbox'); expect(checkboxInput.id).toEqual('myid'); expect(checkbox.getByText(descriptionText)).toBeTruthy(); expect(checkbox.getByText(descriptionText).id).toEqual('myid-description'); expect(checkbox.getByText(errorMessageText)).toBeTruthy(); expect(checkbox.getByText(errorMessageText).id).toEqual('myid-errorText'); }); it("it doesn't allow checking/unchecking disabled checkbox", () => { const labelText = 'Click me pls'; const onChange = jest.fn(); const checkbox = renderCheckbox({ children: labelText, checked: true, disabled: true, onChange, }); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; expect(checkboxInput.checked).toBe(true); userEvent.click(checkboxInput); expect(onChange).not.toHaveBeenCalled(); expect(checkboxInput.checked).toBe(true); userEvent.click(checkbox.getByLabelText(labelText)); expect(onChange).not.toHaveBeenCalled(); expect(checkboxInput.checked).toBe(true); }); it("it doesn't check/uncheck when either description or error message is clicked", () => { const descriptionText = 'Cool checkbox it is'; const errorMessageText = 'Oops.'; const labelText = 'Click me pls'; const checkbox = renderCheckbox({ description: descriptionText, invalid: true, errorMessage: errorMessageText, children: labelText, defaultChecked: false, }); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; expect(checkboxInput.checked).toBe(false); userEvent.click(checkbox.getByText(descriptionText)); expect(checkboxInput.checked).toBe(false); userEvent.click(checkbox.getByText(errorMessageText)); expect(checkboxInput.checked).toBe(false); }); it('it does not apply animation unless initial state has changed after first render of DOM', async () => { const checkbox = renderCheckbox({ defaultChecked: false, children: 'my label', }); const checkboxInput = checkbox.getByRole('checkbox') as HTMLInputElement; const iconWithAnimation = checkbox.container.getElementsByClassName( 'sg-checkbox__icon--with-animation' ); expect(checkboxInput.checked).toBe(false); expect(iconWithAnimation.length).toBe(0); setTimeout(() => { userEvent.click(checkbox.getByLabelText('my label')); }); await waitFor(() => { expect(checkboxInput).toEqual(document.activeElement); }); expect(checkboxInput.checked).toBe(true); await waitFor(() => { expect(iconWithAnimation.length).toBe(1); }); }); describe('a11y', () => { it('should have no a11y violations when children is provided', async () => { await testA11y(item); }); it('should have no a11y violations when it has a custom label', async () => { await testA11y( ); }); it('should have no a11y violations when it is checked', async () => { await testA11y(item); }); it('should have no a11y violations when it is required', async () => { await testA11y(item); }); it('should have no a11y violations when it is invalid and has error message', async () => { await testA11y( item ); }); }); });