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('', () => { 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(', ) - .find('select') - .simulate('focus'); + .find('select')! + .trigger('onFocus'); expect(spy).toHaveBeenCalled(); }); }); @@ -39,11 +45,11 @@ describe(', ); - element.find('select').simulate('focus'); - element.find('select').simulate('blur'); + element.find('select')!.trigger('onBlur'); + expect(spy).toHaveBeenCalled(); }); }); @@ -51,14 +57,13 @@ describe(', - ).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(', - ).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(', - ).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') - .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') - .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') + .find('select')! .prop('id'); expect(typeof id).toBe('string'); expect(id).toBeTruthy(); @@ -184,22 +186,22 @@ describe(', ); - 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(); }); }); @@ -212,23 +214,19 @@ describe(', ); - 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( , - ).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( Invalid} label="Select" onChange={noop} />, ); - expect(select.find('select').prop('aria-invalid')).toBe(true); + expect(select).toContainReactComponent('select', {'aria-invalid': true}); select.setProps({error: 'Some error'}); - expect(select.find('select').prop('aria-invalid')).toBe(true); + expect(select).toContainReactComponent('select', {'aria-invalid': true}); select.setProps({error: 'true'}); - expect(select.find('select').prop('aria-invalid')).toBe(true); + expect(select).toContainReactComponent('select', {'aria-invalid': true}); }); it('connects the select to the error', () => { - const select = mountWithAppProvider( + const select = mountWithApp( ', () => {
, ); - const select = fieldGroup.find(Select).last(); - const errorID = select.find('select').prop('aria-describedby'); + const selects = fieldGroup.findAll(Select)!; + const select = selects[selects.length - 1]; + const errorID = select.find('select')!.prop('aria-describedby'); - expect(select.find('select').prop('aria-invalid')).toBe(true); + expect(select).toContainReactComponent('select', {'aria-invalid': true}); expect(typeof errorID).toBe('string'); - expect(fieldGroup.find(`#${errorID}`).text()).toBe('Some error'); + expect(fieldGroup.find('div', {id: errorID})!).toContainReactText( + 'Some error', + ); }); it('connects the select to both an error and help text', () => { - const select = mountWithAppProvider( + const select = mountWithApp( ', () => { />, ); - expect(select.find(InlineError)).toHaveLength(1); + expect(select).toContainReactComponent(InlineError); }); it('does not render error markup when a boolean value', () => { - const select = mountWithAppProvider( + const select = mountWithApp( , ); - const labelled = element.find(Labelled); - expect(labelled.prop('requiredIndicator')).toBe(true); + expect(element).toContainReactComponent(Labelled, { + requiredIndicator: true, + }); }); }); }); diff --git a/src/components/SettingToggle/tests/SettingToggle.test.tsx b/src/components/SettingToggle/tests/SettingToggle.test.tsx index c46381fb379..802b554ce17 100644 --- a/src/components/SettingToggle/tests/SettingToggle.test.tsx +++ b/src/components/SettingToggle/tests/SettingToggle.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 {SettingAction} from 'components/SettingAction'; import {SettingToggle} from '../SettingToggle'; @@ -16,9 +15,9 @@ describe('', () => { content: 'Click me!', onAction: noop, }; - const toggle = mountWithAppProvider(); + const toggle = mountWithApp(); const {children} = getComponentProps( - toggle.find(SettingAction).prop('action'), + toggle.find(SettingAction)!.prop('action'), ); expect(children).toBe('Click me!'); }); @@ -30,9 +29,9 @@ describe('', () => { content: 'Click me!', onAction: noop, }; - const toggle = mountWithAppProvider(); + const toggle = mountWithApp(); const {primary} = getComponentProps( - toggle.find(SettingAction).prop('action'), + toggle.find(SettingAction)!.prop('action'), ); expect(primary).toBeTruthy(); }); @@ -42,11 +41,9 @@ describe('', () => { content: 'Click me!', onAction: noop, }; - const toggle = mountWithAppProvider( - , - ); + const toggle = mountWithApp(); const {primary} = getComponentProps( - toggle.find(SettingAction).prop('action'), + toggle.find(SettingAction)!.prop('action'), ); expect(primary).toBeFalsy(); }); @@ -54,11 +51,9 @@ describe('', () => { describe('children', () => { it('renders the given children', () => { - const children =
; - const toggle = mountWithAppProvider( - {children}, - ); - expect(toggle.contains(children)).toBeTruthy(); + const children =
; + const toggle = mountWithApp({children}); + expect(toggle).toContainReactComponent('div', {id: 'someId'}); }); }); }); diff --git a/src/components/Sheet/tests/Sheet.test.tsx b/src/components/Sheet/tests/Sheet.test.tsx index ef631a72e85..f378a04d3e5 100644 --- a/src/components/Sheet/tests/Sheet.test.tsx +++ b/src/components/Sheet/tests/Sheet.test.tsx @@ -1,8 +1,6 @@ /* eslint-disable import/no-deprecated */ import React, {useRef} from 'react'; import {CSSTransition} from 'react-transition-group'; -// eslint-disable-next-line no-restricted-imports -import {mountWithAppProvider} from 'test-utilities/legacy'; import {Backdrop, Button} from 'components'; import {mountWithApp} from 'test-utilities'; @@ -18,64 +16,60 @@ describe('', () => { it('renders its children', () => { const children =
Content
; - const sheet = mountWithAppProvider( - {children}, - ); + const sheet = mountWithApp({children}); - expect(sheet.find(children)).not.toBeNull(); + expect(sheet).toContainReactComponent('div', {children: 'Content'}); }); it('renders a Backdrop when open', () => { const children =
Content
; - - const sheet = mountWithAppProvider( - {children}, - ); - const backdrop = sheet.find(Backdrop); - expect(backdrop).not.toBeNull(); + const sheet = mountWithApp({children}); + expect(sheet).toContainReactComponent(Backdrop); }); it('renders a css transition component with bottom class names at mobile sizes', () => { - const sheet = mountWithAppProvider( + const sheet = mountWithApp(
Content
, {mediaQuery: {isNavigationCollapsed: true}}, ); - expect(sheet.find(CSSTransition).props().classNames).toStrictEqual({ - enter: 'Bottom enterBottom', - enterActive: 'Bottom enterBottomActive', - exit: 'Bottom exitBottom', - exitActive: 'Bottom exitBottomActive', + expect(sheet).toContainReactComponent(CSSTransition, { + classNames: { + enter: 'Bottom enterBottom', + enterActive: 'Bottom enterBottomActive', + exit: 'Bottom exitBottom', + exitActive: 'Bottom exitBottomActive', + }, }); }); it('renders a css transition component with right class names at desktop sizes', () => { - const sheet = mountWithAppProvider( + const sheet = mountWithApp(
Content
, ); - expect(sheet.find(CSSTransition).props().classNames).toStrictEqual({ - enter: 'Right enterRight', - enterActive: 'Right enterRightActive', - exit: 'Right exitRight', - exitActive: 'Right exitRightActive', + expect(sheet).toContainReactComponent(CSSTransition, { + classNames: { + enter: 'Right enterRight', + enterActive: 'Right enterRightActive', + exit: 'Right exitRight', + exitActive: 'Right exitRightActive', + }, }); }); it('renders an aria label', () => { const children =
Content
; + const sheet = mountWithApp({children}); - const sheet = mountWithAppProvider( - {children}, - ); - - expect(sheet.find('div[role="dialog"]').prop('aria-label')).toBe( - mockProps.accessibilityLabel, - ); + expect(sheet).toContainReactComponent('div', { + role: 'dialog', + 'aria-label': mockProps.accessibilityLabel, + }); }); describe('activator', () => { @@ -91,13 +85,13 @@ describe('', () => { }); it('renders the element if an element is passed in', () => { - const sheet = mountWithAppProvider( + const sheet = mountWithApp( }>
Content
, ); - expect(sheet.find(Button).exists()).toBe(true); + expect(sheet).toContainReactComponent(Button); }); it('does not render the element if a ref object is passed in', () => { @@ -125,7 +119,7 @@ describe('', () => { }); it('does not throw an error when no activator is passed in', () => { - const sheet = mountWithAppProvider( + const sheet = mountWithApp(
Content
, diff --git a/src/components/Spinner/tests/Spinner.test.tsx b/src/components/Spinner/tests/Spinner.test.tsx index f5940d8c61d..0261b133546 100644 --- a/src/components/Spinner/tests/Spinner.test.tsx +++ b/src/components/Spinner/tests/Spinner.test.tsx @@ -19,22 +19,25 @@ describe('', () => { describe('size', () => { it('renders a large spinner by default', () => { const spinner = mountWithApp(); - expect(spinner).toContainReactComponent('span', { - className: 'Spinner sizeLarge', + + expect(spinner).toContainReactComponentTimes('span', 1, { + className: expect.stringContaining('sizeLarge'), }); }); it('renders a large spinner when size is large', () => { const spinner = mountWithApp(); - expect(spinner).toContainReactComponent('span', { - className: 'Spinner sizeLarge', + + expect(spinner).toContainReactComponentTimes('span', 1, { + className: expect.stringContaining('sizeLarge'), }); }); it('renders a small spinner when size is small', () => { const spinner = mountWithApp(); - expect(spinner).toContainReactComponent('span', { - className: 'Spinner sizeSmall', + + expect(spinner).toContainReactComponentTimes('span', 1, { + className: expect.stringContaining('sizeSmall'), }); }); }); diff --git a/src/components/Sticky/tests/Sticky.test.tsx b/src/components/Sticky/tests/Sticky.test.tsx index 2079de99aa7..8f9b0327960 100644 --- a/src/components/Sticky/tests/Sticky.test.tsx +++ b/src/components/Sticky/tests/Sticky.test.tsx @@ -1,28 +1,27 @@ import React from 'react'; -// eslint-disable-next-line no-restricted-imports -import {mountWithAppProvider} from 'test-utilities/legacy'; +import {mountWithApp} from 'test-utilities'; import {Sticky} from '../Sticky'; describe('', () => { it('renders children component', () => { - const element = mountWithAppProvider( + const element = mountWithApp( , ); - expect(element.find('h1').exists()).toBe(true); + expect(element).toContainReactComponent('h1'); }); it('renders a function as child component with a boolean argument set to false by default', () => { - const element = mountWithAppProvider({functionItem}); - expect(element.find('h1').exists()).toBe(true); - expect(element.find('h2').exists()).toBe(false); + const element = mountWithApp({functionItem}); + expect(element).toContainReactComponent('h1'); + expect(element).not.toContainReactComponent('h2'); }); describe('lifecycle', () => { it('unmounts safely', () => { - const sticky = mountWithAppProvider( + const sticky = mountWithApp(

Child content

, diff --git a/src/components/Subheading/tests/Subheading.test.tsx b/src/components/Subheading/tests/Subheading.test.tsx index c72bc6f83ec..de4b2ec5d94 100644 --- a/src/components/Subheading/tests/Subheading.test.tsx +++ b/src/components/Subheading/tests/Subheading.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} from 'components'; import {Subheading} from '../Subheading'; @@ -8,36 +7,39 @@ import {Subheading} from '../Subheading'; describe('', () => { describe('children', () => { it('renders its children', () => { - const subheading = mountWithAppProvider(Title); - expect(subheading.text()).toBe('Title'); + const subheading = mountWithApp(Title); + expect(subheading).toContainReactText('Title'); + expect(subheading).toHaveReactProps({children: 'Title'}); }); it('sets aria-label as children if it is a string', () => { - const subheading = mountWithAppProvider(Title); - expect(subheading.find('h3').prop('aria-label')).toBe('Title'); + const subheading = mountWithApp(Title); + expect(subheading).toContainReactComponent('h3', {'aria-label': 'Title'}); }); it('does not set aria-label if children is a React component', () => { - const subheading = mountWithAppProvider( + const subheading = mountWithApp( , ); - expect(subheading.find('h3').prop('aria-label')).toBeUndefined(); + expect(subheading).toContainReactComponent('h3', { + 'aria-label': undefined, + }); }); }); describe('element', () => { it('renders provided element', () => { - const subheading = mountWithAppProvider( + const subheading = mountWithApp( Title, ); - expect(subheading.find('h2')).toHaveLength(1); + expect(subheading).toContainReactComponentTimes('h2', 1); }); it('defaults to h3 if element is not provided', () => { - const subheading = mountWithAppProvider(Title); - expect(subheading.find('h3')).toHaveLength(1); + const subheading = mountWithApp(Title); + expect(subheading).toContainReactComponentTimes('h3', 1); }); }); });