From 1ad5e1b479748597bc52fcf2695646c30ce89748 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 7 Feb 2024 16:57:23 -0600 Subject: [PATCH] test: update Checkbox tests to use react testing library --- .../src/components/Checkbox/index.js | 140 ------------------ .../src/components/Checkbox/Checkbox.test.tsx | 114 ++++++++++++++ 2 files changed, 114 insertions(+), 140 deletions(-) delete mode 100644 packages/react/__tests__/src/components/Checkbox/index.js create mode 100644 packages/react/src/components/Checkbox/Checkbox.test.tsx diff --git a/packages/react/__tests__/src/components/Checkbox/index.js b/packages/react/__tests__/src/components/Checkbox/index.js deleted file mode 100644 index 429a65742..000000000 --- a/packages/react/__tests__/src/components/Checkbox/index.js +++ /dev/null @@ -1,140 +0,0 @@ -import React from 'react'; -import sinon from 'sinon'; -import { mount } from 'enzyme'; -import Checkbox from 'src/components/Checkbox'; -import axe from '../../../axe'; - -const defaultProps = { - id: 'boognish', - name: 'boognish', - value: 'boognish', - label: 'Boognish' -}; - -test('handles checked prop', () => { - const wrapper = mount(); - expect( - wrapper.find('.Icon.Checkbox__overlay').hasClass('Icon--checkbox-checked') - ).toBeTruthy(); - expect( - wrapper.find('.Icon.Checkbox__overlay').hasClass('Icon--checkbox-unchecked') - ).toBeFalsy(); - expect(wrapper.find('[type="checkbox"]').getDOMNode().checked).toBeTruthy(); - expect(wrapper.find('.Error').exists()).toBe(false); -}); - -test('handles checked prop changes', done => { - const wrapper = mount(); - wrapper.setProps({ - checked: false - }); - setTimeout(() => { - expect(wrapper.find('[type="checkbox"]').getDOMNode().checked).toBeFalsy(); - done(); - }, 10); -}); - -test('toggles checked state properly', done => { - const wrapper = mount(); - const checkbox = wrapper.find('[type="checkbox"]'); - expect(checkbox.getDOMNode().checked).toBeFalsy(); - expect( - wrapper.find('.Icon.Checkbox__overlay').hasClass('Icon--checkbox-checked') - ).toBeFalsy(); - - checkbox.simulate('change', { target: { checked: true } }); - - setTimeout(() => { - expect(checkbox.getDOMNode().checked).toBeTruthy(); - expect( - wrapper.find('.Icon.Checkbox__overlay').hasClass('Icon--checkbox-checked') - ).toBeTruthy(); - done(); - }, 10); -}); - -test('clicks the checkbox when the overlay is clicked', () => { - let clicked = false; - const wrapper = mount(); - wrapper - .find('[type="checkbox"]') - .getDOMNode() - .addEventListener('click', () => { - clicked = true; - }); - wrapper.find('Icon.Checkbox__overlay').simulate('click'); - expect(clicked).toBeTruthy(); -}); - -test('handles disabled prop', () => { - const wrapper = mount(); - - expect(wrapper.find('[type="checkbox"]').getDOMNode().disabled).toBeTruthy(); - expect(wrapper.find('.Field__label--disabled').exists()).toBeTruthy(); -}); - -test('handles focus/blur', () => { - const onFocus = sinon.spy(); - const onBlur = sinon.spy(); - - const wrapper = mount( - - ); - - wrapper.find('[type="checkbox"]').simulate('focus'); - - expect(wrapper.find('.Checkbox__overlay--focused').exists()).toBeTruthy(); - expect(onFocus.calledOnce).toBe(true); - - wrapper.find('[type="checkbox"]').simulate('blur'); - - expect(wrapper.find('.Checkbox__overlay--focused').exists()).toBeFalsy(); - expect(onBlur.calledOnce).toBe(true); -}); - -test('call onChange when checked state changes', done => { - const onChange = e => { - expect(e).toBeTruthy(); - done(); - }; - - const wrapper = mount(); - wrapper - .find('[type="checkbox"]') - .at(0) - .simulate('change'); -}); - -test('supports ref prop', done => { - const ref = checkbox => { - expect(checkbox).toBeNull(); - done(); - }; - - mount(); -}); - -test('should return no axe violations', async () => { - const wrapper = mount(); - expect(await axe(wrapper.html())).toHaveNoViolations(); -}); - -test('handles error prop', async () => { - const wrapper = mount(); - expect(await axe(wrapper.html())).toHaveNoViolations(); - const errorMessage = wrapper.find('.Error').getDOMNode(); - const input = wrapper.find('input').getDOMNode(); - expect(input.getAttribute('aria-describedby')).toBe(errorMessage.id); -}); - -test('handles labelDescription prop', async () => { - const wrapper = mount( - - ); - expect(await axe(wrapper.html())).toHaveNoViolations(); - const labelDescription = wrapper - .find('.Field__labelDescription') - .getDOMNode(); - const input = wrapper.find('input').getDOMNode(); - expect(input.getAttribute('aria-describedby')).toBe(labelDescription.id); -}); diff --git a/packages/react/src/components/Checkbox/Checkbox.test.tsx b/packages/react/src/components/Checkbox/Checkbox.test.tsx new file mode 100644 index 000000000..5ca5d5321 --- /dev/null +++ b/packages/react/src/components/Checkbox/Checkbox.test.tsx @@ -0,0 +1,114 @@ +import React, { createRef } from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { spy } from 'sinon'; +import { axe } from 'jest-axe'; +import Checkbox from './'; + +type SetOptional = Pick, Keys> & + Omit; +type CheckboxProps = SetOptional< + React.ComponentProps, + 'label' | 'id' +>; + +const renderCheckbox = ({ + label, + ...props +}: CheckboxProps = {}): HTMLInputElement => { + render(); + // no individual assertions needed, as this should throw if the element does not exist + return screen.getByRole('checkbox', { name: label as string }); +}; + +test('should render unchecked checkbox', () => { + const input = renderCheckbox({ label: 'this is a checkbox' }); + expect(input).not.toBeChecked(); + expect(screen.queryByText('this is a checkbox')).toBeInTheDocument(); +}); + +test('should render checked checkbox', () => { + const input = renderCheckbox({ checked: true }); + expect(input).toBeChecked(); +}); + +test('should render disabled unchecked checkbox', () => { + const input = renderCheckbox({ disabled: true }); + expect(input).toBeDisabled(); + expect(input).not.toBeChecked(); +}); + +test('should render disabled checked checkbox', () => { + const input = renderCheckbox({ disabled: true, checked: true }); + expect(input).toBeDisabled(); + expect(input).toBeChecked(); +}); + +test('should render error checkbox', () => { + const input = renderCheckbox({ error: 'you should check this checkbox' }); + expect(input).toHaveAccessibleDescription('you should check this checkbox'); + expect( + screen.queryByText('you should check this checkbox') + ).toBeInTheDocument(); +}); + +test('should support ref prop', () => { + const ref = createRef(); + render(); + expect(ref.current).toBeInstanceOf(HTMLInputElement); + expect(ref.current).toEqual( + screen.queryByRole('checkbox', { name: 'checkbox' }) + ); +}); + +test('should support className prop', () => { + const input = renderCheckbox({ className: 'banana' }); + expect(input.parentElement).toHaveClass('Checkbox', 'banana'); +}); + +test('should support value prop', () => { + render( +
+ + + + ); + const form = screen.getByTestId('form'); + expect(form).toHaveFormValues({ checkbox: ['bananas'] }); +}); + +test('should support labelDescription prop', () => { + const input = renderCheckbox({ + labelDescription: 'more stuff and things you should know' + }); + expect(input).toHaveAccessibleDescription( + /more stuff and things you should know/ + ); + expect( + screen.queryByText('more stuff and things you should know') + ).toBeInTheDocument(); +}); + +test('should have no axe violations with unchecked checkbox', async () => { + const input = renderCheckbox(); + const results = await axe(input); + expect(results).toHaveNoViolations(); +}); + +test('should have no axe violations with checked checkbox', async () => { + const input = renderCheckbox({ checked: true }); + const results = await axe(input); + expect(results).toHaveNoViolations(); +}); + +test('should have no axe violations when checkbox has errors', async () => { + const input = renderCheckbox({ error: 'you should check this checkbox' }); + const results = await axe(input); + expect(results).toHaveNoViolations(); +});