From 702f428c43bed10266117baf9019e8b6c53d8c7d 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, 1 Sep 2021 13:40:17 -0400
Subject: [PATCH 1/4] Add textfield tests
---
UNRELEASED.md | 1 +
.../TextField/tests/TextField.test.tsx | 382 ++++++++++--------
2 files changed, 210 insertions(+), 173 deletions(-)
diff --git a/UNRELEASED.md b/UNRELEASED.md
index 84ea52d6572..1e82289319c 100644
--- a/UNRELEASED.md
+++ b/UNRELEASED.md
@@ -83,5 +83,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
- Modernized tests for PopoverOverlay component([#4430](https://github.com/Shopify/polaris-react/pull/4430))
- Modernized tests for Dropzone, ExceptionList, and ConnectedFilterControl > Item components([#4412](https://github.com/Shopify/polaris-react/pull/4412))
- Modernized tests for DatePicker, DescriptionList, and DisplayText ([#4360](https://github.com/Shopify/polaris-react/pull/4360))
+- Modernized tests for TextField ([]()).
### Deprecations
diff --git a/src/components/TextField/tests/TextField.test.tsx b/src/components/TextField/tests/TextField.test.tsx
index e70f7a62abc..f044d6ab53a 100644
--- a/src/components/TextField/tests/TextField.test.tsx
+++ b/src/components/TextField/tests/TextField.test.tsx
@@ -1,6 +1,4 @@
import React from 'react';
-// eslint-disable-next-line no-restricted-imports
-import {mountWithAppProvider, findByTestID} from 'test-utilities/legacy';
import {InlineError, Labelled, Connected, Select} from 'components';
import {mountWithApp} from 'test-utilities';
@@ -11,7 +9,7 @@ describe('', () => {
it('allows specific props to pass through properties on the input', () => {
const pattern = '\\d\\d';
const inputMode = 'numeric';
- const input = mountWithAppProvider(
+ const input = mountWithApp(
', () => {
align="left"
autoComplete="name"
/>,
- ).find('input');
-
- expect(input.prop('disabled')).toBe(true);
- expect(input.prop('readOnly')).toBe(false);
- expect(input.prop('autoFocus')).toBe(true);
- expect(input.prop('name')).toBe('TextField');
- expect(input.prop('placeholder')).toBe('A placeholder');
- expect(input.prop('value')).toBe('Some value');
- expect(input.prop('min')).toBe(20);
- expect(input.prop('max')).toBe(50);
- expect(input.prop('minLength')).toBe(2);
- expect(input.prop('maxLength')).toBe(2);
- expect(input.prop('spellCheck')).toBe(false);
- expect(input.prop('pattern')).toBe(pattern);
- expect(input.prop('inputMode')).toBe(inputMode);
- expect(input.prop('autoComplete')).toBe('name');
+ );
+
+ expect(input).toContainReactComponent('input', {
+ disabled: true,
+ readOnly: false,
+ autoFocus: true,
+ placeholder: 'A placeholder',
+ value: 'Some value',
+ max: 50,
+ minLength: 2,
+ maxLength: 2,
+ name: 'TextField',
+ spellCheck: false,
+ pattern,
+ min: 20,
+ inputMode,
+ autoComplete: 'name',
+ });
});
it('blocks props not listed as component props to pass on the input', () => {
- const input = mountWithAppProvider(
+ const input = mountWithApp(
', () => {
prefix="test-prefix"
autoComplete="off"
/>,
- ).find('input');
+ );
- expect(input.prop('prefix')).toBeUndefined();
+ expect(input).toContainReactComponent('input', {
+ prefix: undefined,
+ });
});
it('always has an `aria-labelledby` property', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
,
);
- const property = textField.find('input').prop('aria-labelledby');
- expect(property).not.toHaveLength(0);
+ expect(textField).toContainReactComponent('input', {
+ 'aria-labelledby': 'PolarisTextField1Label',
+ });
});
describe('onChange()', () => {
it('is called with the new value', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- (element.find('input') as any).instance().value = 'two';
- element.find('input').simulate('change');
+
+ element.find('input')!.trigger('onChange', {
+ currentTarget: {
+ value: 'two',
+ },
+ });
expect(spy).toHaveBeenCalledWith('two', 'MyTextField');
});
});
@@ -113,7 +120,7 @@ describe('', () => {
describe('onBlur()', () => {
it('is called when the input is blurred', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- element.find('input').simulate('focus');
- element.find('input').simulate('blur');
+ element.find('input')!.trigger('onBlur');
expect(spy).toHaveBeenCalled();
});
});
describe('id', () => {
it('sets the id on the input', () => {
- const id = mountWithAppProvider(
+ const textField = mountWithApp(
,
- )
- .find('input')
- .prop('id');
- expect(id).toBe('MyField');
+ );
+
+ expect(textField).toContainReactComponent('input', {
+ id: 'MyField',
+ });
});
it('sets a random id on the input when none is passed', () => {
- const id = mountWithAppProvider(
+ const textField = mountWithApp(
,
- )
- .find('input')
- .prop('id');
- expect(typeof id).toBe('string');
- expect(id).toBeTruthy();
+ );
+
+ expect(textField).toContainReactComponent('input', {
+ id: 'PolarisTextField1',
+ });
});
it('updates with the new id from props', () => {
const id = 'input field';
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
,
);
textField.setProps({id});
- expect(textField.find('input').prop('id')).toBe(id);
+ expect(textField).toContainReactComponent('input', {
+ id,
+ });
});
it('updates with the previous id after the id prop has been removed', () => {
const id = 'input field';
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
/>,
);
textField.setProps({});
- expect(textField.find('input').prop('id')).toBe(id);
+ expect(textField).toContainReactComponent('input', {
+ id,
+ });
});
});
@@ -218,21 +229,22 @@ describe('', () => {
describe('autoComplete', () => {
it('is passed to input as autoComplete', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
,
);
-
- expect(textField.find('input').prop('autoComplete')).toBe('firstName');
+ expect(textField).toContainReactComponent('input', {
+ autoComplete: 'firstName',
+ });
});
});
describe('helpText', () => {
it('connects the input to the help text', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- const helpTextID = textField
- .find('input')
- .prop('aria-describedby');
- expect(typeof helpTextID).toBe('string');
- expect(textField.find(`#${helpTextID}`).text()).toBe('Some help');
+
+ expect(textField).toContainReactComponent('input', {
+ 'aria-describedby': 'PolarisTextField1HelpText',
+ });
+ expect(textField.find('div')).toContainReactText('Some help');
});
});
describe('error', () => {
it('marks the input as invalid', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
Invalid}
label="TextField"
@@ -258,14 +270,20 @@ describe('', () => {
autoComplete="off"
/>,
);
- expect(textField.find('input').prop('aria-invalid')).toBe(true);
+
+ expect(textField).toContainReactComponent('input', {
+ 'aria-invalid': true,
+ });
textField.setProps({error: 'Some error'});
- expect(textField.find('input').prop('aria-invalid')).toBe(true);
+
+ expect(textField).toContainReactComponent('input', {
+ 'aria-invalid': true,
+ });
});
it('connects the input to the error', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- const errorID = textField.find('input').prop('aria-describedby');
- expect(typeof errorID).toBe('string');
- expect(textField.find(`#${errorID}`).text()).toBe('Some error');
+
+ expect(textField).toContainReactComponent('input', {
+ 'aria-describedby': 'Some error',
+ });
});
it('connects the input to an error rendered separately', () => {
const errorMessage = 'Some error';
const textFieldID = 'collectionRuleType';
- const fieldGroup = mountWithAppProvider(
+ const fieldGroup = mountWithApp(
', () => {
,
);
- const textField = fieldGroup.find(TextField).first();
- const errorID = textField.find('input').prop('aria-describedby');
-
- expect(textField.find('input').prop('aria-invalid')).toBe(true);
- expect(typeof errorID).toBe('string');
- expect(fieldGroup.find(`#${errorID}`).text()).toBe('Some error');
+ expect(fieldGroup.find(TextField)).toContainReactComponent('input', {
+ 'aria-describedby': 'Some error',
+ 'aria-invalid': true,
+ });
});
it('connects the input to both an error and help text', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- const descriptions = textField
- .find('input')
- .prop('aria-describedby')
- .split(' ');
- expect(descriptions).toHaveLength(2);
- expect(textField.find(`#${descriptions[0]}`).text()).toBe('Some error');
- expect(textField.find(`#${descriptions[1]}`).text()).toBe('Some help');
+
+ expect(textField).toContainReactComponent('input', {
+ 'aria-describedby': 'PolarisTextField1Error PolarisTextField1HelpText',
+ });
+
+ expect(textField.find('div')).toContainReactText('Some error');
+ expect(textField.find('div')).toContainReactText('Some help');
});
it('only renders error markup when not a boolean', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
/>,
);
- expect(textField.find(InlineError)).toHaveLength(0);
+ expect(textField).not.toContainReactComponent(InlineError);
textField.setProps({error: 'Some error'});
- expect(textField.find(InlineError)).toHaveLength(1);
+ expect(textField).toContainReactComponent(InlineError);
});
});
describe('prefix', () => {
it('connects the input to the prefix and label', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
});
it('connects the input to the prefix, suffix, and label', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
const mockPrefixButton = (
);
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
textField.find(`#${mockButtonId}`).simulate('click');
expect(onClickSpy).toHaveBeenCalled();
- expect(textField.getDOMNode().querySelector('input')).not.toBe(
+ expect(textField.domNode!.querySelector('input')).not.toBe(
document.activeElement,
);
});
@@ -404,7 +421,7 @@ describe('', () => {
it('does not set focus `onFocus` for the if the `target` is the `prefix`', () => {
const mockButtonId = 'MockPrefix';
const mockPrefixButton = ;
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
describe('suffix', () => {
it('connects the input to the suffix and label', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
const mockSuffixButton = (
);
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
it('does not set focus `onFocus` for the if the `target` is the `suffix`', () => {
const mockButtonId = 'MockSuffix';
const mockSuffixButton = ;
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
describe('characterCount', () => {
it('displays number of characters entered in input field', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
});
it('displays remaining characters as fraction in input field with maxLength', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
});
it('announces updated character count only when input field is in focus', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
describe('type', () => {
it('sets the type on the input', () => {
- const type = mountWithAppProvider(
+ const type = mountWithApp(
', () => {
describe('number', () => {
it('adds an increment button that increases the value', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('adds a decrement button that increases the value', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('handles incrementing from no value', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
});
it('passes the step prop to the input', () => {
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(element.find('input').prop('step')).toBe(6);
+
+ expect(element).toContainReactComponent('input', {
+ step: 6,
+ });
});
it('uses the step prop when incrementing', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('respects a min value', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('respects a max value', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('brings an invalid value up to the min', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('brings an invalid value down to the max', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
});
it('removes increment and decrement buttons when disabled', () => {
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
disabled
/>,
);
- const buttons = element.find('[role="button"]');
- expect(buttons).toHaveLength(0);
+ expect(element).not.toContainReactComponent('[role="button"]');
});
it('removes increment and decrement buttons when readOnly', () => {
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
readOnly
/>,
);
- expect(element.find(Spinner)).toHaveLength(0);
+ expect(element).not.toContainReactComponent(Spinner);
});
it('removes spinner buttons when type is number and step is 0', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(element.find(Spinner)).toHaveLength(0);
+ expect(element).not.toContainReactComponent(Spinner);
});
- it('increments by step when value, step, or both are float numbers', () => {
+ it.only('increments by step when value, step, or both are float numbers', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- element.find('[role="button"]').first().simulate('click');
+
+ element.find('button')!.trigger('onClick');
+ // element.find('[role="button"]').first().simulate('click');
expect(spy).toHaveBeenCalledWith('4.064', 'MyTextField');
});
it('decrements by step when value, step, or both are float numbers', () => {
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('decrements on mouse down', () => {
jest.useFakeTimers();
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('stops decrementing on mouse up', () => {
jest.useFakeTimers();
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
it('stops decrementing on mouse up anywhere in document', () => {
jest.useFakeTimers();
const spy = jest.fn();
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- element
- .find('[role="button"]')
- .last()
- .simulate('mousedown', {button: 0});
+
+ element.find('button')?.trigger('onMouseDown', {button: 0});
+
documentEvent.mouseup();
jest.runOnlyPendingTimers();
@@ -917,7 +937,7 @@ describe('', () => {
describe('multiline', () => {
it('does not render a resizer if `multiline` is false', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(textField.find(Resizer).exists()).toBe(false);
+ expect(textField).not.toContainReactComponent(Resizer);
});
it('renders a resizer with `minimumLines` set to 1 if `multiline` is true', () => {
@@ -980,7 +1000,7 @@ describe('', () => {
describe('aria labels', () => {
it('sets aria labels on the input element', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
/>,
);
- expect(textField.find('input').prop('aria-owns')).toBe('Aria owns');
- expect(textField.find('input').prop('aria-expanded')).toBe(true);
- expect(textField.find('input').prop('aria-activedescendant')).toBe(
- 'Aria active descendant',
- );
- expect(textField.find('input').prop('aria-autocomplete')).toBe(
- 'Aria autocomplete',
- );
- expect(textField.find('input').prop('aria-controls')).toBe(
- 'Aria controls',
- );
+ expect(textField).toContainReactComponent('input', {
+ 'aria-owns': 'Aria owns',
+ 'aria-expanded': true,
+ 'aria-activedescendant': 'Aria active descendant',
+ 'aria-autocomplete': 'Aria autocomplete',
+ 'aria-controls': 'Aria controls',
+ });
});
it('renders a textarea element with `aria-multiline` set to true if multiline greater than 0', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(textField.find('textarea').prop('aria-multiline')).toBe(true);
+ expect(textField).toContainReactComponent('textarea', {
+ 'aria-multiline': true,
+ });
});
it('renders an input element without `aria-multiline` if multiline is equal to 0', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(textField.find('input').prop('aria-multiline')).toBeUndefined();
+ expect(textField).toContainReactComponent('input', {
+ 'aria-multiline': undefined,
+ });
});
it('renders an input element without `aria-multiline` if multiline is undefined', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(textField.find('input').prop('aria-multiline')).toBeUndefined();
+ expect(textField).toContainReactComponent('input', {
+ 'aria-multiline': undefined,
+ });
});
});
describe('Labelled', () => {
it('passes props to Labelled', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
/>,
);
- expect(textField.find(Labelled)).toHaveLength(1);
- expect(textField.find(Labelled).prop('label')).toBe('TextField');
- expect(textField.find(Labelled).prop('id')).toBe('MyField');
- expect(textField.find(Labelled).prop('helpText')).toBe('Help text');
+ expect(textField).toContainReactComponent(Labelled, {
+ id: 'MyField',
+ label: 'TextField',
+ helpText: 'Help text',
+ });
});
it('passes error to Labelled', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
,
);
- expect(textField.find(Labelled).prop('error')).toBe(true);
+ expect(textField).toContainReactComponent(Labelled, {
+ error: true,
+ });
});
it('passes labelHidden to Labelled', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
/>,
);
- expect(textField.find(Labelled).prop('labelHidden')).toBe(true);
+ expect(textField).toContainReactComponent(Labelled, {
+ labelHidden: true,
+ });
});
});
@@ -1123,7 +1150,7 @@ describe('', () => {
onChange={noop}
/>
);
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
/>,
);
- expect(textField.find(Connected)).toHaveLength(1);
- expect(textField.find(Connected).prop('left')).toStrictEqual(
- connectedLeft,
- );
- expect(textField.find(Connected).prop('right')).toStrictEqual(
- connectedRight,
- );
+ expect(textField).toContainReactComponent(Connected, {
+ left: connectedLeft,
+ right: connectedRight,
+ });
});
it('sets focus to the `onClick`', () => {
@@ -1159,7 +1183,7 @@ describe('', () => {
describe('clearButton', () => {
it('renders a clear button when true', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
clearButton
/>,
);
- expect(findByTestID(textField, 'clearButton').exists()).toBeTruthy();
+ expect(textField).toContainReactComponent('button', {
+ className: 'ClearButton',
+ });
});
it('does not render a clear button in inputs without a value', () => {
@@ -1186,13 +1212,13 @@ describe('', () => {
);
expect(textField).not.toContainReactComponent('button', {
- testID: 'clearButton',
+ className: 'ClearButton',
});
});
it('calls onClearButtonClicked() with an id when the clear button is clicked', () => {
const spy = jest.fn();
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
clearButton
/>,
);
- findByTestID(textField, 'clearButton').simulate('click');
+
+ textField.find('button', {className: 'ClearButton'})!.trigger('onClick');
+
expect(spy).toHaveBeenCalledWith('MyTextField');
});
it('does not render a clear button by default', () => {
- const textField = mountWithAppProvider(
+ const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(findByTestID(textField, 'clearButton').exists()).toBeFalsy();
+
+ expect(textField).not.toContainReactComponent('button', {
+ className: 'ClearButton',
+ });
});
it('adds a connected left and right class when a connected element is present', () => {
@@ -1240,7 +1271,7 @@ describe('', () => {
describe('requiredIndicator', () => {
it('passes requiredIndicator prop to Labelled', () => {
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
requiredIndicator
/>,
);
- const labelled = element.find(Labelled);
- expect(labelled.prop('requiredIndicator')).toBe(true);
+ expect(element).toContainReactComponent(Labelled, {
+ requiredIndicator: true,
+ });
});
});
describe('monospaced', () => {
it('passes monospaced prop to TextField', () => {
- const element = mountWithAppProvider(
+ const element = mountWithApp(
', () => {
autoComplete="off"
/>,
);
- expect(element.prop('monospaced')).toBe(true);
+ expect(element).toHaveReactProps({
+ monospaced: true,
+ });
});
it('applies the monospaced style', () => {
- const input = mountWithAppProvider(
+ const input = mountWithApp(
,
- ).find('input');
+ );
- expect(input.prop('className')).toContain('monospaced');
+ expect(input).toContainReactComponent('input', {
+ className: 'monospaced',
+ });
});
});
});
From aee7ab43d81a957ac3e9326cdea77ae2ee108e92 Mon Sep 17 00:00:00 2001
From: Richard Todd
Date: Thu, 2 Sep 2021 16:36:05 -0400
Subject: [PATCH 2/4] Updated mouse tests
---
.../TextField/tests/TextField.test.tsx | 25 +++++++++----------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/src/components/TextField/tests/TextField.test.tsx b/src/components/TextField/tests/TextField.test.tsx
index f044d6ab53a..089bef021e1 100644
--- a/src/components/TextField/tests/TextField.test.tsx
+++ b/src/components/TextField/tests/TextField.test.tsx
@@ -810,7 +810,7 @@ describe('', () => {
expect(element).not.toContainReactComponent(Spinner);
});
- it.only('increments by step when value, step, or both are float numbers', () => {
+ it('increments by step when value, step, or both are float numbers', () => {
const spy = jest.fn();
const element = mountWithApp(
', () => {
/>,
);
- element.find('button')!.trigger('onClick');
- // element.find('[role="button"]').first().simulate('click');
+ element.findAll('div', {role: 'button'})[0].trigger('onClick');
expect(spy).toHaveBeenCalledWith('4.064', 'MyTextField');
});
@@ -842,7 +841,8 @@ describe('', () => {
autoComplete="off"
/>,
);
- element.find('[role="button"]').last().simulate('click');
+ element.findAll('div', {role: 'button'})[1].trigger('onClick');
+
expect(spy).toHaveBeenCalledWith('1.976', 'MyTextField');
});
@@ -860,9 +860,8 @@ describe('', () => {
/>,
);
element
- .find('[role="button"]')
- .last()
- .simulate('mousedown', {button: 0});
+ .findAll('div', {role: 'button'})[1]
+ .trigger('onMouseDown', {button: 0});
jest.runOnlyPendingTimers();
expect(spy).toHaveBeenCalledWith('2', 'MyTextField');
@@ -881,11 +880,11 @@ describe('', () => {
autoComplete="off"
/>,
);
- element
- .find('[role="button"]')
- .last()
- .simulate('mousedown', {button: 0});
- element.find('[role="button"]').last().simulate('mouseup');
+
+ const buttonDiv = element.findAll('div', {role: 'button'})[1];
+
+ buttonDiv.trigger('onMouseDown', {button: 0});
+ buttonDiv.trigger('onMouseUp');
jest.runOnlyPendingTimers();
expect(spy).not.toHaveBeenCalled();
@@ -924,7 +923,7 @@ describe('', () => {
/>,
);
- element.find('button')?.trigger('onMouseDown', {button: 0});
+ element.find('button')!.trigger('onMouseDown', {button: 0});
documentEvent.mouseup();
From 25217a516504e3c7a4d56567f9d5a90df3416cbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Karen=20Pinz=C3=A1s=20Morrongiello?=
<45268098+kpinzas-sh@users.noreply.github.com>
Date: Thu, 2 Sep 2021 21:51:23 -0400
Subject: [PATCH 3/4] Fix tests related to Decrement increment buttons
---
UNRELEASED.md | 2 +-
.../TextField/tests/TextField.test.tsx | 220 ++++++++++++------
2 files changed, 153 insertions(+), 69 deletions(-)
diff --git a/UNRELEASED.md b/UNRELEASED.md
index 1e82289319c..95a74b5bf65 100644
--- a/UNRELEASED.md
+++ b/UNRELEASED.md
@@ -83,6 +83,6 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
- Modernized tests for PopoverOverlay component([#4430](https://github.com/Shopify/polaris-react/pull/4430))
- Modernized tests for Dropzone, ExceptionList, and ConnectedFilterControl > Item components([#4412](https://github.com/Shopify/polaris-react/pull/4412))
- Modernized tests for DatePicker, DescriptionList, and DisplayText ([#4360](https://github.com/Shopify/polaris-react/pull/4360))
-- Modernized tests for TextField ([]()).
+- Modernized tests for TextField ([#4456](https://github.com/Shopify/polaris-react/pull/4456)).
### Deprecations
diff --git a/src/components/TextField/tests/TextField.test.tsx b/src/components/TextField/tests/TextField.test.tsx
index 089bef021e1..9bacff55ab9 100644
--- a/src/components/TextField/tests/TextField.test.tsx
+++ b/src/components/TextField/tests/TextField.test.tsx
@@ -293,7 +293,7 @@ describe('', () => {
);
expect(textField).toContainReactComponent('input', {
- 'aria-describedby': 'Some error',
+ 'aria-describedby': 'PolarisTextField1Error',
});
});
@@ -314,7 +314,7 @@ describe('', () => {
);
expect(fieldGroup.find(TextField)).toContainReactComponent('input', {
- 'aria-describedby': 'Some error',
+ 'aria-describedby': 'collectionRuleTypeError',
'aria-invalid': true,
});
});
@@ -366,13 +366,24 @@ describe('', () => {
autoComplete="off"
/>,
);
+
const labels = textField
- .find('input')
- .prop('aria-labelledby')
+ .find('input')!
+ .prop('aria-labelledby')!
.split(' ');
expect(labels).toHaveLength(2);
- expect(textField.find(`#${labels[0]}`).text()).toBe('TextField');
- expect(textField.find(`#${labels[1]}`).text()).toBe('$');
+
+ expect(
+ textField.find('label', {
+ id: `${labels[0]}`,
+ }),
+ )!.toContainReactText('TextField');
+
+ expect(
+ textField.find('div', {
+ id: `${labels[1]}`,
+ }),
+ )!.toContainReactText('$');
});
it('connects the input to the prefix, suffix, and label', () => {
@@ -386,13 +397,28 @@ describe('', () => {
/>,
);
const labels = textField
- .find('input')
- .prop('aria-labelledby')
+ .find('input')!
+ .prop('aria-labelledby')!
.split(' ');
expect(labels).toHaveLength(3);
- expect(textField.find(`#${labels[0]}`).text()).toBe('TextField');
- expect(textField.find(`#${labels[1]}`).text()).toBe('$');
- expect(textField.find(`#${labels[2]}`).text()).toBe('.00');
+
+ expect(
+ textField.find('label', {
+ id: `${labels[0]}`,
+ }),
+ )!.toContainReactText('TextField');
+
+ expect(
+ textField.find('div', {
+ id: `${labels[1]}`,
+ }),
+ )!.toContainReactText('$');
+
+ expect(
+ textField.find('div', {
+ id: `${labels[2]}`,
+ }),
+ )!.toContainReactText('.00');
});
it('does not set focus `onClick` for the if the `target` is the `prefix`', () => {
@@ -410,12 +436,10 @@ describe('', () => {
/>,
);
- textField.find(`#${mockButtonId}`).simulate('click');
+ textField.find('button', {id: mockButtonId})!.trigger('onClick');
expect(onClickSpy).toHaveBeenCalled();
- expect(textField.domNode!.querySelector('input')).not.toBe(
- document.activeElement,
- );
+ expect(document.activeElement).not.toBe(textField.find('input')!.domNode);
});
it('does not set focus `onFocus` for the if the `target` is the `prefix`', () => {
@@ -430,14 +454,11 @@ describe('', () => {
/>,
);
- textField.find(`#${mockButtonId}`).simulate('focus');
+ textField.find('button', {id: mockButtonId})!.trigger('onFocus');
- const connectedInteriorWrapper = textField
- .find(Connected)
- .find('div')
- .first();
-
- expect(connectedInteriorWrapper.hasClass('focus')).toBe(false);
+ expect(textField.find(Connected)!).not.toContainReactComponent('div', {
+ className: expect.stringContaining('focus'),
+ });
});
});
@@ -452,12 +473,22 @@ describe('', () => {
/>,
);
const labels = textField
- .find('input')
- .prop('aria-labelledby')
+ .find('input')!
+ .prop('aria-labelledby')!
.split(' ');
expect(labels).toHaveLength(2);
- expect(textField.find(`#${labels[0]}`).text()).toBe('TextField');
- expect(textField.find(`#${labels[1]}`).text()).toBe('kg');
+
+ expect(
+ textField.find('label', {
+ id: `${labels[0]}`,
+ }),
+ )!.toContainReactText('TextField');
+
+ expect(
+ textField.find('div', {
+ id: `${labels[1]}`,
+ }),
+ )!.toContainReactText('kg');
});
it('does not set focus `onClick` for the if the `target` is the `suffix`', () => {
@@ -475,12 +506,11 @@ describe('', () => {
/>,
);
- textField.find(`#${mockButtonId}`).simulate('click');
+ textField.find('button', {id: mockButtonId})!.trigger('onClick');
expect(onClickSpy).toHaveBeenCalled();
- expect(textField.getDOMNode().querySelector('input')).not.toBe(
- document.activeElement,
- );
+
+ expect(document.activeElement).not.toBe(textField.find('input')!.domNode);
});
it('does not set focus `onFocus` for the if the `target` is the `suffix`', () => {
@@ -495,14 +525,11 @@ describe('', () => {
/>,
);
- textField.find(`#${mockButtonId}`).simulate('focus');
+ textField.find('button', {id: mockButtonId})!.trigger('onFocus');
- const connectedInteriorWrapper = textField
- .find(Connected)
- .find('div')
- .first();
-
- expect(connectedInteriorWrapper.hasClass('focus')).toBe(false);
+ expect(textField.find(Connected)!).not.toContainReactComponent('div', {
+ className: expect.stringContaining('focus'),
+ });
});
});
@@ -519,9 +546,11 @@ describe('', () => {
/>,
);
- const characterCount = textField.find('#MyFieldCharacterCounter');
-
- expect(characterCount.text()).toBe('4');
+ expect(
+ textField.find('div', {
+ id: 'MyFieldCharacterCounter',
+ }),
+ ).toContainReactText('4');
});
it('displays remaining characters as fraction in input field with maxLength', () => {
@@ -537,9 +566,11 @@ describe('', () => {
/>,
);
- const characterCount = textField.find('#MyFieldCharacterCounter');
-
- expect(characterCount.text()).toBe('4/10');
+ expect(
+ textField.find('div', {
+ id: 'MyFieldCharacterCounter',
+ }),
+ ).toContainReactText('4/10');
});
it('announces updated character count only when input field is in focus', () => {
@@ -554,30 +585,34 @@ describe('', () => {
/>,
);
- expect(textField.find('#MyFieldCharacterCounter').prop('aria-live')).toBe(
- 'off',
- );
+ expect(textField).toContainReactComponent('div', {
+ id: 'MyFieldCharacterCounter',
+ 'aria-live': 'off',
+ });
- textField.find('input').simulate('focus');
- expect(textField.find('#MyFieldCharacterCounter').prop('aria-live')).toBe(
- 'polite',
- );
+ textField.find('input')!.trigger('onFocus');
+
+ expect(textField).toContainReactComponent('div', {
+ id: 'MyFieldCharacterCounter',
+ 'aria-live': 'polite',
+ });
});
});
describe('type', () => {
it('sets the type on the input', () => {
- const type = mountWithApp(
+ const textField = mountWithApp(
,
- )
- .find('input')
- .prop('type');
- expect(type).toBe('email');
+ );
+
+ expect(textField).toContainReactComponent('input', {
+ type: 'email',
+ });
});
describe('number', () => {
@@ -593,7 +628,11 @@ describe('', () => {
autoComplete="off"
/>,
);
- element.find('[role="button"]').first().simulate('click');
+ element!
+ .find('div', {
+ role: 'button',
+ })!
+ .trigger('onClick');
expect(spy).toHaveBeenCalledWith('4', 'MyTextField');
});
@@ -609,7 +648,12 @@ describe('', () => {
autoComplete="off"
/>,
);
- element.find('[role="button"]').last().simulate('click');
+
+ element
+ .findAll('div', {
+ role: 'button',
+ })[1]!
+ .trigger('onClick');
expect(spy).toHaveBeenCalledWith('2', 'MyTextField');
});
@@ -646,7 +690,11 @@ describe('', () => {
autoComplete="off"
/>,
);
- element.find('[role="button"]').first().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[0]!
+ .trigger('onClick');
expect(spy).toHaveBeenCalledWith('1', 'MyTextField');
});
@@ -681,7 +729,11 @@ describe('', () => {
autoComplete="off"
/>,
);
- element.find('[role="button"]').first().simulate('click');
+ element!
+ .find('div', {
+ role: 'button',
+ })!
+ .trigger('onClick');
expect(spy).toHaveBeenCalledWith('1.75', 'MyTextField');
});
@@ -699,10 +751,18 @@ describe('', () => {
/>,
);
- element.find('[role="button"]').last().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[1]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('2', 'MyTextField');
- element.find('[role="button"]').first().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[0]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('3', 'MyTextField');
});
@@ -720,10 +780,18 @@ describe('', () => {
/>,
);
- element.find('[role="button"]').first().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[0]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('2', 'MyTextField');
- element.find('[role="button"]').last().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[1]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('1', 'MyTextField');
});
@@ -741,10 +809,18 @@ describe('', () => {
/>,
);
- element.find('[role="button"]').first().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[0]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('2', 'MyTextField');
- element.find('[role="button"]').last().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[1]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('2', 'MyTextField');
});
@@ -762,10 +838,18 @@ describe('', () => {
/>,
);
- element.find('[role="button"]').first().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[0]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('2', 'MyTextField');
- element.find('[role="button"]').last().simulate('click');
+ element
+ .findAll('div', {
+ role: 'button',
+ })[1]!
+ .trigger('onClick');
expect(spy).toHaveBeenLastCalledWith('2', 'MyTextField');
});
@@ -1311,7 +1395,7 @@ describe('', () => {
);
expect(input).toContainReactComponent('input', {
- className: 'monospaced',
+ className: expect.stringContaining('monospaced'),
});
});
});
From facc65dda6cbf04e1399d8f808f76a8c426b14d2 Mon Sep 17 00:00:00 2001
From: Richard Todd
Date: Fri, 3 Sep 2021 10:59:18 -0400
Subject: [PATCH 4/4] Updated final textField tests
---
.../TextField/tests/TextField.test.tsx | 61 ++++++++++++-------
1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/src/components/TextField/tests/TextField.test.tsx b/src/components/TextField/tests/TextField.test.tsx
index 9bacff55ab9..41414fa70c3 100644
--- a/src/components/TextField/tests/TextField.test.tsx
+++ b/src/components/TextField/tests/TextField.test.tsx
@@ -4,6 +4,7 @@ import {mountWithApp} from 'test-utilities';
import {Resizer, Spinner} from '../components';
import {TextField} from '../TextField';
+import styles from '../TextField.scss';
describe('', () => {
it('allows specific props to pass through properties on the input', () => {
@@ -422,11 +423,8 @@ describe('', () => {
});
it('does not set focus `onClick` for the if the `target` is the `prefix`', () => {
- const onClickSpy = jest.fn();
const mockButtonId = 'MockPrefix';
- const mockPrefixButton = (
-
- );
+ const mockPrefixButton = ;
const textField = mountWithApp(
', () => {
/>,
);
- textField.find('button', {id: mockButtonId})!.trigger('onClick');
+ const button = textField.find('button', {id: mockButtonId})!.domNode!;
- expect(onClickSpy).toHaveBeenCalled();
- expect(document.activeElement).not.toBe(textField.find('input')!.domNode);
+ textField
+ .find('div', {className: styles.TextField})!
+ .trigger('onClick', {target: button});
+
+ expect(textField.find(Connected)!).not.toContainReactComponent('div', {
+ className: expect.stringContaining(styles.focus),
+ });
});
it('does not set focus `onFocus` for the if the `target` is the `prefix`', () => {
@@ -454,10 +457,14 @@ describe('', () => {
/>,
);
- textField.find('button', {id: mockButtonId})!.trigger('onFocus');
+ const button = textField.find('button', {id: mockButtonId})!.domNode!;
+
+ textField
+ .find('div', {className: styles.TextField})!
+ .trigger('onFocus', {target: button});
expect(textField.find(Connected)!).not.toContainReactComponent('div', {
- className: expect.stringContaining('focus'),
+ className: expect.stringContaining(styles.focus),
});
});
});
@@ -492,11 +499,8 @@ describe('', () => {
});
it('does not set focus `onClick` for the if the `target` is the `suffix`', () => {
- const onClickSpy = jest.fn();
const mockButtonId = 'MockSuffix';
- const mockSuffixButton = (
-
- );
+ const mockSuffixButton = ;
const textField = mountWithApp(
', () => {
autoComplete="off"
/>,
);
+ const button = textField.find('button', {id: mockButtonId})!.domNode!;
- textField.find('button', {id: mockButtonId})!.trigger('onClick');
+ textField
+ .find('div', {className: styles.TextField})!
+ .trigger('onClick', {target: button});
- expect(onClickSpy).toHaveBeenCalled();
-
- expect(document.activeElement).not.toBe(textField.find('input')!.domNode);
+ expect(textField.find(Connected)!).not.toContainReactComponent('div', {
+ className: expect.stringContaining(styles.focus),
+ });
});
it('does not set focus `onFocus` for the if the `target` is the `suffix`', () => {
@@ -525,7 +532,11 @@ describe('', () => {
/>,
);
- textField.find('button', {id: mockButtonId})!.trigger('onFocus');
+ const button = textField.find('button', {id: mockButtonId})!.domNode!;
+
+ textField
+ .find('div', {className: styles.TextField})!
+ .trigger('onFocus', {target: button});
expect(textField.find(Connected)!).not.toContainReactComponent('div', {
className: expect.stringContaining('focus'),
@@ -590,7 +601,11 @@ describe('', () => {
'aria-live': 'off',
});
- textField.find('input')!.trigger('onFocus');
+ const textFieldDiv = textField.find('div', {
+ className: 'TextField hasValue',
+ })!;
+ // onClick callback sets dom focus on input
+ textFieldDiv.trigger('onClick', {target: textFieldDiv.domNode!});
expect(textField).toContainReactComponent('div', {
id: 'MyFieldCharacterCounter',
@@ -1007,7 +1022,9 @@ describe('', () => {
/>,
);
- element.find('button')!.trigger('onMouseDown', {button: 0});
+ element
+ .findAll('div', {role: 'button'})[1]
+ .trigger('onMouseDown', {button: 0});
documentEvent.mouseup();
@@ -1091,7 +1108,7 @@ describe('', () => {
ariaOwns="Aria owns"
ariaExpanded
ariaActiveDescendant="Aria active descendant"
- ariaAutocomplete="Aria autocomplete"
+ ariaAutocomplete="inline"
ariaControls="Aria controls"
autoComplete="off"
/>,
@@ -1101,7 +1118,7 @@ describe('', () => {
'aria-owns': 'Aria owns',
'aria-expanded': true,
'aria-activedescendant': 'Aria active descendant',
- 'aria-autocomplete': 'Aria autocomplete',
+ 'aria-autocomplete': 'inline',
'aria-controls': 'Aria controls',
});
});