From 04c4a891692e3e1de8fa3d36b2d65a776f764748 Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Thu, 5 Aug 2021 13:42:23 -0400 Subject: [PATCH 01/11] Switch to using mountWithApp on ResourceItem tests. --- .../ResourceItem/tests/ResourceItem.test.tsx | 317 +++++++++++------- 1 file changed, 197 insertions(+), 120 deletions(-) diff --git a/src/components/ResourceItem/tests/ResourceItem.test.tsx b/src/components/ResourceItem/tests/ResourceItem.test.tsx index 3eb66f9fb10..92ed857caa6 100644 --- a/src/components/ResourceItem/tests/ResourceItem.test.tsx +++ b/src/components/ResourceItem/tests/ResourceItem.test.tsx @@ -1,10 +1,4 @@ import React from 'react'; -// eslint-disable-next-line no-restricted-imports -import { - findByTestID, - mountWithAppProvider, - trigger, -} from 'test-utilities/legacy'; import {mountWithApp} from 'test-utilities'; import { Avatar, @@ -15,8 +9,10 @@ import { Button, } from 'components'; -import {ResourceListContext} from '../../../utilities/resource-list'; import {ResourceItem} from '../ResourceItem'; +import {classNames} from '../../../utilities/css'; +import {ResourceListContext} from '../../../utilities/resource-list'; +import styles from '../ResourceItem.scss'; describe('', () => { let spy: jest.SpyInstance; @@ -77,7 +73,7 @@ describe('', () => { describe('accessibilityLabel', () => { it('is used on the for the aria-label attribute', () => { - const item = mountWithAppProvider( + const item = mountWithApp( ', () => { , ); - expect(item.find(UnstyledLink).prop('aria-label')).toBe( - accessibilityLabel, - ); + expect(item).toContainReactComponent(UnstyledLink, { + 'aria-label': accessibilityLabel, + }); }); }); describe('name', () => { it('is used as the Checkbox label', () => { - const item = mountWithAppProvider( + const item = mountWithApp( ', () => { const expectedLabel = name; - expect(item.find(Checkbox).prop('label')).toBe(expectedLabel); + expect(item).toContainReactComponent(Checkbox, {label: expectedLabel}); }); it('is used on for the aria-label attribute if an `accessibilityLabel` is not provided', () => { - const item = mountWithAppProvider( + const item = mountWithApp( , @@ -120,11 +116,13 @@ describe('', () => { const expectedLabel = `View details for ${name}`; - expect(item.find(UnstyledLink).prop('aria-label')).toBe(expectedLabel); + expect(item).toContainReactComponent(UnstyledLink, { + 'aria-label': expectedLabel, + }); }); it('is used on the disclosure action menu when there are persistent actions', () => { - const item = mountWithAppProvider( + const item = mountWithApp( ', () => { const expectedLabel = `Actions for ${name}`; - expect( - item - .find(Button) - .findWhere( - (node) => - node.prop('plain') && - node.prop('accessibilityLabel') === expectedLabel, - ), - ).toHaveLength(1); + expect(item).toContainReactComponentTimes(Button, 1, { + plain: true, + accessibilityLabel: expectedLabel, + }); }); }); describe('ResourceName.singular', () => { it('is used on for the aria-label attribute if a `name` and `accessibilityLabel` is not provided', () => { - const item = mountWithAppProvider( + const item = mountWithApp( , @@ -161,13 +154,15 @@ describe('', () => { const expectedLabel = `View details for ${mockDefaultContext.resourceName.singular}`; - expect(item.find(UnstyledLink).prop('aria-label')).toBe(expectedLabel); + expect(item).toContainReactComponent(UnstyledLink, { + 'aria-label': expectedLabel, + }); }); }); describe('url', () => { it('does not render an by default', () => { - const element = mountWithAppProvider( + const element = mountWithApp( ', () => { , ); - expect(element.find(UnstyledLink).exists()).toBe(false); + expect(element).not.toContainReactComponent(UnstyledLink); }); it('renders an ', () => { - const element = mountWithAppProvider( + const element = mountWithApp( , ); - expect(element.find(UnstyledLink).exists()).toBe(true); + expect(element).toContainReactComponent(UnstyledLink); }); it('renders an with url', () => { - const element = mountWithAppProvider( + const element = mountWithApp( , ); - expect(element.find(UnstyledLink).prop('url')).toBe(url); + expect(element).toContainReactComponent(UnstyledLink, {url}); }); it('renders an with an aria-label of ariaLabel', () => { - const element = mountWithAppProvider( + const element = mountWithApp( , ); - expect(element.find(UnstyledLink).prop('aria-label')).toBe(ariaLabel); + expect(element).toContainReactComponent(UnstyledLink, { + 'aria-label': ariaLabel, + }); }); it('adds a data-href to the wrapper element', () => { - const element = mountWithAppProvider( + const element = mountWithApp( , ); - expect(findByTestID(element, 'Item-Wrapper').prop('data-href')).toBe(url); + expect(element).toContainReactComponent('div', {'data-href': url}); }); }); describe('external', () => { it('renders an with undefined external prop', () => { - const element = mountWithAppProvider( + const element = mountWithApp( , ); - expect(element.find(UnstyledLink).prop('external')).toBeUndefined(); + expect(element).toContainReactComponent(UnstyledLink, { + external: undefined, + }); }); it('renders an with external set to true', () => { - const element = mountWithAppProvider( + const element = mountWithApp( ', () => { , ); - expect(element.find(UnstyledLink).prop('external')).toBe(true); + expect(element).toContainReactComponent(UnstyledLink, { + external: true, + }); }); it('renders an with external set to false', () => { - const element = mountWithAppProvider( + const element = mountWithApp( ', () => { , ); - expect(element.find(UnstyledLink).prop('external')).toBe(false); + expect(element).toContainReactComponent(UnstyledLink, { + external: false, + }); }); }); describe('id', () => { it('is used on the content node and for the description of a link', () => { - const item = mountWithAppProvider( + const item = mountWithApp( ', () => { , ); - expect(findByTestID(item, 'Item-Content').prop('id')).toBe(itemId); - expect(item.find(UnstyledLink).prop('aria-describedby')).toBe(itemId); + expect(item).toContainReactComponent('div', {id: itemId}); + expect(item).toContainReactComponent(UnstyledLink, { + 'aria-describedby': itemId, + }); }); }); describe('onClick()', () => { it('calls onClick when clicking on the item when onClick exists', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('click'); + wrapper + .find('div', {className: styles.ResourceItem})! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); it('calls onClick when clicking on the item when both onClick and url exist', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('click'); + wrapper + .find('div', {className: styles.ResourceItem})! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); it('calls window.open on metaKey + click', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - const item = findByTestID(wrapper, 'Item-Wrapper'); - trigger(item, 'onClick', { - stopPropagation: () => {}, - nativeEvent: {metaKey: true}, - }); + + wrapper + .find('div', {className: styles.ResourceItem})! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {metaKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); it('calls onClick when hitting keyUp on the item when onClick and URL exists', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('keyup', { - key: 'Enter', - }); + wrapper + .find('div', {className: styles.ResourceItem})! + .trigger('onKeyUp', {key: 'Enter'}); expect(onClick).toHaveBeenCalled(); }); it('does not call onClick when hitting keyUp on non Enter key', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('keyup', { - key: 'Tab', - }); + wrapper + .find('div', {className: styles.ResourceItem})! + .trigger('onKeyUp', {key: 'Tab'}); expect(onClick).not.toHaveBeenCalled(); }); it('does not call onClick when hitting keyUp on the item when no URL exists', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('keyup', { - key: 'Enter', - }); + wrapper + .find('div', { + className: classNames( + styles.ResourceItem, + styles.selectable, + styles.selectMode, + ), + })! + .trigger('onKeyUp', {key: 'Enter'}); expect(onClick).not.toHaveBeenCalled(); }); it('calls window.open on ctrlKey + click', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - const item = findByTestID(wrapper, 'Item-Wrapper'); - trigger(item, 'onClick', { - stopPropagation: () => {}, - nativeEvent: {ctrlKey: true}, - }); + + wrapper + .find('div', {className: styles.ResourceItem})! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {ctrlKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); }); @@ -391,25 +416,29 @@ describe('', () => { describe('Selectable', () => { it('does not call the Item onClick when clicking the LargerSelectionArea', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'LargerSelectionArea').simulate('click'); + wrapper.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).not.toHaveBeenCalled(); }); it('calls onSelectionChange with the id of the item when clicking the LargerSelectionArea', () => { const sortOrder = 0; - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'LargerSelectionArea').simulate('click', { + wrapper.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, nativeEvent: {shiftKey: false}, }); expect(mockSelectableContext.onSelectionChange).toHaveBeenCalledWith( @@ -424,7 +453,7 @@ describe('', () => { describe('SelectMode', () => { it('calls onClick when item is clicked', () => { const onClick = jest.fn(); - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('click'); + wrapper + .find('div', { + className: classNames( + styles.ResourceItem, + styles.selectable, + styles.selectMode, + ), + })! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).not.toHaveBeenCalledWith(itemId); }); it('calls onSelectionChange with the id of the item even if url or onClick is present', () => { const onClick = jest.fn(); const sortOrder = 0; - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('click', { - nativeEvent: {shiftKey: false}, - }); + wrapper + .find('div', { + className: classNames( + styles.ResourceItem, + styles.selectable, + styles.selectMode, + ), + })! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {shiftKey: false}, + }); expect(mockSelectModeContext.onSelectionChange).toHaveBeenCalledWith( true, itemId, @@ -465,69 +514,94 @@ describe('', () => { }); it('renders a checked Checkbox if the item is in the selectedItems context', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - expect(wrapper.find(Checkbox).props().checked).toBe(true); + expect(wrapper).toContainReactComponent(Checkbox, {checked: true}); }); it('does not call window.open when clicking the item with metaKey', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('click', { - nativeEvent: {metaKey: true}, - }); + + wrapper + .find('div', { + className: classNames( + styles.ResourceItem, + styles.selectable, + styles.selected, + styles.selectMode, + ), + })! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {metaKey: true}, + }); expect(spy).not.toHaveBeenCalled(); }); it('does not call window.open when clicking the item with ctrlKey', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - findByTestID(wrapper, 'Item-Wrapper').simulate('click', { - nativeEvent: {ctrlKey: true}, - }); + + wrapper + .find('div', { + className: classNames( + styles.ResourceItem, + styles.selectable, + styles.selected, + styles.selectMode, + ), + })! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {ctrlKey: true}, + }); expect(spy).not.toHaveBeenCalled(); }); }); describe('media', () => { it('does not include media if not provided', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - expect(findByTestID(wrapper, 'Media').exists()).toBe(false); + expect(wrapper).not.toContainReactComponent('div', { + className: styles.Media, + }); }); it('renders a disabled checked Checkbox if loading context is true', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - expect(wrapper.find(Checkbox).prop('disabled')).toBe(true); + expect(wrapper).toContainReactComponent(Checkbox, {disabled: true}); }); it('includes an if one is provided', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( } /> , ); - expect(findByTestID(wrapper, 'Media').find(Avatar).exists()).toBe(true); + const media = wrapper.find('div', {className: styles.Media}); + expect(media).toContainReactComponent(Avatar); }); it('includes a if one is provided', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { /> , ); - expect(findByTestID(wrapper, 'Media').find(Thumbnail).exists()).toBe( - true, - ); + const media = wrapper.find('div', {className: styles.Media}); + expect(media).toContainReactComponent(Thumbnail); }); }); describe('shortcutActions', () => { it('does not render shortcut actions if none are provided', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( , ); - expect(findByTestID(wrapper, 'ShortcutActions').exists()).toBe(false); + expect(wrapper).not.toContainReactComponent('div', { + className: styles.Actions, + }); }); it('renders shortcut actions when some are provided', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { /> , ); - expect(findByTestID(wrapper, 'ShortcutActions').exists()).toBe(true); + expect(wrapper).toContainReactComponent('div', { + className: styles.Actions, + }); }); it('renders persistent shortcut actions if persistActions is true', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { /> , ); - expect(wrapper.find(ButtonGroup).exists()).toBe(true); + expect(wrapper).toContainReactComponent(ButtonGroup); }); it('does not render while loading', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { /> , ); - expect(wrapper.find(ButtonGroup)).toHaveLength(0); + expect(wrapper).not.toContainReactComponent(ButtonGroup); }); }); describe('accessibleMarkup', () => { it('renders with a tab index of -1 when loading is true', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { /> , ); - expect(wrapper.find(UnstyledLink).prop('tabIndex')).toBe(-1); + expect(wrapper).toContainReactComponent(UnstyledLink, {tabIndex: -1}); }); it('renders with a tab index of 0 when loading is false', () => { - const wrapper = mountWithAppProvider( + const wrapper = mountWithApp( ', () => { /> , ); - expect(wrapper.find(UnstyledLink).prop('tabIndex')).toBe(0); + expect(wrapper).toContainReactComponent(UnstyledLink, {tabIndex: 0}); }); }); @@ -711,7 +788,7 @@ describe('', () => { describe('dataHref', () => { it('renders a data-href tag on the li when the dataHref prop is specified', () => { - const item = mountWithAppProvider( + const item = mountWithApp( ', () => { , ); - expect(item.find('li').prop('data-href')).toBe('google.com'); + expect(item).toContainReactComponent('li', {'data-href': 'google.com'}); }); it('renders a data-href tag on the li when the dataHref prop is not specified', () => { - const item = mountWithAppProvider( + const item = mountWithApp( ', () => { , ); - expect(item.find('li').prop('data-href')).toBeUndefined(); + expect(item).toContainReactComponent('li', {'data-href': undefined}); }); }); }); From 3c22e0900fc439c41b8f841967c7a8736ce26e85 Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Thu, 5 Aug 2021 13:50:04 -0400 Subject: [PATCH 02/11] Adding update to UNRELEASED.md --- UNRELEASED.md | 1 + 1 file changed, 1 insertion(+) diff --git a/UNRELEASED.md b/UNRELEASED.md index 8dae4c28da3..24845181cf5 100644 --- a/UNRELEASED.md +++ b/UNRELEASED.md @@ -43,5 +43,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f - Modernized tests for Breadcrumbs, BulkActions, Button, ButtonGroup/Item, and ButtonGroup components([#4315](https://github.com/Shopify/polaris-react/pull/4315)) - Modernized tests for DualThumb ([#4341](https://github.com/Shopify/polaris-react/pull/4341)) - Modernized tests for AppProvider, AfterInitialMount components([#4315](https://github.com/Shopify/polaris-react/pull/4331)) +- Modernized tests for ResourceItem ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) ### Deprecations From 1e1357b66b38416c6783ca948b88e0ea8f308c6a Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Thu, 5 Aug 2021 13:58:06 -0400 Subject: [PATCH 03/11] Removing testID props. --- src/components/ResourceItem/ResourceItem.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/components/ResourceItem/ResourceItem.tsx b/src/components/ResourceItem/ResourceItem.tsx index a514f1b84e2..b25df1af93b 100644 --- a/src/components/ResourceItem/ResourceItem.tsx +++ b/src/components/ResourceItem/ResourceItem.tsx @@ -159,9 +159,7 @@ class BaseResourceItem extends Component { let handleMarkup: React.ReactNode = null; const mediaMarkup = media ? ( -
- {media} -
+
{media}
) : null; if (selectable) { @@ -177,7 +175,6 @@ class BaseResourceItem extends Component {
{ } else { actionsMarkup = (
- + {buttonsFrom(shortcutActions, { size: 'slim', })} @@ -282,11 +279,7 @@ class BaseResourceItem extends Component { ); const containerMarkup = ( -
+
{ownedMarkup} {content} {actionsMarkup} @@ -335,7 +328,6 @@ class BaseResourceItem extends Component { onBlur={this.handleBlur} onKeyUp={this.handleKeyUp} onMouseOut={this.handleMouseOut} - testID="Item-Wrapper" data-href={url} > {accessibleMarkup} From 32528322a7e517eac1eff359997db26df60ad3a7 Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Thu, 5 Aug 2021 17:27:58 -0400 Subject: [PATCH 04/11] Fixing type-checking errors. --- .../ResourceItem/tests/ResourceItem.test.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/ResourceItem/tests/ResourceItem.test.tsx b/src/components/ResourceItem/tests/ResourceItem.test.tsx index 92ed857caa6..5292af4745d 100644 --- a/src/components/ResourceItem/tests/ResourceItem.test.tsx +++ b/src/components/ResourceItem/tests/ResourceItem.test.tsx @@ -214,7 +214,8 @@ describe('', () => { , ); - expect(element).toContainReactComponent('div', {'data-href': url}); + const div = element.find('div', {'data-href': url} as any); + expect(div).not.toBeNull(); }); }); @@ -798,9 +799,10 @@ describe('', () => { /> , ); - - expect(item).toContainReactComponent('li', {'data-href': 'google.com'}); + const li = item.find('li', {'data-href': 'google.com'} as any); + expect(li).not.toBeNull(); }); + it('renders a data-href tag on the li when the dataHref prop is not specified', () => { const item = mountWithApp( @@ -812,7 +814,8 @@ describe('', () => { , ); - expect(item).toContainReactComponent('li', {'data-href': undefined}); + const li = item.find('li', {'data-href': undefined} as any); + expect(li).not.toBeNull(); }); }); }); From 2bf6d95db6977ff4e0d7953965090d317b3963cc Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Mon, 9 Aug 2021 13:40:52 -0400 Subject: [PATCH 05/11] Modernizing tests for ResourceList. --- UNRELEASED.md | 1 + src/components/ResourceItem/ResourceItem.tsx | 6 +- src/components/ResourceList/ResourceList.tsx | 6 +- .../ResourceList/tests/ResourceList.test.tsx | 567 ++++++++++-------- 4 files changed, 324 insertions(+), 256 deletions(-) diff --git a/UNRELEASED.md b/UNRELEASED.md index 24845181cf5..60000410de6 100644 --- a/UNRELEASED.md +++ b/UNRELEASED.md @@ -44,5 +44,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f - Modernized tests for DualThumb ([#4341](https://github.com/Shopify/polaris-react/pull/4341)) - Modernized tests for AppProvider, AfterInitialMount components([#4315](https://github.com/Shopify/polaris-react/pull/4331)) - Modernized tests for ResourceItem ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) +- Modernized tests for ResourceItem, ResourceList ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) ### Deprecations diff --git a/src/components/ResourceItem/ResourceItem.tsx b/src/components/ResourceItem/ResourceItem.tsx index b25df1af93b..74b8ef983c5 100644 --- a/src/components/ResourceItem/ResourceItem.tsx +++ b/src/components/ResourceItem/ResourceItem.tsx @@ -167,11 +167,7 @@ class BaseResourceItem extends Component { name || accessibilityLabel || i18n.translate('Polaris.Common.checkbox'); handleMarkup = ( -
+
({ ) : null; const headerTitleMarkup = ( -
- {headerTitle()} -
+
{headerTitle()}
); const selectButtonMarkup = isSelectable ? ( @@ -639,7 +637,7 @@ export const ResourceList: ResourceListType = function ResourceList({ isSticky && styles['HeaderWrapper-isSticky'], ); return ( -
+
{headerWrapperOverlay}
diff --git a/src/components/ResourceList/tests/ResourceList.test.tsx b/src/components/ResourceList/tests/ResourceList.test.tsx index a11c9548803..8edf82934ce 100644 --- a/src/components/ResourceList/tests/ResourceList.test.tsx +++ b/src/components/ResourceList/tests/ResourceList.test.tsx @@ -10,17 +10,15 @@ import { EmptyState, } from 'components'; import {mountWithApp} from 'test-utilities'; -// eslint-disable-next-line no-restricted-imports -import { - findByTestID, - mountWithAppProvider, - trigger, -} from 'test-utilities/legacy'; import {SELECT_ALL_ITEMS} from 'utilities/resource-list'; import {BulkActions} from '../../BulkActions'; import {CheckableButton} from '../../CheckableButton'; +import {classNames} from '../../../utilities/css'; + +import styles from '../ResourceList.scss'; + const itemsNoID = [{url: 'item 1'}, {url: 'item 2'}]; const singleItemNoID = [{url: 'item 1'}]; const singleItemWithID = [{id: '1', url: 'item 1'}]; @@ -53,10 +51,10 @@ const defaultWindowWidth = window.innerWidth; describe('', () => { describe('renderItem', () => { it('renders list items', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find('li')).toHaveLength(3); + expect(resourceList).toContainReactComponentTimes('li', 3); }); it('renders custom markup and warns user', () => { @@ -64,10 +62,11 @@ describe('', () => { const warningSpy = jest .spyOn(console, 'warn') .mockImplementation(() => {}); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find('li').first().text()).toBe('title 1'); + expect(resourceList).toContainReactText('title 1'); + // expect(resourceList.find('li').first().text()).toBe('title 1'); expect(warningSpy).toHaveBeenCalledWith( ' renderItem function should return a .', ); @@ -78,66 +77,65 @@ describe('', () => { describe('Selectable', () => { it('does not render bulk actions if the promotedBulkActions and the bulkActions props are not provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(BulkActions).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(BulkActions); }); it('does not render a `CheckableButton` if the `selectable` prop is not provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(CheckableButton).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(CheckableButton); }); it('does render bulk actions if the promotedBulkActions prop is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - - expect(resourceList.find(BulkActions).exists()).toBe(true); + expect(resourceList).toContainReactComponent(BulkActions); }); it('renders bulk actions if the bulkActions prop is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(BulkActions).exists()).toBe(true); + expect(resourceList).toContainReactComponent(BulkActions); }); it('renders a `CheckableButton` if the `selectable` prop is true', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(CheckableButton).exists()).toBe(true); + expect(resourceList).toContainReactComponent(CheckableButton); }); }); describe('hasMoreItems', () => { it('does not add a prop of paginatedSelectAllAction to BulkActions if omitted', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect( - resourceList.find(BulkActions).prop('paginatedSelectAllAction'), - ).toBeUndefined(); + expect(resourceList).toContainReactComponent(BulkActions, { + paginatedSelectAllAction: undefined, + }); }); it('adds a prop of paginatedSelectAllAction to BulkActions if included', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { bulkActions={bulkActions} />, ); + expect(resourceList).toContainReactComponent(BulkActions); expect( - resourceList.find(BulkActions).prop('paginatedSelectAllAction'), - ).toBeDefined(); + resourceList.find(BulkActions)!.props.paginatedSelectAllAction, + ).not.toBe(undefined); }); }); describe('resourceName', () => { describe('resoureName.singular', () => { it('renders default singular resource name when resourceName isn’t provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 1 item', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 1 item'); }); it('renders the given singular resource name when resourceName is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { showHeader />, ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 1 product', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 1 product'); }); }); - describe('resoureName.plural', () => { + describe('resourceName.plural', () => { it('renders default plural resource name when resourceName isn’t provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 2 items', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 2 items'); }); it('renders the given plural resource name when resourceName is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { showHeader />, ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 2 products', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 2 products'); }); }); }); describe('headerTitle', () => { it('prints loading text when loading is true', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Loading items', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Loading items'); }); it('prints number of items shown when totalItemsCount is not provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 2 products', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 2 products'); }); it('prints number of items shown of totalItemsCount when totalItemsCount is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 2 of 5 products', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 2 of 5 products'); }); it('prints number of items shown of totalItemsCount plural when totalItemsCount is provided and items is one resource', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(findByTestID(resourceList, 'headerTitleWrapper').text()).toBe( - 'Showing 1 of 5 products', - ); + const headerTitleWrapper = resourceList.find('div', { + className: styles.HeaderTitleWrapper, + }); + expect(headerTitleWrapper).toContainReactText('Showing 1 of 5 products'); }); }); describe('bulkActionsAccessibilityLabel', () => { it('provides the BulkActions with the right accessibilityLabel if there’s 1 item and it isn’t selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(BulkActions).prop('accessibilityLabel')).toBe( - 'Select item', - ); + expect(resourceList).toContainReactComponent(BulkActions, { + accessibilityLabel: 'Select item', + }); }); it('provides the BulkActions with the right accessibilityLabel if there’s 1 item and it is selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { selectedItems={['1']} />, ); - expect(resourceList.find(BulkActions).prop('accessibilityLabel')).toBe( - 'Deselect item', - ); + expect(resourceList).toContainReactComponent(BulkActions, { + accessibilityLabel: 'Deselect item', + }); }); it('provides the BulkActions with the right accessibilityLabel if there are multiple items and they are selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { selectedItems={['5', '6', '7']} />, ); - expect(resourceList.find(BulkActions).prop('accessibilityLabel')).toBe( - 'Deselect all 3 items', - ); + expect(resourceList).toContainReactComponent(BulkActions, { + accessibilityLabel: 'Deselect all 3 items', + }); }); + it('provides the BulkActions with the right accessibilityLabel if there’s multiple items and some or none are selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(BulkActions).prop('accessibilityLabel')).toBe( - 'Select all 3 items', - ); + expect(resourceList).toContainReactComponent(BulkActions, { + accessibilityLabel: 'Select all 3 items', + }); }); }); describe('onSelectionChange()', () => { it('calls onSelectionChange() when an item is clicked', () => { const onSelectionChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { onSelectionChange={onSelectionChange} />, ); - const firstItem = resourceList.find(ResourceItem).first(); - findByTestID(firstItem, 'LargerSelectionArea').simulate('click'); + resourceList.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onSelectionChange).toHaveBeenCalled(); }); }); describe('header markup', () => { it('renders header markup if the list isn’t selectable but the showHeader prop is true', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - true, - ); + expect(resourceList).toContainReactComponent('div', { + className: styles.HeaderWrapper, + }); }); it('doesn’t render header markup if the list is selectable but the showHeader prop is false', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - false, - ); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderWrapper, + }); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderContentWrapper, + }); }); it('does not render when items is empty', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - false, - ); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderWrapper, + }); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderContentWrapper, + }); }); it('renders when sort options are given', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - true, - ); + expect(resourceList).toContainReactComponent('div', { + className: classNames( + styles.HeaderWrapper, + styles['HeaderWrapper-hasSort'], + ), + }); }); it('renders when an alternateTool is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - true, - ); + expect(resourceList).toContainReactComponent('div', { + className: classNames( + styles.HeaderWrapper, + styles['HeaderWrapper-hasAlternateTool'], + ), + }); }); it('renders when bulkActions are given', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - true, - ); + expect(resourceList).toContainReactComponent('div', { + className: classNames( + styles.HeaderWrapper, + styles['HeaderWrapper-hasSelect'], + ), + }); }); it('renders when promotedBulkActions are given', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - true, - ); + expect(resourceList).toContainReactComponent('div', { + className: classNames( + styles.HeaderWrapper, + styles['HeaderWrapper-hasSelect'], + ), + }); }); it('does not render when sort options, bulkActions and promotedBulkActions are not given', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(findByTestID(resourceList, 'ResourceList-Header').exists()).toBe( - false, - ); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderWrapper, + }); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderContentWrapper, + }); }); it('renders on non-initial load when items are provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - - expect(findByTestID(resourceList, 'ResourceList-Header')).toHaveLength(0); + // initially not rendered + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderWrapper, + }); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderContentWrapper, + }); + // update props resourceList.setProps({items: itemsWithID}); - resourceList.update(); - expect(findByTestID(resourceList, 'ResourceList-Header')).toHaveLength(1); + // now it's rendered + expect(resourceList).toContainReactComponent('div', { + className: classNames( + styles.HeaderWrapper, + styles['HeaderWrapper-hasSelect'], + ), + }); }); it('does not render when EmptySearchResult exists', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( fake filterControl
} />, ); - - expect(resourceList.find(EmptySearchResult).exists()).toBe(true); - expect(findByTestID(resourceList, 'ResourceList-Header')).toHaveLength(0); + expect(resourceList).toContainReactComponent(EmptySearchResult); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderWrapper, + }); + expect(resourceList).not.toContainReactComponent('div', { + className: styles.HeaderContentWrapper, + }); }); }); describe('filterControl', () => { it('renders when exists', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( Test
} />, ); - expect(resourceList.find('#test123').exists()).toBe(true); + expect(resourceList).toContainReactComponent('div', {id: 'test123'}); }); }); @@ -497,7 +542,7 @@ describe('', () => { ); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(EmptyState)).toHaveLength(1); + expect(resourceList).toContainReactComponentTimes(EmptyState, 1); }); it('does not render when exists but items are provided', () => { @@ -522,7 +567,7 @@ describe('', () => { ); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(EmptyState)).toHaveLength(0); + expect(resourceList).not.toContainReactComponent(EmptyState); }); it('does not render when exists, items is empty, but loading is true', () => { @@ -547,7 +592,7 @@ describe('', () => { ); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(EmptyState)).toHaveLength(0); + expect(resourceList).not.toContainReactComponent(EmptyState); }); }); describe('', () => { it('renders when filterControl exists and items is empty', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( fake filterControl
} />, ); - expect(resourceList.find(EmptySearchResult).exists()).toBe(true); + expect(resourceList).toContainReactComponent(EmptySearchResult); }); it('does not render when filterControl does not exist', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(EmptySearchResult).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(EmptySearchResult); }); it('does not render when items is not empty', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( Test
} />, ); - expect(resourceList.find(EmptySearchResult).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(EmptySearchResult); }); it('does not render when filterControl exists, items is empty, and loading is true', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { loading />, ); - expect(resourceList.find(EmptySearchResult).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(EmptySearchResult); }); it('does not render when filterControl exists, items is empty, and emptyState is set', () => { @@ -616,7 +661,7 @@ describe('', () => { ); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(EmptySearchResult).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(EmptySearchResult); }); it('renders the provided markup when emptySearchState is set', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(EmptySearchResult).exists()).toBe(false); - expect(resourceList.find('div#emptySearchState').exists()).toBe(true); + expect(resourceList).not.toContainReactComponent(EmptySearchResult); + expect(resourceList).toContainReactComponent('div', { + id: 'emptySearchState', + }); }); }); describe('Sorting', () => { it('does not render a sort select if sortOptions aren’t provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find(Select).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(Select); }); it('renders a sort select if sortOptions are provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - expect(resourceList.find(Select).exists()).toBe(true); + expect(resourceList).toContainReactComponent(Select); }); it('does not render a sort select if an alternateTool is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { alternateTool={alternateTool} />, ); - expect(resourceList.find(Select).exists()).toBe(false); + expect(resourceList).not.toContainReactComponent(Select); }); describe('sortOptions', () => { it('passes a sortOptions to the Select options', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - expect(resourceList.find(Select).props()).toHaveProperty( - 'options', - sortOptions, - ); + expect(resourceList).toContainReactComponent(Select, { + options: sortOptions, + }); }); }); describe('sortValue', () => { it('passes a sortValue to the Select value', () => { const onSortChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - expect(resourceList.find(Select).props()).toHaveProperty( - 'value', - 'sortValue', - ); + expect(resourceList).toContainReactComponent(Select, { + value: 'sortValue', + }); }); }); describe('onSortChange', () => { it('calls onSortChange when the Sort Select changes', () => { const onSortChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - trigger(resourceList.find(Select), 'onChange', 'PRODUCT_TITLE_DESC'); + resourceList.find(Select)!.trigger('onChange', 'PRODUCT_TITLE_DESC'); expect(onSortChange).toHaveBeenCalledWith('PRODUCT_TITLE_DESC'); }); }); @@ -733,25 +778,29 @@ describe('', () => { describe('Alternate Tool', () => { it('does not render if an alternateTool is not provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find('#AlternateTool').exists()).toBe(false); + expect(resourceList).not.toContainReactComponent('div', { + id: 'AlternateTool', + }); }); it('renders if an alternateTool is provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( , ); - expect(resourceList.find('#AlternateTool').exists()).toBe(true); + expect(resourceList).toContainReactComponent('div', { + id: 'AlternateTool', + }); }); it('renders even if sortOptions are provided', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { alternateTool={alternateTool} />, ); - expect(resourceList.find('#AlternateTool').exists()).toBe(true); + expect(resourceList).toContainReactComponent('div', { + id: 'AlternateTool', + }); }); describe('sortOptions', () => { it('passes a sortOptions to the Select options', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { onSortChange={noop} />, ); - expect(resourceList.find(Select).props()).toHaveProperty( - 'options', - sortOptions, - ); + expect(resourceList).toContainReactComponent(Select, { + options: sortOptions, + }); }); }); describe('sortValue', () => { it('passes a sortValue to the Select value', () => { const onSortChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - expect(resourceList.find(Select).props()).toHaveProperty( - 'value', - 'sortValue', - ); + expect(resourceList).toContainReactComponent(Select, { + value: 'sortValue', + }); }); }); describe('onSortChange', () => { it('calls onSortChange when the Sort Select changes', () => { const onSortChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { renderItem={renderItem} />, ); - trigger(resourceList.find(Select), 'onChange', 'PRODUCT_TITLE_DESC'); + resourceList.find(Select)!.trigger('onChange', 'PRODUCT_TITLE_DESC'); expect(onSortChange).toHaveBeenCalledWith('PRODUCT_TITLE_DESC'); }); }); @@ -817,7 +866,7 @@ describe('', () => { describe('loading', () => { it('renders a spinner', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(Spinner).exists()).toBe(true); + expect(resourceList).toContainReactComponent(Spinner); }); it('renders a spinner after initial load when loading is true', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { ); resourceList.setProps({loading: true}); - expect(resourceList.find(Spinner).exists()).toBe(true); + expect(resourceList).toContainReactComponent(Spinner); }); it('does not render an if loading is true and there are no items', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(ResourceItem)).toHaveLength(0); + expect(resourceList).not.toContainReactComponent(ResourceItem); }); }); describe('BulkActions', () => { it('renders on initial load when items are selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { selectedItems={['1']} />, ); - expect(resourceList.find(BulkActions)).toHaveLength(1); + expect(resourceList).toContainReactComponentTimes(BulkActions, 1); }); it('enables select mode when items are programmatically selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(BulkActions).prop('selectMode')).toBe(false); + expect(resourceList).toContainReactComponent(BulkActions, { + selectMode: false, + }); resourceList.setProps({selectedItems: ['1']}); - resourceList.update(); - expect(resourceList.find(BulkActions).prop('selectMode')).toBe(true); + expect(resourceList).toContainReactComponent(BulkActions, { + selectMode: true, + }); }); it('disables select mode when items are deselected programmatically selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect(resourceList.find(BulkActions).prop('selectMode')).toBe(true); + expect(resourceList).toContainReactComponent(BulkActions, { + selectMode: true, + }); resourceList.setProps({selectedItems: []}); - resourceList.update(); - expect(resourceList.find(BulkActions).prop('selectMode')).toBe(false); + expect(resourceList).toContainReactComponent(BulkActions, { + selectMode: false, + }); }); describe('focus', () => { @@ -1029,7 +1084,7 @@ describe('', () => { return item.id; } const onSelectionChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { resolveItemId={resolveItemId} />, ); - const firstItem = resourceList.find(ResourceItem).first(); - findByTestID(firstItem, 'LargerSelectionArea').simulate('click'); - - const lastItem = resourceList.find(ResourceItem).last(); - findByTestID(lastItem, 'LargerSelectionArea').simulate('click', { + const firstItem = resourceList.find(ResourceItem); + firstItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); + const allItems = resourceList.findAll(ResourceItem); + const lastItem = allItems[allItems.length - 1]; + lastItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, nativeEvent: {shiftKey: true}, }); - expect(onSelectionChange).toHaveBeenCalledWith(['5', '6', '7']); }); it('does not select shift selected items if resolveItemId was not provided', () => { const onSelectionChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { onSelectionChange={onSelectionChange} />, ); - const firstItem = resourceList.find(ResourceItem).first(); - findByTestID(firstItem, 'LargerSelectionArea').simulate('click'); - - const lastItem = resourceList.find(ResourceItem).last(); - findByTestID(lastItem, 'LargerSelectionArea').simulate('click', { + const firstItem = resourceList.find(ResourceItem); + firstItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); + const allItems = resourceList.findAll(ResourceItem); + const lastItem = allItems[allItems.length - 1]; + lastItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, nativeEvent: {shiftKey: true}, }); @@ -1091,7 +1153,7 @@ describe('', () => { } const onSelectionChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { resolveItemId={resolveItemId} />, ); - const firstItem = resourceList.find(ResourceItem).first(); - findByTestID(firstItem, 'LargerSelectionArea').simulate('click'); - - const lastItem = resourceList.find(ResourceItem).last(); - findByTestID(lastItem, 'LargerSelectionArea').simulate('click', { + const firstItem = resourceList.find(ResourceItem); + firstItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); + const allItems = resourceList.findAll(ResourceItem); + const lastItem = allItems[allItems.length - 1]; + lastItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, nativeEvent: {shiftKey: true}, }); @@ -1118,7 +1184,7 @@ describe('', () => { return item.id; } const onSelectionChange = jest.fn(); - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { resolveItemId={resolveItemId} />, ); - // Sets {lastSeleced: 0} - const firstItem = resourceList.find(ResourceItem).first(); - findByTestID(firstItem, 'LargerSelectionArea').simulate('click'); - - const lastItem = resourceList.find(ResourceItem).last(); - findByTestID(lastItem, 'LargerSelectionArea').simulate('click', { + // Sets {lastSelected: 0} + const firstItem = resourceList.find(ResourceItem); + firstItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); + const allItems = resourceList.findAll(ResourceItem); + const lastItem = allItems[allItems.length - 1]; + lastItem!.find('div', {className: styles.Handle})!.trigger('onClick', { + stopPropagation: () => {}, nativeEvent: {shiftKey: true}, }); @@ -1147,7 +1217,7 @@ describe('', () => { }); it('an inline label is hidden on small screen', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { ); setSmallScreen(); - trigger(resourceList.find(EventListener), 'handler'); - - expect(resourceList.find(Select).first().prop('labelInline')).toBe(false); + resourceList.find(EventListener)!.trigger('handler'); + expect(resourceList).toContainReactComponent(Select, { + labelInline: false, + }); }); it('select mode is turned off on large screen when no items are selected', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - trigger(resourceList.find(BulkActions), 'onSelectModeToggle', true); - trigger(resourceList.find(EventListener).first(), 'handler'); - expect(resourceList.find(BulkActions).prop('selectMode')).toBe(false); + resourceList.find(BulkActions)!.trigger('onSelectModeToggle', true); + resourceList.find(EventListener)!.trigger('handler'); + expect(resourceList).toContainReactComponent(BulkActions, { + selectMode: false, + }); }); }); describe('isFiltered', () => { it('renders `selectAllFilteredItems` label if true', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect( - resourceList.find(BulkActions).prop('paginatedSelectAllAction'), - ).toStrictEqual({ - content: 'Select all 2+ customers in this filter', - onAction: expect.any(Function), + expect(resourceList).toContainReactComponent(BulkActions, { + paginatedSelectAllAction: { + content: 'Select all 2+ customers in this filter', + onAction: expect.any(Function), + }, }); }); @@ -1215,13 +1288,13 @@ describe('', () => { resourceList.find(BulkActions)!.find(Button)!.trigger('onClick'); - expect( - resourceList.find(BulkActions)!.prop('paginatedSelectAllText'), - ).toBe('All 2+ customers in this filter are selected.'); + expect(resourceList).toContainReactComponent(BulkActions, { + paginatedSelectAllText: 'All 2+ customers in this filter are selected.', + }); }); it('renders `selectAllItems` label if not passed', () => { - const resourceList = mountWithAppProvider( + const resourceList = mountWithApp( ', () => { />, ); - expect( - resourceList.find(BulkActions).prop('paginatedSelectAllAction'), - ).toStrictEqual({ - content: 'Select all 2+ customers in your store', - onAction: expect.any(Function), + expect(resourceList).toContainReactComponent(BulkActions, { + paginatedSelectAllAction: { + content: 'Select all 2+ customers in your store', + onAction: expect.any(Function), + }, }); }); @@ -1254,9 +1327,9 @@ describe('', () => { resourceList.find(BulkActions)!.find(Button)!.trigger('onClick'); - expect( - resourceList.find(BulkActions)!.prop('paginatedSelectAllText'), - ).toBe('All 2+ customers in your store are selected.'); + expect(resourceList).toContainReactComponent(BulkActions, { + paginatedSelectAllText: 'All 2+ customers in your store are selected.', + }); }); }); }); From 6535c8c344b7a13a1b1b3bdd07d30c5235ca007a Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Mon, 9 Aug 2021 14:00:51 -0400 Subject: [PATCH 06/11] Fixing lint errors. --- src/components/ResourceList/tests/ResourceList.test.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/ResourceList/tests/ResourceList.test.tsx b/src/components/ResourceList/tests/ResourceList.test.tsx index 8edf82934ce..9d379502bef 100644 --- a/src/components/ResourceList/tests/ResourceList.test.tsx +++ b/src/components/ResourceList/tests/ResourceList.test.tsx @@ -14,9 +14,7 @@ import {SELECT_ALL_ITEMS} from 'utilities/resource-list'; import {BulkActions} from '../../BulkActions'; import {CheckableButton} from '../../CheckableButton'; - import {classNames} from '../../../utilities/css'; - import styles from '../ResourceList.scss'; const itemsNoID = [{url: 'item 1'}, {url: 'item 2'}]; @@ -143,10 +141,9 @@ describe('', () => { bulkActions={bulkActions} />, ); - expect(resourceList).toContainReactComponent(BulkActions); expect( resourceList.find(BulkActions)!.props.paginatedSelectAllAction, - ).not.toBe(undefined); + ).not.toBeUndefined(); }); }); From c865613d62229734b360a1416027d850978b591a Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Tue, 10 Aug 2021 09:49:44 -0400 Subject: [PATCH 07/11] Removing duplicate entry on UNRELEASED.md --- UNRELEASED.md | 1 - 1 file changed, 1 deletion(-) diff --git a/UNRELEASED.md b/UNRELEASED.md index 60000410de6..721d297dbd8 100644 --- a/UNRELEASED.md +++ b/UNRELEASED.md @@ -43,7 +43,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f - Modernized tests for Breadcrumbs, BulkActions, Button, ButtonGroup/Item, and ButtonGroup components([#4315](https://github.com/Shopify/polaris-react/pull/4315)) - Modernized tests for DualThumb ([#4341](https://github.com/Shopify/polaris-react/pull/4341)) - Modernized tests for AppProvider, AfterInitialMount components([#4315](https://github.com/Shopify/polaris-react/pull/4331)) -- Modernized tests for ResourceItem ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) - Modernized tests for ResourceItem, ResourceList ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) ### Deprecations From eb7a380e0f3495575b4ca51ef7bc66791820f360 Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Tue, 10 Aug 2021 13:38:50 -0400 Subject: [PATCH 08/11] Update UNRELEASED.md Co-authored-by: Kyle Durand --- UNRELEASED.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UNRELEASED.md b/UNRELEASED.md index 721d297dbd8..1206aab4e64 100644 --- a/UNRELEASED.md +++ b/UNRELEASED.md @@ -43,6 +43,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f - Modernized tests for Breadcrumbs, BulkActions, Button, ButtonGroup/Item, and ButtonGroup components([#4315](https://github.com/Shopify/polaris-react/pull/4315)) - Modernized tests for DualThumb ([#4341](https://github.com/Shopify/polaris-react/pull/4341)) - Modernized tests for AppProvider, AfterInitialMount components([#4315](https://github.com/Shopify/polaris-react/pull/4331)) -- Modernized tests for ResourceItem, ResourceList ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) +- Modernized tests for `ResourceItem`, `ResourceList` ([#4362](https://github.com/Shopify/polaris-react/pull/4362)) ### Deprecations From c2c34513897b1246d82a014b4c808e4019872592 Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Tue, 10 Aug 2021 17:36:47 -0400 Subject: [PATCH 09/11] PR suggestions. --- .../ResourceItem/tests/ResourceItem.test.tsx | 110 +++++++----------- .../ResourceList/tests/ResourceList.test.tsx | 51 ++------ 2 files changed, 50 insertions(+), 111 deletions(-) diff --git a/src/components/ResourceItem/tests/ResourceItem.test.tsx b/src/components/ResourceItem/tests/ResourceItem.test.tsx index 5292af4745d..03979d02da3 100644 --- a/src/components/ResourceItem/tests/ResourceItem.test.tsx +++ b/src/components/ResourceItem/tests/ResourceItem.test.tsx @@ -10,7 +10,6 @@ import { } from 'components'; import {ResourceItem} from '../ResourceItem'; -import {classNames} from '../../../utilities/css'; import {ResourceListContext} from '../../../utilities/resource-list'; import styles from '../ResourceItem.scss'; @@ -71,6 +70,10 @@ describe('', () => { const external = false; const ariaLabel = 'View Item'; + const resourceItemSelector = {className: styles.ResourceItem}; + const resourceItemFilter = (node: any) => + node.prop('className').includes(styles.ResourceItem); + describe('accessibilityLabel', () => { it('is used on the for the aria-label attribute', () => { const item = mountWithApp( @@ -214,8 +217,7 @@ describe('', () => { , ); - const div = element.find('div', {'data-href': url} as any); - expect(div).not.toBeNull(); + expect(element).toContainReactComponent('div', {'data-href': url} as any); }); }); @@ -299,12 +301,10 @@ describe('', () => { , ); - wrapper - .find('div', {className: styles.ResourceItem})! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper.find('div', resourceItemSelector)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); @@ -321,12 +321,10 @@ describe('', () => { , ); - wrapper - .find('div', {className: styles.ResourceItem})! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper.find('div', resourceItemSelector)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); @@ -337,12 +335,10 @@ describe('', () => { , ); - wrapper - .find('div', {className: styles.ResourceItem})! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {metaKey: true}, - }); + wrapper.find('div', resourceItemSelector)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {metaKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); @@ -355,7 +351,7 @@ describe('', () => { ); wrapper - .find('div', {className: styles.ResourceItem})! + .find('div', resourceItemSelector)! .trigger('onKeyUp', {key: 'Enter'}); expect(onClick).toHaveBeenCalled(); @@ -370,7 +366,7 @@ describe('', () => { ); wrapper - .find('div', {className: styles.ResourceItem})! + .find('div', resourceItemSelector)! .trigger('onKeyUp', {key: 'Tab'}); expect(onClick).not.toHaveBeenCalled(); @@ -385,13 +381,8 @@ describe('', () => { ); wrapper - .find('div', { - className: classNames( - styles.ResourceItem, - styles.selectable, - styles.selectMode, - ), - })! + .find('div') + .findWhere(resourceItemFilter)! .trigger('onKeyUp', {key: 'Enter'}); expect(onClick).not.toHaveBeenCalled(); @@ -404,12 +395,10 @@ describe('', () => { , ); - wrapper - .find('div', {className: styles.ResourceItem})! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {ctrlKey: true}, - }); + wrapper.find('div', resourceItemSelector)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {ctrlKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); }); @@ -465,13 +454,8 @@ describe('', () => { ); wrapper - .find('div', { - className: classNames( - styles.ResourceItem, - styles.selectable, - styles.selectMode, - ), - })! + .find('div') + .findWhere(resourceItemFilter)! .trigger('onClick', { stopPropagation: () => {}, nativeEvent: {}, @@ -495,13 +479,8 @@ describe('', () => { ); wrapper - .find('div', { - className: classNames( - styles.ResourceItem, - styles.selectable, - styles.selectMode, - ), - })! + .find('div') + .findWhere(resourceItemFilter)! .trigger('onClick', { stopPropagation: () => {}, nativeEvent: {shiftKey: false}, @@ -531,14 +510,8 @@ describe('', () => { ); wrapper - .find('div', { - className: classNames( - styles.ResourceItem, - styles.selectable, - styles.selected, - styles.selectMode, - ), - })! + .find('div') + .findWhere(resourceItemFilter)! .trigger('onClick', { stopPropagation: () => {}, nativeEvent: {metaKey: true}, @@ -554,14 +527,8 @@ describe('', () => { ); wrapper - .find('div', { - className: classNames( - styles.ResourceItem, - styles.selectable, - styles.selected, - styles.selectMode, - ), - })! + .find('div') + .findWhere(resourceItemFilter)! .trigger('onClick', { stopPropagation: () => {}, nativeEvent: {ctrlKey: true}, @@ -799,8 +766,10 @@ describe('', () => { /> , ); - const li = item.find('li', {'data-href': 'google.com'} as any); - expect(li).not.toBeNull(); + + expect(item).toContainReactComponent('li', { + 'data-href': 'google.com', + } as any); }); it('renders a data-href tag on the li when the dataHref prop is not specified', () => { @@ -814,8 +783,9 @@ describe('', () => { , ); - const li = item.find('li', {'data-href': undefined} as any); - expect(li).not.toBeNull(); + expect(item).toContainReactComponent('li', { + 'data-href': undefined, + } as any); }); }); }); diff --git a/src/components/ResourceList/tests/ResourceList.test.tsx b/src/components/ResourceList/tests/ResourceList.test.tsx index 9d379502bef..a3047b0828c 100644 --- a/src/components/ResourceList/tests/ResourceList.test.tsx +++ b/src/components/ResourceList/tests/ResourceList.test.tsx @@ -14,7 +14,6 @@ import {SELECT_ALL_ITEMS} from 'utilities/resource-list'; import {BulkActions} from '../../BulkActions'; import {CheckableButton} from '../../CheckableButton'; -import {classNames} from '../../../utilities/css'; import styles from '../ResourceList.scss'; const itemsNoID = [{url: 'item 1'}, {url: 'item 2'}]; @@ -371,10 +370,7 @@ describe('', () => { />, ); expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderWrapper, - }); - expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderContentWrapper, + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -383,10 +379,7 @@ describe('', () => { , ); expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderWrapper, - }); - expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderContentWrapper, + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -400,10 +393,7 @@ describe('', () => { />, ); expect(resourceList).toContainReactComponent('div', { - className: classNames( - styles.HeaderWrapper, - styles['HeaderWrapper-hasSort'], - ), + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -416,10 +406,7 @@ describe('', () => { />, ); expect(resourceList).toContainReactComponent('div', { - className: classNames( - styles.HeaderWrapper, - styles['HeaderWrapper-hasAlternateTool'], - ), + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -432,10 +419,7 @@ describe('', () => { />, ); expect(resourceList).toContainReactComponent('div', { - className: classNames( - styles.HeaderWrapper, - styles['HeaderWrapper-hasSelect'], - ), + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -448,10 +432,7 @@ describe('', () => { />, ); expect(resourceList).toContainReactComponent('div', { - className: classNames( - styles.HeaderWrapper, - styles['HeaderWrapper-hasSelect'], - ), + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -460,10 +441,7 @@ describe('', () => { , ); expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderWrapper, - }); - expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderContentWrapper, + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -477,19 +455,13 @@ describe('', () => { ); // initially not rendered expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderWrapper, - }); - expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderContentWrapper, + className: expect.stringContaining(styles.HeaderWrapper), }); // update props resourceList.setProps({items: itemsWithID}); // now it's rendered expect(resourceList).toContainReactComponent('div', { - className: classNames( - styles.HeaderWrapper, - styles['HeaderWrapper-hasSelect'], - ), + className: expect.stringContaining(styles.HeaderWrapper), }); }); @@ -503,10 +475,7 @@ describe('', () => { ); expect(resourceList).toContainReactComponent(EmptySearchResult); expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderWrapper, - }); - expect(resourceList).not.toContainReactComponent('div', { - className: styles.HeaderContentWrapper, + className: expect.stringContaining(styles.HeaderWrapper), }); }); }); From 97de9942a294225c545f796c5b0a34944c55617f Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Wed, 11 Aug 2021 10:31:28 -0400 Subject: [PATCH 10/11] Removing constant from tests and exporting Node from react-testing. --- .../ResourceItem/tests/ResourceItem.test.tsx | 56 +++++++++++-------- src/test-utilities/react-testing.tsx | 4 +- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/components/ResourceItem/tests/ResourceItem.test.tsx b/src/components/ResourceItem/tests/ResourceItem.test.tsx index 03979d02da3..5d35f2b410f 100644 --- a/src/components/ResourceItem/tests/ResourceItem.test.tsx +++ b/src/components/ResourceItem/tests/ResourceItem.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {mountWithApp} from 'test-utilities'; +import {mountWithApp, Node} from 'test-utilities'; import { Avatar, ButtonGroup, @@ -70,8 +70,7 @@ describe('', () => { const external = false; const ariaLabel = 'View Item'; - const resourceItemSelector = {className: styles.ResourceItem}; - const resourceItemFilter = (node: any) => + const resourceItemFilter = (node: Node) => node.prop('className').includes(styles.ResourceItem); describe('accessibilityLabel', () => { @@ -301,10 +300,13 @@ describe('', () => { , ); - wrapper.find('div', resourceItemSelector)!.trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper + .find('div')! + .findWhere(resourceItemFilter)! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); @@ -321,10 +323,13 @@ describe('', () => { , ); - wrapper.find('div', resourceItemSelector)!.trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper + .find('div')! + .findWhere(resourceItemFilter)! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); @@ -335,10 +340,13 @@ describe('', () => { , ); - wrapper.find('div', resourceItemSelector)!.trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {metaKey: true}, - }); + wrapper + .find('div')! + .findWhere(resourceItemFilter)! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {metaKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); @@ -351,7 +359,8 @@ describe('', () => { ); wrapper - .find('div', resourceItemSelector)! + .find('div')! + .findWhere(resourceItemFilter)! .trigger('onKeyUp', {key: 'Enter'}); expect(onClick).toHaveBeenCalled(); @@ -366,7 +375,8 @@ describe('', () => { ); wrapper - .find('div', resourceItemSelector)! + .find('div')! + .findWhere(resourceItemFilter)! .trigger('onKeyUp', {key: 'Tab'}); expect(onClick).not.toHaveBeenCalled(); @@ -384,7 +394,6 @@ describe('', () => { .find('div') .findWhere(resourceItemFilter)! .trigger('onKeyUp', {key: 'Enter'}); - expect(onClick).not.toHaveBeenCalled(); }); @@ -395,10 +404,13 @@ describe('', () => { , ); - wrapper.find('div', resourceItemSelector)!.trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {ctrlKey: true}, - }); + wrapper + .find('div')! + .findWhere(resourceItemFilter)! + .trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {ctrlKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); }); diff --git a/src/test-utilities/react-testing.tsx b/src/test-utilities/react-testing.tsx index c4142e30cc6..79cd0938194 100644 --- a/src/test-utilities/react-testing.tsx +++ b/src/test-utilities/react-testing.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {createMount, mount} from '@shopify/react-testing'; +import {createMount, mount, Node} from '@shopify/react-testing'; import translations from '../../locales/en.json'; import { @@ -7,7 +7,7 @@ import { WithPolarisTestProviderOptions, } from '../components'; -export {createMount, mount}; +export {createMount, mount, Node}; export const mountWithApp = createMount< WithPolarisTestProviderOptions, From 0be81d005d9869f5d6e30f448c8f2691448c8720 Mon Sep 17 00:00:00 2001 From: Luca Bezerra Date: Wed, 11 Aug 2021 11:23:54 -0400 Subject: [PATCH 11/11] Better way of classList filtering and Node type exporting. --- .../ResourceItem/tests/ResourceItem.test.tsx | 105 ++++++------------ src/test-utilities/react-testing.tsx | 3 +- 2 files changed, 38 insertions(+), 70 deletions(-) diff --git a/src/components/ResourceItem/tests/ResourceItem.test.tsx b/src/components/ResourceItem/tests/ResourceItem.test.tsx index 5d35f2b410f..9fdccf5dca9 100644 --- a/src/components/ResourceItem/tests/ResourceItem.test.tsx +++ b/src/components/ResourceItem/tests/ResourceItem.test.tsx @@ -71,7 +71,7 @@ describe('', () => { const ariaLabel = 'View Item'; const resourceItemFilter = (node: Node) => - node.prop('className').includes(styles.ResourceItem); + node.is('div') && node!.domNode.classList.contains(styles.ResourceItem); describe('accessibilityLabel', () => { it('is used on the for the aria-label attribute', () => { @@ -300,13 +300,10 @@ describe('', () => { , ); - wrapper - .find('div')! - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); @@ -323,13 +320,10 @@ describe('', () => { , ); - wrapper - .find('div')! - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).toHaveBeenCalledWith(itemId); }); @@ -340,13 +334,10 @@ describe('', () => { , ); - wrapper - .find('div')! - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {metaKey: true}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {metaKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); @@ -358,10 +349,7 @@ describe('', () => { , ); - wrapper - .find('div')! - .findWhere(resourceItemFilter)! - .trigger('onKeyUp', {key: 'Enter'}); + wrapper.findWhere(resourceItemFilter)!.trigger('onKeyUp', {key: 'Enter'}); expect(onClick).toHaveBeenCalled(); }); @@ -374,10 +362,7 @@ describe('', () => { , ); - wrapper - .find('div')! - .findWhere(resourceItemFilter)! - .trigger('onKeyUp', {key: 'Tab'}); + wrapper.findWhere(resourceItemFilter)!.trigger('onKeyUp', {key: 'Tab'}); expect(onClick).not.toHaveBeenCalled(); }); @@ -390,10 +375,7 @@ describe('', () => { , ); - wrapper - .find('div') - .findWhere(resourceItemFilter)! - .trigger('onKeyUp', {key: 'Enter'}); + wrapper.findWhere(resourceItemFilter)!.trigger('onKeyUp', {key: 'Enter'}); expect(onClick).not.toHaveBeenCalled(); }); @@ -404,13 +386,10 @@ describe('', () => { , ); - wrapper - .find('div')! - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {ctrlKey: true}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {ctrlKey: true}, + }); expect(spy).toHaveBeenCalledWith(url, '_blank'); }); }); @@ -465,13 +444,10 @@ describe('', () => { , ); - wrapper - .find('div') - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {}, + }); expect(onClick).not.toHaveBeenCalledWith(itemId); }); @@ -490,13 +466,10 @@ describe('', () => { , ); - wrapper - .find('div') - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {shiftKey: false}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {shiftKey: false}, + }); expect(mockSelectModeContext.onSelectionChange).toHaveBeenCalledWith( true, itemId, @@ -521,13 +494,10 @@ describe('', () => { , ); - wrapper - .find('div') - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {metaKey: true}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {metaKey: true}, + }); expect(spy).not.toHaveBeenCalled(); }); @@ -538,13 +508,10 @@ describe('', () => { , ); - wrapper - .find('div') - .findWhere(resourceItemFilter)! - .trigger('onClick', { - stopPropagation: () => {}, - nativeEvent: {ctrlKey: true}, - }); + wrapper.findWhere(resourceItemFilter)!.trigger('onClick', { + stopPropagation: () => {}, + nativeEvent: {ctrlKey: true}, + }); expect(spy).not.toHaveBeenCalled(); }); }); diff --git a/src/test-utilities/react-testing.tsx b/src/test-utilities/react-testing.tsx index 79cd0938194..6d690992f36 100644 --- a/src/test-utilities/react-testing.tsx +++ b/src/test-utilities/react-testing.tsx @@ -7,7 +7,8 @@ import { WithPolarisTestProviderOptions, } from '../components'; -export {createMount, mount, Node}; +export {createMount, mount}; +export type {Node}; export const mountWithApp = createMount< WithPolarisTestProviderOptions,