From 2bc88fa52fe0167bf352d661f0fb68e0f18f3141 Mon Sep 17 00:00:00 2001 From: Marin Atanasov Date: Thu, 18 Aug 2022 15:14:35 +0300 Subject: [PATCH 1/4] Components: Refactor Guide tests to @testing-library/react --- packages/components/src/guide/index.js | 4 +- packages/components/src/guide/test/index.js | 106 +++++++++++++------- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/packages/components/src/guide/index.js b/packages/components/src/guide/index.js index 32bd6cadaeae9a..91e4b0d147ff18 100644 --- a/packages/components/src/guide/index.js +++ b/packages/components/src/guide/index.js @@ -42,7 +42,9 @@ export default function Guide( { useEffect( () => { // Each time we change the current page, start from the first element of the page. // This also solves any focus loss that can happen. - focus.tabbable.find( guideContainer.current )?.[ 0 ]?.focus(); + if ( guideContainer.current ) { + focus.tabbable.find( guideContainer.current )?.[ 0 ]?.focus(); + } }, [ currentPage ] ); if ( Children.count( children ) ) { diff --git a/packages/components/src/guide/test/index.js b/packages/components/src/guide/test/index.js index 0e38f63c20037e..846f277c2fe357 100644 --- a/packages/components/src/guide/test/index.js +++ b/packages/components/src/guide/test/index.js @@ -1,23 +1,22 @@ /** * External dependencies */ -import { shallow } from 'enzyme'; +import { fireEvent, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; /** * Internal dependencies */ import Guide from '../'; -import PageControl from '../page-control'; -import Modal from '../../modal'; describe( 'Guide', () => { it( 'renders nothing when there are no pages', () => { - const wrapper = shallow( ); - expect( wrapper.isEmptyRender() ).toBe( true ); + render( ); + expect( screen.queryByRole( 'dialog' ) ).not.toBeInTheDocument(); } ); it( 'renders one page at a time', () => { - const wrapper = shallow( + render( Page 1

}, @@ -25,11 +24,14 @@ describe( 'Guide', () => { ] } /> ); - expect( wrapper.find( 'p' ) ).toHaveLength( 1 ); + + expect( screen.queryByRole( 'dialog' ) ).toBeVisible(); + expect( screen.queryByText( 'Page 1' ) ).toBeVisible(); + expect( screen.queryByText( 'Page 2' ) ).not.toBeInTheDocument(); } ); it( 'hides back button and shows forward button on the first page', () => { - const wrapper = shallow( + render( Page 1

}, @@ -37,20 +39,23 @@ describe( 'Guide', () => { ] } /> ); - expect( wrapper.find( PageControl ).prop( 'currentPage' ) ).toBe( 0 ); - expect( wrapper.find( '.components-guide__back-button' ) ).toHaveLength( - 0 - ); + + expect( + screen.queryByRole( 'button', { name: 'Previous' } ) + ).not.toBeInTheDocument(); expect( - wrapper.find( '.components-guide__forward-button' ) - ).toHaveLength( 1 ); + screen.queryByRole( 'button', { name: 'Next' } ) + ).toBeVisible(); expect( - wrapper.find( '.components-guide__finish-button' ) - ).toHaveLength( 0 ); + screen.queryByRole( 'button', { name: 'Finish' } ) + ).not.toBeInTheDocument(); } ); - it( 'shows back button and shows finish button on the last page', () => { - const wrapper = shallow( + it( 'shows back button and shows finish button on the last page', async () => { + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); + render( Page 1

}, @@ -58,47 +63,76 @@ describe( 'Guide', () => { ] } /> ); - wrapper.find( '.components-guide__forward-button' ).simulate( 'click' ); - expect( wrapper.find( PageControl ).prop( 'currentPage' ) ).toBe( 1 ); - expect( wrapper.find( '.components-guide__back-button' ) ).toHaveLength( - 1 - ); + await user.click( screen.getByRole( 'button', { name: 'Next' } ) ); + + expect( screen.queryByText( 'Page 1' ) ).not.toBeInTheDocument(); + expect( screen.queryByText( 'Page 2' ) ).toBeVisible(); + expect( - wrapper.find( '.components-guide__forward-button' ) - ).toHaveLength( 0 ); + screen.queryByRole( 'button', { name: 'Previous' } ) + ).toBeVisible(); expect( - wrapper.find( '.components-guide__finish-button' ) - ).toHaveLength( 1 ); + screen.queryByRole( 'button', { name: 'Next' } ) + ).not.toBeInTheDocument(); + expect( + screen.queryByRole( 'button', { name: 'Finish' } ) + ).toBeVisible(); } ); it( "doesn't display the page control if there is only one page", () => { - const wrapper = shallow( - Page 1

} ] } /> - ); - expect( wrapper.find( PageControl ).exists() ).toBeFalsy(); + render( Page 1

} ] } /> ); + expect( + screen.queryByRole( 'list', { name: 'Guide controls' } ) + ).not.toBeInTheDocument(); } ); - it( 'calls onFinish when the finish button is clicked', () => { + it( 'calls onFinish when the finish button is clicked', async () => { + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); const onFinish = jest.fn(); - const wrapper = shallow( + render( Page 1

} ] } /> ); - wrapper.find( '.components-guide__finish-button' ).simulate( 'click' ); + await user.click( screen.getByRole( 'button', { name: 'Finish' } ) ); + expect( onFinish ).toHaveBeenCalled(); } ); it( 'calls onFinish when the modal is closed', () => { const onFinish = jest.fn(); - const wrapper = shallow( + render( Page 1

} ] } /> ); - wrapper.find( Modal ).prop( 'onRequestClose' )(); + + /** + * Workaround to trigger an Escape keypress event. + * + * @todo Remove this workaround in favor of userEvent.keyboard() or userEvent.type(). + * + * This curently doesn't work: + * + * ``` + * await user.keyboard( '[Escape]' ); + * ``` + * + * because the event sent has a `keyCode` of `0`. + * + * To fix this, we'll need to update the Modal component to work with `KeyboardEvent.code`. + * + * @see https://github.com/testing-library/user-event/issues/969 + */ + fireEvent.keyDown( screen.getByRole( 'dialog' ), { + key: 'Escape', + keyCode: 27, + } ); + expect( onFinish ).toHaveBeenCalled(); } ); } ); From 87a0958dd2ab7069ccc295a0aa8dd40ea9d991b5 Mon Sep 17 00:00:00 2001 From: Marin Atanasov Date: Thu, 18 Aug 2022 15:19:49 +0300 Subject: [PATCH 2/4] Add changelog --- packages/components/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index d33e0c7bb25cc4..866d333f467693 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -15,6 +15,7 @@ - Ensure all dependencies allow version ranges ([#43355](https://github.com/WordPress/gutenberg/pull/43355)). - `Popover`: make sure offset middleware always applies the latest frame offset values ([#43329](https://github.com/WordPress/gutenberg/pull/43329/)). - `Dropdown`: anchor popover to the dropdown wrapper (instead of the toggle) ([#43377](https://github.com/WordPress/gutenberg/pull/43377/)). +- `Guide`: Fix error when rendering with no pages ([#43380](https://github.com/WordPress/gutenberg/pull/43380/)). ### Enhancements @@ -37,10 +38,12 @@ - `contextConnect`: Refactor away from `_.uniq()` ([#43330](https://github.com/WordPress/gutenberg/pull/43330/)). - `ColorPalette`: Refactor away from `_.uniq()` ([#43330](https://github.com/WordPress/gutenberg/pull/43330/)). - `Guide`: Refactor away from `_.times()` ([#43374](https://github.com/WordPress/gutenberg/pull/43374/)). +- `Guide`: Update tests to use `@testing-library/react` ([#43380](https://github.com/WordPress/gutenberg/pull/43380)). - `Modal`: use `KeyboardEvent.code` instead of deprecated `KeyboardEvent.keyCode`. improve unit tests ([#43429](https://github.com/WordPress/gutenberg/pull/43429/)). ### Experimental - `FormTokenField`: add `__experimentalAutoSelectFirstMatch` prop to auto select the first matching suggestion on typing ([#42527](https://github.com/WordPress/gutenberg/pull/42527/)). +======= ## 19.17.0 (2022-08-10) From f433923c46d0c8050286253775bb3ba2c84c482b Mon Sep 17 00:00:00 2001 From: Marin Atanasov Date: Mon, 22 Aug 2022 12:10:15 +0300 Subject: [PATCH 3/4] fireEvent -> user-event --- packages/components/src/guide/test/index.js | 29 +++++---------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/packages/components/src/guide/test/index.js b/packages/components/src/guide/test/index.js index 846f277c2fe357..bd36752959ff69 100644 --- a/packages/components/src/guide/test/index.js +++ b/packages/components/src/guide/test/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; /** @@ -102,7 +102,10 @@ describe( 'Guide', () => { expect( onFinish ).toHaveBeenCalled(); } ); - it( 'calls onFinish when the modal is closed', () => { + it( 'calls onFinish when the modal is closed', async () => { + const user = userEvent.setup( { + advanceTimers: jest.advanceTimersByTime, + } ); const onFinish = jest.fn(); render( { /> ); - /** - * Workaround to trigger an Escape keypress event. - * - * @todo Remove this workaround in favor of userEvent.keyboard() or userEvent.type(). - * - * This curently doesn't work: - * - * ``` - * await user.keyboard( '[Escape]' ); - * ``` - * - * because the event sent has a `keyCode` of `0`. - * - * To fix this, we'll need to update the Modal component to work with `KeyboardEvent.code`. - * - * @see https://github.com/testing-library/user-event/issues/969 - */ - fireEvent.keyDown( screen.getByRole( 'dialog' ), { - key: 'Escape', - keyCode: 27, - } ); + await user.keyboard( '[Escape]' ); expect( onFinish ).toHaveBeenCalled(); } ); From b47a5f989b3066bcf6c1e5bf1bf393c72b1ffd5a Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Mon, 22 Aug 2022 12:25:00 +0300 Subject: [PATCH 4/4] Clean up after bad rebase Co-authored-by: Marco Ciampini --- packages/components/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 866d333f467693..a36c5e1aaeff8d 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -43,7 +43,6 @@ ### Experimental - `FormTokenField`: add `__experimentalAutoSelectFirstMatch` prop to auto select the first matching suggestion on typing ([#42527](https://github.com/WordPress/gutenberg/pull/42527/)). -======= ## 19.17.0 (2022-08-10)