From c7effe53b0e21b55dab203039ab2282b54611c09 Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Thu, 24 Mar 2022 17:17:47 -0700 Subject: [PATCH 1/2] convert to testing-library --- .../ChoiceGroup/ChoiceGroup.test.tsx | 165 +- .../__snapshots__/ChoiceGroup.test.tsx.snap | 1666 +++++++++-------- 2 files changed, 913 insertions(+), 918 deletions(-) diff --git a/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx b/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx index e879074607c67..40f6279aa5b0d 100644 --- a/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx +++ b/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx @@ -1,48 +1,34 @@ import * as React from 'react'; -import { mount, ReactWrapper } from 'enzyme'; -import * as ReactTestUtils from 'react-dom/test-utils'; -import * as renderer from 'react-test-renderer'; +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { ChoiceGroup } from './ChoiceGroup'; import { merge, resetIds } from '../../Utilities'; -import { safeMount } from '@fluentui/test-utilities'; import { isConformant } from '../../common/isConformant'; -import type { IChoiceGroupOption, IChoiceGroup, IChoiceGroupProps } from './ChoiceGroup.types'; +import type { IChoiceGroupOption, IChoiceGroup } from './ChoiceGroup.types'; const TEST_OPTIONS: IChoiceGroupOption[] = [ { key: '1', text: '1', 'data-automation-id': 'auto1', autoFocus: true } as IChoiceGroupOption, { key: '2', text: '2' }, { key: '3', text: '3' }, ]; -const CHOICE_QUERY_SELECTOR = '.ms-ChoiceField-input'; describe('ChoiceGroup', () => { - let choiceGroup: ReactWrapper | undefined; - beforeEach(() => { // Resetting ids to create predictability in generated ids. resetIds(); }); - afterEach(() => { - if (choiceGroup) { - choiceGroup.unmount(); - choiceGroup = undefined; - } - }); - it('renders ChoiceGroup correctly', () => { - const component = renderer.create(); - const tree = component.toJSON(); - expect(tree).toMatchSnapshot(); + const { container } = render(); + expect(container).toMatchSnapshot(); }); it('renders ChoiceGroup with label correctly', () => { - const component = renderer.create( + const { container } = render( , ); - const tree = component.toJSON(); - expect(tree).toMatchSnapshot(); + expect(container).toMatchSnapshot(); }); isConformant({ @@ -51,19 +37,19 @@ describe('ChoiceGroup', () => { }); it('does not use className prop from parent on label', () => { - choiceGroup = mount(); - const label = choiceGroup.getDOMNode().querySelector('label'); + const { container } = render( + , + ); + const label = container.querySelector('label'); expect(label).toBeTruthy(); expect(label!.textContent).toBe('test label'); expect(label!.className).not.toContain('testClassName'); }); it('can change options', () => { - choiceGroup = mount(); + const { getAllByRole } = render(); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceOptions.length).toBe(3); @@ -71,19 +57,19 @@ describe('ChoiceGroup', () => { expect(choiceOptions[1].checked).toEqual(false); expect(choiceOptions[2].checked).toEqual(false); - ReactTestUtils.Simulate.change(choiceOptions[0]); + userEvent.click(choiceOptions[0]); expect(choiceOptions[0].checked).toEqual(true); expect(choiceOptions[1].checked).toEqual(false); expect(choiceOptions[2].checked).toEqual(false); - ReactTestUtils.Simulate.change(choiceOptions[1]); + userEvent.click(choiceOptions[1]); expect(choiceOptions[0].checked).toEqual(false); expect(choiceOptions[1].checked).toEqual(true); expect(choiceOptions[2].checked).toEqual(false); - ReactTestUtils.Simulate.change(choiceOptions[0]); + userEvent.click(choiceOptions[0]); expect(choiceOptions[0].checked).toEqual(true); expect(choiceOptions[1].checked).toEqual(false); @@ -94,11 +80,9 @@ describe('ChoiceGroup', () => { const options: IChoiceGroupOption[] = merge([], TEST_OPTIONS); options[0].disabled = true; - choiceGroup = mount(); + const { getAllByRole } = render(); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceOptions[0].disabled).toEqual(true); expect(choiceOptions[1].disabled).toEqual(false); @@ -106,27 +90,26 @@ describe('ChoiceGroup', () => { }); it('renders all choice options as disabled when disabled', () => { - choiceGroup = mount(); + const { getAllByRole } = render( + , + ); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceOptions[0].disabled).toEqual(true); expect(choiceOptions[1].disabled).toEqual(true); expect(choiceOptions[2].disabled).toEqual(true); }); + /* Testing that the defaultSelectedKey is working correctly. */ it('can act as an uncontrolled component', () => { - choiceGroup = mount(); + const { getAllByRole } = render(); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceOptions[0].checked).toEqual(true); - ReactTestUtils.Simulate.change(choiceOptions[1]); + userEvent.click(choiceOptions[1]); expect(choiceOptions[1].checked).toEqual(true); }); @@ -140,15 +123,13 @@ describe('ChoiceGroup', () => { _selectedItem = item; }; - choiceGroup = mount(); + const { getAllByRole } = render(); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceOptions[0].checked).toEqual(true); - ReactTestUtils.Simulate.change(choiceOptions[1]); + userEvent.click(choiceOptions[1]); expect(choiceOptions[0].checked).toEqual(true); expect(choiceOptions[1].checked).toEqual(false); @@ -162,11 +143,9 @@ describe('ChoiceGroup', () => { item: IChoiceGroupOption | undefined, ): void => undefined; - choiceGroup = mount(); + const { getAllByRole } = render(); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; const extraAttributeGetter: (index: number) => string | null = (index: number): string | null => { const input: HTMLInputElement = choiceOptions[index]; @@ -178,24 +157,24 @@ describe('ChoiceGroup', () => { }); it('can set role attribute to empty string', () => { - choiceGroup = mount(); - const role = choiceGroup.getDOMNode().getAttribute('role'); + const { container } = render(); + const role = container.querySelector('.ms-ChoiceFieldGroup')!.getAttribute('role'); expect(role).toEqual(''); }); it('can set role attribute on the containing element', () => { - choiceGroup = mount(); - const role = choiceGroup.getDOMNode().getAttribute('role'); + const { container } = render(); + const role = container.querySelector('.ms-ChoiceFieldGroup')!.getAttribute('role'); expect(role).toEqual('Test'); }); it('can assign a custom aria label', () => { const option4: IChoiceGroupOption[] = [{ key: '4', text: '4', ariaLabel: 'Custom aria label' }]; - choiceGroup = mount(); + const { getAllByRole } = render( + , + ); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceOptions.length).toBe(4); @@ -207,80 +186,74 @@ describe('ChoiceGroup', () => { it('returns the current checked option with user interaction', () => { const choiceGroupRef = React.createRef(); - choiceGroup = mount(); + const { getAllByRole } = render(); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceGroupRef.current!.checkedOption).toBeUndefined(); - ReactTestUtils.Simulate.change(choiceOptions[0]); + userEvent.click(choiceOptions[0]); expect(choiceGroupRef.current!.checkedOption).toEqual(TEST_OPTIONS[0]); }); it('returns the current checked option with defaultSelectedKey', () => { const choiceGroupRef = React.createRef(); - choiceGroup = mount(); + const { getAllByRole } = render( + , + ); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceGroupRef.current!.checkedOption).toEqual(TEST_OPTIONS[0]); - ReactTestUtils.Simulate.change(choiceOptions[1]); + userEvent.click(choiceOptions[1]); expect(choiceGroupRef.current!.checkedOption).toEqual(TEST_OPTIONS[1]); }); it('returns the current checked option with selectedKey', () => { const choiceGroupRef = React.createRef(); - choiceGroup = mount(); + const { getAllByRole } = render( + , + ); - const choiceOptions = choiceGroup - .getDOMNode() - .querySelectorAll(CHOICE_QUERY_SELECTOR) as NodeListOf; + const choiceOptions = getAllByRole('radio') as HTMLInputElement[]; expect(choiceGroupRef.current!.checkedOption).toEqual(TEST_OPTIONS[0]); - ReactTestUtils.Simulate.change(choiceOptions[1]); + userEvent.click(choiceOptions[1]); // selectedKey is still used even though it didn't get updated for latest user click expect(choiceGroupRef.current!.checkedOption).toEqual(TEST_OPTIONS[0]); }); it('can render element id', () => { - choiceGroup = mount(); - expect(choiceGroup.getDOMNode().getAttribute('id')).toBe('foo'); + const { container } = render(); + const root = container.querySelector('.ms-ChoiceFieldGroup'); + expect(root!.getAttribute('id')).toBe('foo'); }); it('can focus the checked option', () => { - // This test has to mount the element to the document since ChoiceGroup.focus() uses document.getElementById() const choiceGroupRef = React.createRef(); - safeMount( + const { getAllByRole } = render( , - choiceGroup2 => { - const option = choiceGroup2.getDOMNode().querySelector(CHOICE_QUERY_SELECTOR) as HTMLInputElement; - const focusSpy = jest.spyOn(option, 'focus'); - - choiceGroupRef.current!.focus(); - expect(focusSpy).toHaveBeenCalled(); - }, - true /* attach */, ); + + const option = getAllByRole('radio')[0] as HTMLInputElement; + const focusSpy = jest.spyOn(option, 'focus'); + + choiceGroupRef.current!.focus(); + expect(focusSpy).toHaveBeenCalled(); }); it('can focus the first enabled option', () => { const choiceGroupRef = React.createRef(); - safeMount( + const { getAllByRole } = render( , - choiceGroup2 => { - const option = choiceGroup2.getDOMNode().querySelectorAll(CHOICE_QUERY_SELECTOR)![1] as HTMLInputElement; - const focusSpy = jest.spyOn(option, 'focus'); - - choiceGroupRef.current!.focus(); - expect(focusSpy).toHaveBeenCalled(); - }, - true /* attach */, ); + + const option = getAllByRole('radio')[1] as HTMLInputElement; + const focusSpy = jest.spyOn(option, 'focus'); + + choiceGroupRef.current!.focus(); + expect(focusSpy).toHaveBeenCalled(); }); }); diff --git a/packages/react/src/components/ChoiceGroup/__snapshots__/ChoiceGroup.test.tsx.snap b/packages/react/src/components/ChoiceGroup/__snapshots__/ChoiceGroup.test.tsx.snap index 4b1f090baf874..f7498915d1b76 100644 --- a/packages/react/src/components/ChoiceGroup/__snapshots__/ChoiceGroup.test.tsx.snap +++ b/packages/react/src/components/ChoiceGroup/__snapshots__/ChoiceGroup.test.tsx.snap @@ -1,431 +1,442 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ChoiceGroup renders ChoiceGroup correctly 1`] = ` -
+
- - + + 1 + + +
-
-
- - + + 2 + + +
-
-
- - + + 3 + + +
@@ -434,465 +445,476 @@ exports[`ChoiceGroup renders ChoiceGroup correctly 1`] = ` `; exports[`ChoiceGroup renders ChoiceGroup with label correctly 1`] = ` -
+
-
-
+ test label + +
- - + + 1 + + +
-
-
- - + + 2 + + +
-
-
- - + + 3 + + +
From 4f6ff43c528651bc0d40e068a038da24f14b43ed Mon Sep 17 00:00:00 2001 From: Tristan Watanabe Date: Tue, 29 Mar 2022 11:37:13 -0700 Subject: [PATCH 2/2] remove usage of queryselector --- .../components/ChoiceGroup/ChoiceGroup.test.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx b/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx index 40f6279aa5b0d..f665643408139 100644 --- a/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx +++ b/packages/react/src/components/ChoiceGroup/ChoiceGroup.test.tsx @@ -37,10 +37,10 @@ describe('ChoiceGroup', () => { }); it('does not use className prop from parent on label', () => { - const { container } = render( + const { getByRole } = render( , ); - const label = container.querySelector('label'); + const label = getByRole('radiogroup').firstElementChild; expect(label).toBeTruthy(); expect(label!.textContent).toBe('test label'); expect(label!.className).not.toContain('testClassName'); @@ -158,14 +158,14 @@ describe('ChoiceGroup', () => { it('can set role attribute to empty string', () => { const { container } = render(); - const role = container.querySelector('.ms-ChoiceFieldGroup')!.getAttribute('role'); + const role = container.firstElementChild!.getAttribute('role'); expect(role).toEqual(''); }); it('can set role attribute on the containing element', () => { - const { container } = render(); - const role = container.querySelector('.ms-ChoiceFieldGroup')!.getAttribute('role'); - expect(role).toEqual('Test'); + const { container } = render(); + const role = container.firstElementChild!.getAttribute('role'); + expect(role).toEqual('radiogroup'); }); it('can assign a custom aria label', () => { @@ -224,7 +224,7 @@ describe('ChoiceGroup', () => { it('can render element id', () => { const { container } = render(); - const root = container.querySelector('.ms-ChoiceFieldGroup'); + const root = container.firstElementChild; expect(root!.getAttribute('id')).toBe('foo'); });