diff --git a/UNRELEASED.md b/UNRELEASED.md
index fc0e6cf3dae..d6fef31e4b1 100644
--- a/UNRELEASED.md
+++ b/UNRELEASED.md
@@ -52,5 +52,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
- Modernized tests for SkeletonBodyTest, SkeletonDisplayTest, SkeletonPage, SkeletonThumbnail, and Spinner components ([#4353](https://github.com/Shopify/polaris-react/pull/4353))
- Modernized tests for Message, Menu, Search, SearchDismissOverlay, SearchField, UserMenu and TopBar components. ([#4311](https://github.com/Shopify/polaris-react/pull/4311))
- Modernized tests for Konami, Labelled, and Link components([#4389](https://github.com/Shopify/polaris-react/pull/4389))
+- Modernized tests for Scrollable, ScrollTo, ScrollLock, Select, SettingToggle, Sheet, Spinner, and Sticky components([#4386](https://github.com/Shopify/polaris-react/pull/4386))
### Deprecations
diff --git a/src/components/ScrollLock/tests/ScrollLock.test.tsx b/src/components/ScrollLock/tests/ScrollLock.test.tsx
index 16bb1237e3f..f2ed7c76f96 100644
--- a/src/components/ScrollLock/tests/ScrollLock.test.tsx
+++ b/src/components/ScrollLock/tests/ScrollLock.test.tsx
@@ -1,6 +1,5 @@
import React, {useState, useCallback} from 'react';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider} from 'test-utilities/legacy';
+import {mountWithApp} from 'test-utilities';
import {SCROLL_LOCKING_ATTRIBUTE} from '../../../utilities/scroll-lock-manager';
import {ScrollLock} from '../ScrollLock';
@@ -19,7 +18,6 @@ describe('ScrollLock', () => {
it('does not remove the data attribute from the body when two scrolllocks are mounted and one unmounts', () => {
function DummyFrame() {
const [showScrollLock, setScrollLock] = useState(true);
-
const setScollLockFalse = useCallback(() => setScrollLock(false), []);
const scrollLockMarkup = showScrollLock ? : null;
@@ -33,9 +31,8 @@ describe('ScrollLock', () => {
);
}
- const scrollLockContainer = mountWithAppProvider();
-
- scrollLockContainer.find('button').simulate('click');
+ const scrollLockContainer = mountWithApp();
+ scrollLockContainer.find('button')!.trigger('onClick');
expect(document.body.hasAttribute(`${SCROLL_LOCKING_ATTRIBUTE}`)).toBe(
true,
@@ -43,14 +40,14 @@ describe('ScrollLock', () => {
});
it('adds data attribute to the body when it mounts', () => {
- mountWithAppProvider();
+ mountWithApp();
expect(document.body.hasAttribute(`${SCROLL_LOCKING_ATTRIBUTE}`)).toBe(
true,
);
});
it('removes data attribute from the body when it unmounts', () => {
- const scrollLock = mountWithAppProvider();
+ const scrollLock = mountWithApp();
scrollLock.unmount();
expect(document.body.hasAttribute(`${SCROLL_LOCKING_ATTRIBUTE}`)).toBe(
false,
diff --git a/src/components/Scrollable/components/ScrollTo/tests/ScrollTo.test.tsx b/src/components/Scrollable/components/ScrollTo/tests/ScrollTo.test.tsx
index aef32b0741d..556aad5c5a5 100644
--- a/src/components/Scrollable/components/ScrollTo/tests/ScrollTo.test.tsx
+++ b/src/components/Scrollable/components/ScrollTo/tests/ScrollTo.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 {ScrollTo} from '../ScrollTo';
import {ScrollableContext} from '../../../context';
@@ -9,7 +8,7 @@ describe('', () => {
it('calls scrollToPosition on mount', () => {
const spy = jest.fn();
- mountWithAppProvider(
+ mountWithApp(
,
@@ -20,7 +19,7 @@ describe('', () => {
it("does not call scrollToPosition when it's undefined", () => {
function fn() {
- mountWithAppProvider(
+ mountWithApp(
,
diff --git a/src/components/Scrollable/tests/Scrollable.test.tsx b/src/components/Scrollable/tests/Scrollable.test.tsx
index 6e518a3720c..7571c1e2a2e 100644
--- a/src/components/Scrollable/tests/Scrollable.test.tsx
+++ b/src/components/Scrollable/tests/Scrollable.test.tsx
@@ -1,6 +1,4 @@
import React from 'react';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider} from 'test-utilities/legacy';
import {mountWithApp} from 'test-utilities';
import {Scrollable} from '../Scrollable';
@@ -8,12 +6,12 @@ import {ScrollableContext} from '../context';
describe('', () => {
it('mounts', () => {
- const scrollable = mountWithAppProvider();
+ const scrollable = mountWithApp();
expect(scrollable).toBeTruthy();
});
it('unmounts', () => {
- const scrollable = mountWithAppProvider();
+ const scrollable = mountWithApp();
expect(() => {
scrollable.unmount();
}).not.toThrow();
@@ -26,14 +24,12 @@ describe('', () => {
of Shopify Inc.
);
- const scrollable = mountWithAppProvider(
- {children},
- );
- expect(scrollable.contains(children)).toBe(true);
+ const scrollable = mountWithApp({children});
+ expect(scrollable).toContainReactComponent('div', {children});
});
it('provides scrollToPosition callback to children', () => {
- const Child: React.SFC = (_) => (
+ const Child: React.FunctionComponent = (_) => (
{(scrollToPosition) => {
return scrollToPosition ? : null;
@@ -41,7 +37,7 @@ describe('', () => {
);
- const scrollableContainer = mountWithAppProvider(
+ const scrollableContainer = mountWithApp(
{}}>
@@ -49,18 +45,18 @@ describe('', () => {
,
);
- const div = scrollableContainer.find(Child).find('div').first();
- expect(div.exists()).toBe(true);
+ const scrollChild = scrollableContainer.find(Child)!;
+ expect(scrollChild).toContainReactComponent('div');
});
it('allows children to receive scroll events', () => {
const spy = jest.fn();
- const scrollArea = mountWithAppProvider(
+ const scrollArea = mountWithApp(
-
+
,
);
- scrollArea.find('#scrollContents').simulate('scroll');
+ scrollArea.find('div', {onScroll: spy})!.trigger('onScroll');
expect(spy).toHaveBeenCalledTimes(1);
});
diff --git a/src/components/Select/tests/Select.test.tsx b/src/components/Select/tests/Select.test.tsx
index 38c21cd0aff..897d3950297 100644
--- a/src/components/Select/tests/Select.test.tsx
+++ b/src/components/Select/tests/Select.test.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import {InlineError, Icon, Labelled} from 'components';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider, ReactWrapper} from 'test-utilities/legacy';
+import {mountWithApp} from 'test-utilities';
import {CircleTickOutlineMinor} from '@shopify/polaris-icons';
import {Select} from '../Select';
@@ -10,7 +9,7 @@ describe('', () => {
describe('onChange()', () => {
it('is called with the value of the newly-selected option', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
onChange={spy}
/>,
);
- (element.find('select') as any).instance().value = 'two';
- element.find('select').simulate('change');
+
+ const select = element.find('select')! as any;
+ select.value = 'two';
+
+ const event = {
+ currentTarget: select,
+ };
+
+ select.trigger('onChange', event);
expect(spy).toHaveBeenCalledWith('two', 'MySelect');
});
});
@@ -27,11 +33,11 @@ describe('', () => {
describe('onFocus()', () => {
it('is called when the select is focused', () => {
const spy = jest.fn();
- mountWithAppProvider(
+ mountWithApp(
,
)
- .find('select')
- .simulate('focus');
+ .find('select')!
+ .trigger('onFocus');
expect(spy).toHaveBeenCalled();
});
});
@@ -39,11 +45,11 @@ describe('', () => {
describe('onBlur()', () => {
it('is called when the select is blurred', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
,
);
- element.find('select').simulate('focus');
- element.find('select').simulate('blur');
+ element.find('select')!.trigger('onBlur');
+
expect(spy).toHaveBeenCalled();
});
});
@@ -51,14 +57,13 @@ describe('', () => {
describe('options', () => {
it('translates an array of strings into options', () => {
const options = ['one', 'two'];
- const optionElements = mountWithAppProvider(
+ const optionElements = mountWithApp(
,
- ).find('option');
+ ).findAll('option');
options.forEach((option, index) => {
- const optionElement = optionElements.at(index);
- expect(optionElement.key()).toBe(option);
- expect(optionElement.prop('value')).toBe(option);
+ const optionElement = optionElements[index];
+ expect(optionElement).toHaveReactProps({value: option});
expect(optionElement.text()).toBe(option);
});
});
@@ -68,15 +73,15 @@ describe('', () => {
{value: 'one', label: 'One'},
{value: 'two', label: 'Two'},
];
- const optionElements = mountWithAppProvider(
+ const optionElements = mountWithApp(
,
- ).find('option');
+ ).findAll('option');
options.forEach(({value, label}, index) => {
- const optionElement = optionElements.at(index);
- expect(optionElement.key()).toBe(value);
- expect(optionElement.prop('value')).toBe(value);
- expect(optionElement.text()).toBe(label);
+ const optionElement = optionElements[index];
+
+ expect(optionElement).toHaveReactProps({value});
+ expect(optionElement).toContainReactText(label);
});
});
@@ -86,96 +91,93 @@ describe('', () => {
{value: 'two', label: 'Two', disabled: true},
{value: 'three', label: 'Three', disabled: false},
];
- const optionElements = mountWithAppProvider(
+ const optionElements = mountWithApp(
,
- ).find('option');
-
+ ).findAll('option')!;
options.forEach(({disabled}, index) => {
- const optionElement = optionElements.at(index);
- expect(optionElement.prop('disabled')).toBe(disabled);
+ const optionElement = optionElements[index];
+
+ expect(optionElement).toHaveReactProps({disabled});
});
});
});
describe('groups', () => {
- const optionsAndGroups = [
- {title: 'Group one', options: ['one.1', 'one.2']},
- 'one',
- 'two',
- {title: 'Group two', options: ['two.1', 'two.2']},
- ];
-
- function testOptions(
- optionOrGroup: string | {title: string; options: string[]},
- optionOrOptgroupElement: ReactWrapper,
- ) {
- if (typeof optionOrGroup === 'string') {
- expect(optionOrOptgroupElement.type()).toBe('option');
- expect(optionOrOptgroupElement.key()).toBe(optionOrGroup);
- expect(optionOrOptgroupElement.prop('value')).toBe(optionOrGroup);
- expect(optionOrOptgroupElement.text()).toBe(optionOrGroup);
- } else {
- expect(optionOrOptgroupElement.type()).toBe('optgroup');
- expect(optionOrOptgroupElement.prop('label')).toBe(optionOrGroup.title);
- const options = optionOrOptgroupElement.children();
+ it('translates grouped options into optgroup tags', () => {
+ const groupOptions = [
+ {title: 'Group one', options: ['one.1', 'one.2']},
+ {title: 'Group two', options: ['two.1', 'two.2']},
+ ];
- optionOrGroup.options.forEach((option, optionIndex) => {
- const optionElement = options.at(optionIndex);
- expect(optionElement.type()).toBe('option');
- expect(optionElement.key()).toBe(option);
- expect(optionElement.prop('value')).toBe(option);
- expect(optionElement.text()).toBe(option);
+ const optgroupElements = mountWithApp(
+ ,
+ ).find('select')!;
+
+ groupOptions.forEach((optionOrGroup, index) => {
+ const optgroupElement = optgroupElements.children[index];
+
+ expect(optgroupElement.type).toBe('optgroup');
+ expect(optgroupElement).toHaveReactProps({
+ label: optionOrGroup.title,
});
- }
- }
+ const options = optgroupElement.children;
- // Expectations are ran within the call to testOptions()
- // eslint-disable-next-line jest/expect-expect
- it('translates grouped options into optgroup tags', () => {
- const optionOrOptgroupElements = mountWithAppProvider(
- ,
- )
- .find('select')
- .children();
+ optionOrGroup.options.forEach((option, optionIndex) => {
+ const optionElement = options[optionIndex];
+ expect(optionElement.type).toBe('option');
+ expect(optionElement).toHaveReactProps({
+ value: option,
+ });
+ expect(optionElement).toContainReactText(option);
+ });
+ });
+ });
- optionsAndGroups.forEach((optionOrGroup, index) => {
- const optionOrOptgroupElement = optionOrOptgroupElements.at(index);
- testOptions(optionOrGroup, optionOrOptgroupElement);
+ it('translates string options into options tags', () => {
+ const stringOptions = ['one', 'two'];
+ const optionGroupElements = mountWithApp(
+ ,
+ ).find('select')!;
+
+ stringOptions.forEach((optionOrGroup, index) => {
+ const optionGroupElement = optionGroupElements.children[index];
+ expect(optionGroupElement.type).toBe('option');
+ expect(optionGroupElement).toHaveReactProps({
+ value: optionOrGroup,
+ });
});
});
});
describe('value', () => {
it('uses the passed value for the select', () => {
- const value = mountWithAppProvider(
+ const select = mountWithApp(
,
- )
- .find('select')
- .prop('value');
- expect(value).toBe('Some value');
+ );
+
+ expect(select).toContainReactComponent('select', {value: 'Some value'});
});
});
describe('id', () => {
it('sets the id on the input', () => {
- const id = mountWithAppProvider(
+ const select = mountWithApp(
,
- )
- .find('select')
- .prop('id');
- expect(id).toBe('MySelect');
+ );
+
+ expect(select).toContainReactComponent('select', {id: 'MySelect'});
});
it('sets a random id on the input when none is passed', () => {
- const id = mountWithAppProvider(
+ const id = mountWithApp(
,
)
- .find('select')
+ .find('select')!
.prop('id');
expect(typeof id).toBe('string');
expect(id).toBeTruthy();
@@ -184,22 +186,22 @@ describe('', () => {
describe('disabled', () => {
it('sets the disabled attribute on the select', () => {
- const select = mountWithAppProvider(
+ const select = mountWithApp(
,
);
- expect(select.find('select').prop('disabled')).toBe(true);
+ expect(select.find('select')!.prop('disabled')).toBe(true);
});
it('is only disabled when disabled is explicitly set to true', () => {
- let select = mountWithAppProvider(
+ let select = mountWithApp(
,
);
- expect(select.find('select').prop('disabled')).toBeFalsy();
+ expect(select.find('select')!.prop('disabled')).toBeFalsy();
- select = mountWithAppProvider(
+ select = mountWithApp(
,
);
- expect(select.find('select').prop('disabled')).toBeFalsy();
+ expect(select.find('select')!.prop('disabled')).toBeFalsy();
});
});
@@ -212,23 +214,19 @@ describe('', () => {
prefix: ,
},
];
- const select = mountWithAppProvider(
+ const select = mountWithApp(
,
);
- expect(
- select
- .find(Icon)
- .filterWhere(
- (icon) => icon.prop('source') === CircleTickOutlineMinor,
- ),
- ).toHaveLength(1);
+ expect(select).toContainReactComponentTimes(Icon, 1, {
+ source: CircleTickOutlineMinor,
+ });
});
});
describe('helpText', () => {
it('connects the select to the help text', () => {
- const select = mountWithAppProvider(
+ const select = mountWithApp(
', () => {
onChange={noop}
/>,
);
- const helpTextID = select.find('select').prop('aria-describedby');
+ const helpTextID = select.find('select')!.prop('aria-describedby');
expect(typeof helpTextID).toBe('string');
- expect(select.find(`#${helpTextID}`).text()).toBe('Some help');
+ expect(select.find('div', {id: helpTextID})).toContainReactText(
+ 'Some help',
+ );
});
});
describe('placeholder', () => {
it('renders the placeholder as the initially selected option', () => {
const placeholderValue = '';
- const select = mountWithAppProvider(
+ const select = mountWithApp(
,
- ).find('select');
- const placeholderOption = select.find('option').first();
-
- expect(placeholderValue).toBe(placeholderOption.prop('value'));
- expect(placeholderOption.prop('disabled')).toBe(true);
+ ).find('select')!;
+ const placeholderOption = select.findAll('option')![0];
+ expect(placeholderOption).toHaveReactProps({
+ disabled: true,
+ value: placeholderValue,
+ });
});
it('sets the placeholder value as the select value when there is an onChange handler', () => {
- const select = mountWithAppProvider(
+ const select = mountWithApp(
,
- ).find('select');
- const placeholderOption = select.find('option').first();
- expect(select.prop('value')).toBe(placeholderOption.prop('value'));
+ ).find('select')!;
+ const placeholderOption = select.findAll('option')![0];
+ expect(select).toHaveReactProps({
+ value: placeholderOption.prop('value'),
+ });
});
});
describe('error', () => {
it('marks the select as invalid', () => {
- const select = mountWithAppProvider(
+ const select = mountWithApp(