From 215341d1fcbfe4b9a76665244ed1b8bfe3757e7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karen=20Pinz=C3=A1s=20Morrongiello?=
<45268098+kpinzas-sh@users.noreply.github.com>
Date: Wed, 11 Aug 2021 17:14:15 -0400
Subject: [PATCH] Add CalloutCard, Caption, CheckableButton, Resizer,
VideoThumbnail test modernization
---
UNRELEASED.md | 2 +-
.../CalloutCard/tests/CalloutCard.test.tsx | 71 +++++++++------
src/components/Caption/tests/Caption.test.tsx | 11 ++-
.../tests/CheckableButton.test.tsx | 41 +++++----
.../TextField/components/Resizer/Resizer.tsx | 4 +-
.../components/Resizer/tests/Resizer.test.tsx | 71 +++++++--------
.../tests/VideoThumbnail.test.tsx | 88 +++++++------------
7 files changed, 138 insertions(+), 150 deletions(-)
diff --git a/UNRELEASED.md b/UNRELEASED.md
index 33b84027ace..00ff647a77a 100644
--- a/UNRELEASED.md
+++ b/UNRELEASED.md
@@ -46,7 +46,7 @@ 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 SkeletonBodyTest, SkeletonDisplayTest, SkeletonPage, SkeletonThumbnail, and Spinner components ([#4353](https://github.com/Shopify/polaris-react/pull/4353))
-
+- Modernized tests for CalloutCard, Caption, CheckableButton, Resizer, VideoThumbnail ([#4387](https://github.com/Shopify/polaris-react/pull/4387))
- Modernized tests for Message, Menu, Search, SearchDismissOverlay, SearchField, UserMenu and TopBar components. ([#4311](https://github.com/Shopify/polaris-react/pull/4311))
### Deprecations
diff --git a/src/components/CalloutCard/tests/CalloutCard.test.tsx b/src/components/CalloutCard/tests/CalloutCard.test.tsx
index b70282eb1f1..b7386f1b6fe 100644
--- a/src/components/CalloutCard/tests/CalloutCard.test.tsx
+++ b/src/components/CalloutCard/tests/CalloutCard.test.tsx
@@ -1,6 +1,5 @@
import React from 'react';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider} from 'test-utilities/legacy';
+import {mountWithApp} from 'test-utilities';
import {Button, ButtonGroup} from 'components';
import {CalloutCard} from '../CalloutCard';
@@ -9,56 +8,70 @@ describe('', () => {
const illustration =
'https://cdn.shopify.com/s/assets/admin/checkout/settings-customizecart-705f57c725ac05be5a34ec20c05b94298cb8afd10aac7bd9c7ad02030f48cfa0.svg';
const spy = jest.fn();
- const calloutCard = mountWithAppProvider(
-
- Content
- ,
- );
+
+ function calloutCardMock() {
+ return mountWithApp(
+
+ Content
+ ,
+ );
+ }
it('renders its children', () => {
- expect(calloutCard.find('p').first().contains('Content')).toBe(true);
+ const calloutCard = calloutCardMock();
+ expect(calloutCard.find('p')).toContainReactText('Content');
});
it('renders the title as an h2 element', () => {
- expect(calloutCard.find('h2').first().contains('Title')).toBe(true);
+ const calloutCard = calloutCardMock();
+ expect(calloutCard.find('h2')).toContainReactText('Title');
});
it('renders the illustration', () => {
- expect(calloutCard.find('img').prop('src')).toBe(illustration);
+ const calloutCard = calloutCardMock();
+ expect(calloutCard).toContainReactComponent('img', {
+ src: illustration,
+ });
});
it('renders the primaryAction as an a tag with the given url', () => {
- expect(calloutCard.find('a').prop('href')).toBe('https://www.shopify.com');
+ const calloutCard = calloutCardMock();
+ expect(calloutCard).toContainReactComponent('a', {
+ href: 'https://www.shopify.com',
+ });
});
it('renders the primaryAction as an a tag with the given content', () => {
- expect(calloutCard.find('a').contains('Customize checkout')).toBe(true);
+ const calloutCard = calloutCardMock();
+ expect(calloutCard.find('a')).toContainReactText('Customize checkout');
});
it('renders a secondary action with the given content in a button group', () => {
- expect(calloutCard.find(Button).last().text()).toBe('Secondary action');
- expect(calloutCard.find(ButtonGroup)).toHaveLength(1);
+ const calloutCard = calloutCardMock();
+ expect(calloutCard).toContainReactComponentTimes(ButtonGroup, 1);
+ expect(calloutCard).toContainReactComponent(Button, {
+ children: 'Secondary action',
+ });
});
it('is dismissed', () => {
- expect(calloutCard.find(Button)).toHaveLength(3);
-
- calloutCard.find(Button).first().simulate('click');
-
+ const calloutCard = calloutCardMock();
+ expect(calloutCard).toContainReactComponentTimes(Button, 3);
+ calloutCard.findAll(Button)[0].trigger('onClick');
expect(spy).toHaveBeenCalled();
});
it('only renders one button when only a primary action is given', () => {
- const oneActionCalloutCard = mountWithAppProvider(
+ const oneActionCalloutCard = mountWithApp(
', () => {
,
);
- expect(oneActionCalloutCard.find(Button)).toHaveLength(1);
+ expect(oneActionCalloutCard).toContainReactComponent(Button);
});
});
diff --git a/src/components/Caption/tests/Caption.test.tsx b/src/components/Caption/tests/Caption.test.tsx
index e0c57760cee..f3c8c5a5a90 100644
--- a/src/components/Caption/tests/Caption.test.tsx
+++ b/src/components/Caption/tests/Caption.test.tsx
@@ -1,18 +1,17 @@
import React from 'react';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider} from 'test-utilities/legacy';
+import {mountWithApp} from 'test-utilities';
import {Caption} from '../Caption';
describe('
', () => {
it('renders a p tag', () => {
- const caption = mountWithAppProvider(Caption text);
- expect(caption.find('p')).toHaveLength(1);
+ const caption = mountWithApp(Caption text);
+ expect(caption).toContainReactComponentTimes('p', 1);
});
it('renders its children', () => {
const captionMarkup = 'Caption text';
- const caption = mountWithAppProvider({captionMarkup});
- expect(caption.contains(captionMarkup)).toBe(true);
+ const caption = mountWithApp({captionMarkup});
+ expect(caption).toContainReactText(captionMarkup);
});
});
diff --git a/src/components/CheckableButton/tests/CheckableButton.test.tsx b/src/components/CheckableButton/tests/CheckableButton.test.tsx
index 7f72982bfe9..78298c3ddc9 100644
--- a/src/components/CheckableButton/tests/CheckableButton.test.tsx
+++ b/src/components/CheckableButton/tests/CheckableButton.test.tsx
@@ -1,6 +1,5 @@
import React from 'react';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider} from 'test-utilities/legacy';
+import {mountWithApp} from 'test-utilities';
import {Checkbox} from 'components';
import {CheckableButton} from '../CheckableButton';
@@ -18,43 +17,49 @@ describe('', () => {
describe('select', () => {
it('is passed down to Checkbox', () => {
const {selected} = CheckableButtonProps;
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- expect(element.find(Checkbox).prop('checked')).toStrictEqual(selected);
+ expect(element).toContainReactComponent(Checkbox, {
+ checked: selected,
+ });
+ expect(element).toContainReactComponentTimes(Checkbox, 1);
});
});
describe('label', () => {
it('is passed down to span', () => {
const {label} = CheckableButtonProps;
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- expect(element.find('span').last().text()).toStrictEqual(label);
+ expect(element).toContainReactComponent('span', {
+ className: 'Label',
+ children: label,
+ });
});
});
describe('accessibilityLabel', () => {
it('sets the label on the Checkbox', () => {
const {accessibilityLabel} = CheckableButtonProps;
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- expect(element.find(Checkbox).first().prop('label')).toStrictEqual(
- accessibilityLabel,
- );
+ expect(element).toContainReactComponent(Checkbox, {
+ label: accessibilityLabel,
+ });
});
describe('disabled', () => {
it('is passed down to checkbox', () => {
const {disabled} = CheckableButtonProps;
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- expect(element.find(Checkbox).first().prop('disabled')).toStrictEqual(
+ expect(element).toContainReactComponent(Checkbox, {
disabled,
- );
+ });
});
});
});
@@ -62,21 +67,23 @@ describe('', () => {
describe('onToggleAll', () => {
it('is called when the CheckableButton is clicked', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- element.find('div').first().simulate('click');
+ element.find('div')!.trigger('onClick');
expect(spy).toHaveBeenCalled();
});
it('is called when the CheckableButton pressed with spacebar', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- element.find(Checkbox).first().simulate('click', {
+
+ element.find(Checkbox)!.find('input')!.trigger('onKeyUp', {
keyCode: Key.Space,
});
+
expect(spy).toHaveBeenCalled();
});
});
diff --git a/src/components/TextField/components/Resizer/Resizer.tsx b/src/components/TextField/components/Resizer/Resizer.tsx
index eec889c68c1..276c19548e2 100644
--- a/src/components/TextField/components/Resizer/Resizer.tsx
+++ b/src/components/TextField/components/Resizer/Resizer.tsx
@@ -35,7 +35,6 @@ export function Resizer({
const minimumLinesMarkup = minimumLines ? (
+
', () => {
it('cancels existing animationFrame on update', () => {
const cancelAnimationFrameSpy = jest.spyOn(window, 'cancelAnimationFrame');
const contents = 'Contents';
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
', () => {
);
resizer.setProps({currentHeight: 2});
- trigger(resizer.find(EventListener), 'handler');
+ resizer.find(EventListener)!.trigger('handler');
expect(cancelAnimationFrameSpy).toHaveBeenCalled();
});
@@ -46,7 +41,7 @@ describe('
', () => {
it('cancels the animationFrame unmount', () => {
const cancelAnimationFrameSpy = jest.spyOn(window, 'cancelAnimationFrame');
const contents = 'Contents';
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
@@ -58,52 +53,47 @@ describe('
', () => {
describe('contents', () => {
it('renders contents', () => {
const contents = 'Contents';
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
- const contentsNode = findByTestID(resizer, 'ContentsNode');
- expect(contentsNode.text()).toBe(contents);
+ expect(resizer.find('div')).toContainReactText(contents);
});
it('encodes HTML entities', () => {
const contents = `
&\nContents
`;
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
- const contentsNode = findByTestID(resizer, 'ContentsNode');
const expectedEncodedContents =
'<div>&
Contents</div>
';
- expect(contentsNode.html()).toContain(expectedEncodedContents);
+ expect(resizer)!.toContainReactHtml(expectedEncodedContents);
});
it('ignores carriage returns when rendering content', () => {
const contents = `
&\n\r\r\rContents
`;
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
- const contentsNode = findByTestID(resizer, 'ContentsNode');
const expectedEncodedContents =
'<div>&
Contents</div>
';
- expect(contentsNode.html()).toContain(expectedEncodedContents);
+ expect(resizer)!.toContainReactHtml(expectedEncodedContents);
});
});
describe('minimumLines', () => {
it('renders a number of
tags equivalent to minimumLines', () => {
const minimumLines = 3;
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
- const breakingSpaces = findByTestID(resizer, 'MinimumLines');
- expect(breakingSpaces.html()).toContain('
');
+ expect(resizer.find('div'))!.toContainReactHtml('
');
});
it('renders nothing when minimumLines is undefined', () => {
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
- const breakingSpaces = findByTestID(resizer, 'MinimumLines');
- expect(breakingSpaces).toHaveLength(0);
+ expect(resizer.find('div'))!.not.toContainReactHtml('
');
});
});
@@ -118,7 +108,7 @@ describe('', () => {
it('is called on mount if minimumLines is provided', () => {
const spy = jest.fn();
- mountWithAppProvider(
+ mountWithApp(
', () => {
it('is not called on mount if minimumLines is not provided', () => {
const spy = jest.fn();
- mountWithAppProvider(
+ mountWithApp(
,
);
animationFrame.runFrame();
@@ -141,7 +131,7 @@ describe('', () => {
it('is not called on mount if currentHeight is the same as DOM height', () => {
const spy = jest.fn();
- mountWithAppProvider(
+ mountWithApp(
', () => {
it('is called again on resize', () => {
const spy = jest.fn();
const currentHeight = 50;
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
', () => {
/>,
);
resizer.setProps({currentHeight: 1});
- trigger(resizer.find(EventListener), 'handler');
+ resizer.find(EventListener)?.trigger('handler');
animationFrame.runFrame();
expect(spy).toHaveBeenCalledWith(30);
});
@@ -173,7 +163,7 @@ describe('', () => {
it('is not called again on resize if minimumLines is not provided', () => {
const spy = jest.fn();
const currentHeight = 0;
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
', () => {
/>,
);
resizer.setProps({currentHeight: 1});
- trigger(resizer.find(EventListener), 'handler');
+ resizer.find(EventListener)?.trigger('handler');
animationFrame.runFrame();
expect(spy).toHaveBeenCalledTimes(0);
});
@@ -190,7 +180,7 @@ describe('', () => {
it('is not called again on resize if currentHeight is the same as DOM height', () => {
const spy = jest.fn();
const currentHeight = 0;
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
', () => {
/>,
);
resizer.setProps({currentHeight: 1});
- trigger(resizer.find(EventListener), 'handler');
+
+ resizer.find(EventListener)?.trigger('handler');
animationFrame.runFrame();
expect(spy).toHaveBeenCalledTimes(0);
});
@@ -206,23 +197,25 @@ describe('', () => {
describe('aria-hidden', () => {
it('renders aria-hidden as true', () => {
const contents = 'Contents';
- const resizer = mountWithAppProvider(
+ const resizer = mountWithApp(
,
);
- const wrapperDiv = findByTestID(resizer, 'ResizerWrapper');
- expect(wrapperDiv.prop('aria-hidden')).toBe(true);
+ expect(resizer).toContainReactComponent('div', {
+ className: 'Resizer',
+ 'aria-hidden': true,
+ });
});
});
describe('lifecycle', () => {
it('mounts safely', () => {
expect(() => {
- mountWithAppProvider();
+ mountWithApp();
}).not.toThrow();
});
it('updates safely', () => {
- const resizer = mountWithAppProvider();
+ const resizer = mountWithApp();
expect(() => {
resizer.setProps({contents: 'new content'});
@@ -230,7 +223,7 @@ describe('', () => {
});
it('unmounts safely', () => {
- const resizer = mountWithAppProvider();
+ const resizer = mountWithApp();
expect(() => {
resizer.unmount();
diff --git a/src/components/VideoThumbnail/tests/VideoThumbnail.test.tsx b/src/components/VideoThumbnail/tests/VideoThumbnail.test.tsx
index b03b7d357bf..229b4279d1e 100644
--- a/src/components/VideoThumbnail/tests/VideoThumbnail.test.tsx
+++ b/src/components/VideoThumbnail/tests/VideoThumbnail.test.tsx
@@ -14,11 +14,13 @@ describe('', () => {
it('renders with play button and custom overlay', () => {
const videoThumbnail = mountWithApp();
+ expect(videoThumbnail).toContainReactComponent('div', {
+ className: 'Thumbnail',
+ style: {
+ backgroundImage: `url(${mockProps.thumbnailUrl})`,
+ },
+ });
expect(videoThumbnail.find('button')).not.toBeNull();
- expect(
- videoThumbnail.find('div', {className: 'Thumbnail'})!.prop('style')!
- .backgroundImage,
- ).toBe(`url(${mockProps.thumbnailUrl})`);
});
});
@@ -37,41 +39,30 @@ describe('', () => {
,
);
- const timestamp = videoThumbnail
- .find('p', {
- className: 'Timestamp',
- })
- ?.text();
-
- expect(timestamp).toStrictEqual('0:45');
+ expect(videoThumbnail).toContainReactComponent('p', {
+ className: 'Timestamp',
+ children: '0:45',
+ });
});
it('renders a timestamp with seconds and minutes only when less than 60 minutes', () => {
const videoThumbnail = mountWithApp(
,
);
-
- const timestamp = videoThumbnail
- .find('p', {
- className: 'Timestamp',
- })
- ?.text();
-
- expect(timestamp).toStrictEqual('2:15');
+ expect(videoThumbnail).toContainReactComponent('p', {
+ className: 'Timestamp',
+ children: '2:15',
+ });
});
it('renders timestamp with seconds, minutes, and hours when greater than 60 minutes', () => {
const videoThumbnail = mountWithApp(
,
);
-
- const timestamp = videoThumbnail
- .find('p', {
- className: 'Timestamp',
- })
- ?.text();
-
- expect(timestamp).toStrictEqual('1:02:25');
+ expect(videoThumbnail).toContainReactComponent('p', {
+ className: 'Timestamp',
+ children: '1:02:25',
+ });
});
});
@@ -106,11 +97,8 @@ describe('', () => {
className: 'Progress',
});
- const progressIndicator = videoThumbnail.find('div', {
+ expect(videoThumbnail).toContainReactComponent('div', {
className: 'Indicator',
- });
-
- expect(progressIndicator).toHaveReactProps({
style: expect.objectContaining({
transform: 'scaleX(0)',
}),
@@ -131,11 +119,8 @@ describe('', () => {
className: 'Progress',
});
- const progressIndicator = videoThumbnail.find('div', {
+ expect(videoThumbnail).toContainReactComponent('div', {
className: 'Indicator',
- });
-
- expect(progressIndicator).toHaveReactProps({
style: expect.objectContaining({
transform: 'scaleX(0)',
}),
@@ -156,11 +141,8 @@ describe('', () => {
className: 'Progress',
});
- const progressIndicator = videoThumbnail.find('div', {
+ expect(videoThumbnail).toContainReactComponent('div', {
className: 'Indicator',
- });
-
- expect(progressIndicator).toHaveReactProps({
style: expect.objectContaining({
transform: 'scaleX(0.5)',
}),
@@ -251,9 +233,9 @@ describe('', () => {
accessibilityLabel={accessibilityLabel}
/>,
);
- expect(videoThumbnail.find('button')!.prop('aria-label')).toStrictEqual(
- accessibilityLabel,
- );
+ expect(videoThumbnail).toContainReactComponent('button', {
+ 'aria-label': accessibilityLabel,
+ });
});
describe('when videoLength is provided', () => {
@@ -265,10 +247,9 @@ describe('', () => {
,
);
- const actualLabel = videoThumbnail.find('button')!.prop('aria-label');
- const expectedLabel = `${defaultLabelWithDuration} 45 seconds`;
-
- expect(actualLabel).toStrictEqual(expectedLabel);
+ expect(videoThumbnail).toContainReactComponent('button', {
+ 'aria-label': `${defaultLabelWithDuration} 45 seconds`,
+ });
});
it('sets the default label with time in seconds and minutes when less than 60 minutes', () => {
@@ -277,10 +258,9 @@ describe('', () => {
,
);
- const actualLabel = videoThumbnail.find('button')!.prop('aria-label');
- const expectedLabel = `${defaultLabelWithDuration} 2 minutes and 15 seconds`;
-
- expect(actualLabel).toStrictEqual(expectedLabel);
+ expect(videoThumbnail).toContainReactComponent('button', {
+ 'aria-label': `${defaultLabelWithDuration} 2 minutes and 15 seconds`,
+ });
});
it('sets the default label with time in seconds, minutes, and hours when greater than 60 minutes', () => {
@@ -288,11 +268,9 @@ describe('', () => {
const videoThumbnail = mountWithApp(
,
);
-
- const actualLabel = videoThumbnail.find('button')!.prop('aria-label');
- const expectedLabel = `${defaultLabelWithDuration} 1 hour, 2 minutes, and 25 seconds`;
-
- expect(actualLabel).toStrictEqual(expectedLabel);
+ expect(videoThumbnail).toContainReactComponent('button', {
+ 'aria-label': `${defaultLabelWithDuration} 1 hour, 2 minutes, and 25 seconds`,
+ });
});
});
});