Skip to content

Commit 44084d9

Browse files
dcalhounfluiddot
authored andcommitted
Fix native test timeouts caused by combining fake timers and setImmediate (#37715)
* Upgrade to @testing-library/[email protected] * Clean up fake timer usage after tests This may be unnecessary, but avoid potential issues where fake timers are unexpectedly used and cause breakages in other tests. * Enable combination of modern fake timers and waitFor Previously, `waitFor` would timeout when `jest.useFakeTimers('modern')` was enabled. The 'modern' version is now the default in Jest 27. The Jest preset from `@testing-library/react-native` provides a workaround for a larger issue in React Native and Jest that mutates the global `Promise` object. https://git.io/JSDZI * Remove global enabling of fake timers Enabling fake timers can have negative consequences with `waitFor`, e.g. causing unexpected timeouts. Enabling it globally is far-reaching and this should likely be enabled within individual tests as needed. * Replace jest-jasmine2 with jest-circus The latter is considered the successor to the former. We seemingly do not depend on anything explicitly provided by `jest-jasmine2` and should likely move on from it. * Switch testing environment from jsdom to node Improves speed of test environment setup and fixes a timeout issue when combining `waitFor` and `jest.useFakeTimers('modern')`. It is not yet exactly pinpointed as to _why_ this fixes the timeout issue. It appears to related to `setImmediate` and `setTimeout`. * Remove setImmediate global for testing environment This may be unnecessary if `testEnvironment: 'node'` is retained. However, most tests are currently broken due to missing DOM APIs. * Polyfill required DOM APIs for testing environment Now that `testEnvironment: 'node'` is utilized for the testing environment, we must mirror the app runtime and polyfill the necessary DOM APIs used in the source. The Enzyme configuration removed conflicts with the switch from `testEnvironment: 'jsdom'` to `testEnvironment: 'node'`. Enzyme depends upon `react-dom`, which introduces far more dependencies upon DOM APIs. Currently, all Enzyme-related tests fail and need to be replaced with `@testing-library/react-native`. * Avoid import of react-dom within native file Importing `react-dom` introduces additional dependencies upon the DOM API and is incompatible with `testEnvironment: 'node'`. The `act` utility is available from `@testing-library/react-native`. * Explicitly toggle fake timers in tests This may not be necessary, but may help avoid unexpected issues from lingering fake timers, e.g. timeout errors while using `waitFor`. * Reinstate legacy Jest timers The Jest preset from `@testing-library/react-native` that fixed support for "modern" timers by modifying the polyfilled the global `Promise` resulted in new failures from within React Native itself. Specifically, core React Native components rely upon `.done` from the `promise` package. `.done` is a non-standard method that does not exist on the global `Promise` used by `@testing-library/react-native`'s preset. * Disable erroneously failing test This previously passing test now fails after upgrading `@testing-library/react-native` due to changes in the library. Setting `pointerEvent` to "box-none" or "none" currently erroneously prevents triggering other events unrelated to pressing on the element, e.g. `onTouch*`, `onLayout`. https://git.io/JSHZt * Reinstate jest-jasmine2 to support done callback The Jest team create jest-circus as the predecessor for jest-jasmine2. The former does not support the `done` callback with async/await, and would appear to have no plans to do so. It would likely benefit us to refactor the one current test using `done` away from it, and embrace `jest-circus` to maintain alignment with Jest core. * Refactor native unit tests away from done callback The Jest team created `jest-circus` as the predecessor for `jest-jasmine2`. The former does not support the `done` callback with async/await, and would appear to have no plans to do so. In order to embrace `jest-circus` and maintain alignment with Jest core, the one test using `done` was refactored to avoid it - https://git.io/JSHWU - https://git.io/JSHWk * Remove Enzyme from Editor tests * Remove Enzyme from Paragraph tests * Remove Enzyme from BlockMover tests * Remove Enzyme from BlockEdit test * Remove Enzyme from LinksUI test * Remove Enzyme from ListEdit tests * Remove Enzyme from Platform tests * Remove Enzyme from BlockTypesTab tests * Remove Enzyme from HTMLTextInput tests * Remove Enzyme from ReusableBlockTab tests * Remove Enzyme from MediaUpload tests * Remove Enzyme from BlockMediaUpdateProgress tests * Remove Enzyme from MediaUploadProgress tests * Fix ReferencEerror in Inserter test Usage of `react-test-renderer` caused the following error. Leveraging `@testing-library/react-native` instead resolved it for an unknown reason. ``` ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From packages/block-editor/src/components/inserter/test/index.native.js. 468 | style: listStyle, 469 | safeAreaBottomInset, > 470 | scrollEnabled, | ^ 471 | automaticallyAdjustContentInsets: false, 472 | }; 473 | at Object.get PanResponder [as PanResponder] (node_modules/react-native/index.js:251:12) at BottomSheet.render (packages/components/src/mobile/bottom-sheet/index.native.js:470:39) at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8459:31) at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8409:24) at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9990:16) ``` * Fix ReferencEerror in Verse test Usage of `react-test-renderer` caused the following error. Leveraging `@testing-library/react-native` instead resolved it for an unknown reason. ``` ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From packages/block-editor/src/components/inserter/test/index.native.js. 468 | style: listStyle, 469 | safeAreaBottomInset, > 470 | scrollEnabled, | ^ 471 | automaticallyAdjustContentInsets: false, 472 | }; 473 | at Object.get PanResponder [as PanResponder] (node_modules/react-native/index.js:251:12) at BottomSheet.render (packages/components/src/mobile/bottom-sheet/index.native.js:470:39) at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8459:31) at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8409:24) at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9990:16) ``` * Fix ReferencEerror in Audio test Usage of `react-test-renderer` caused the following error. Leveraging `@testing-library/react-native` instead resolved it for an unknown reason. ``` ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From packages/block-editor/src/components/inserter/test/index.native.js. 468 | style: listStyle, 469 | safeAreaBottomInset, > 470 | scrollEnabled, | ^ 471 | automaticallyAdjustContentInsets: false, 472 | }; 473 | at Object.get PanResponder [as PanResponder] (node_modules/react-native/index.js:251:12) at BottomSheet.render (packages/components/src/mobile/bottom-sheet/index.native.js:470:39) at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8459:31) at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8409:24) at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9990:16) ``` * Fix ReferencEerror in File test Usage of `react-test-renderer` caused the following error. Leveraging `@testing-library/react-native` instead resolved it for an unknown reason. ``` ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From packages/block-editor/src/components/inserter/test/index.native.js. 468 | style: listStyle, 469 | safeAreaBottomInset, > 470 | scrollEnabled, | ^ 471 | automaticallyAdjustContentInsets: false, 472 | }; 473 | at Object.get PanResponder [as PanResponder] (node_modules/react-native/index.js:251:12) at BottomSheet.render (packages/components/src/mobile/bottom-sheet/index.native.js:470:39) at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8459:31) at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8409:24) at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9990:16) ``` * Fix ReferencEerror in Search test Usage of `react-test-renderer` caused the following error. Leveraging `@testing-library/react-native` instead resolved it for an unknown reason. ``` ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From packages/block-editor/src/components/inserter/test/index.native.js. 468 | style: listStyle, 469 | safeAreaBottomInset, > 470 | scrollEnabled, | ^ 471 | automaticallyAdjustContentInsets: false, 472 | }; 473 | at Object.get PanResponder [as PanResponder] (node_modules/react-native/index.js:251:12) at BottomSheet.render (packages/components/src/mobile/bottom-sheet/index.native.js:470:39) at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8459:31) at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8409:24) at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9990:16) ``` * Fix ReferencEerror in Missing test Usage of `react-test-renderer` caused the following error. Leveraging `@testing-library/react-native` instead resolved it for an unknown reason. ``` ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From packages/block-editor/src/components/inserter/test/index.native.js. 468 | style: listStyle, 469 | safeAreaBottomInset, > 470 | scrollEnabled, | ^ 471 | automaticallyAdjustContentInsets: false, 472 | }; 473 | at Object.get PanResponder [as PanResponder] (node_modules/react-native/index.js:251:12) at BottomSheet.render (packages/components/src/mobile/bottom-sheet/index.native.js:470:39) at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8459:31) at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8409:24) at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9990:16) ``` * Upgrade to @testing-library/[email protected] * Add assertions to block type tab tests Improve test clarity with explicit expect assertions. Co-authored-by: Carlos Garcia <[email protected]> * Remove unnecessary abstraction The switch away from Enzyme reduced this abstraction to a single line, so it provides less value now. * Consistently assert media block update progress spinner removal This increases consistency amongst the tests, as most already include this assertion. * Update MediaUpload test to select 'Choose from device' option This selection better aligns with the test description. * Remove duplicative matchMedia global definition The test environment now imports the globals setup file used by the app runtime. That file includes a `matchMedia` global definition as well. * Add assertions to LinkSettings tests Improve test clarity with explicit expect assertions. * Removed shallow renderer usage in tests Shallow rendering components is generally considered a non-optimal approach to testing React components by the React community. This replaces `shallow` with `render` to further test integration of the subject components. * Remove unused import The `React` import was utilized by the now removed `shallow` render implementation. * Remove unnecessary top-level beforeAll usage Jest runs each test file independently, so top-level code will not impact other test files. Since the `(before|after)All` usage in code changed is all top-level, and not within a `describe`, it is superfluous. Co-authored-by: Carlos Garcia <[email protected]>
1 parent 573c86e commit 44084d9

File tree

39 files changed

+838
-804
lines changed

39 files changed

+838
-804
lines changed

package-lock.json

+18-59
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
"@storybook/react": "6.4.9",
108108
"@testing-library/jest-dom": "5.16.1",
109109
"@testing-library/react": "11.2.2",
110-
"@testing-library/react-native": "7.1.0",
110+
"@testing-library/react-native": "9.0.0",
111111
"@types/classnames": "2.3.1",
112112
"@types/eslint": "7.28.0",
113113
"@types/estree": "0.0.50",

packages/block-editor/src/components/block-edit/test/edit.native.js

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/**
22
* External dependencies
33
*/
4-
import { shallow, mount } from 'enzyme';
4+
import { render } from 'test/helpers';
5+
import { Text } from 'react-native';
56

67
/**
78
* WordPress dependencies
@@ -26,39 +27,39 @@ describe( 'Edit', () => {
2627
} );
2728

2829
it( 'should return null if block type not defined', () => {
29-
const wrapper = shallow( <Edit name="core/test-block" /> );
30+
const screen = render( <Edit name="core/test-block" /> );
3031

31-
expect( wrapper.type() ).toBe( null );
32+
expect( screen.toJSON() ).toBe( null );
3233
} );
3334

3435
it( 'should use edit implementation of block', () => {
35-
const edit = () => <div />;
36+
const edit = () => <Text>core/test-block</Text>;
3637
registerBlockType( 'core/test-block', {
3738
category: 'text',
3839
title: 'block title',
3940
edit,
4041
} );
4142

42-
const wrapper = shallow( <Edit name="core/test-block" /> );
43+
const screen = render( <Edit name="core/test-block" /> );
4344

44-
expect( wrapper.exists( edit ) ).toBe( true );
45+
expect( screen.getByText( 'core/test-block' ) ).toBeDefined();
4546
} );
4647

4748
it( 'should assign context', () => {
48-
const edit = ( { context } ) => context.value;
49+
const edit = ( { context } ) => <Text>{ context.value }</Text>;
4950
registerBlockType( 'core/test-block', {
5051
category: 'text',
5152
title: 'block title',
5253
usesContext: [ 'value' ],
5354
edit,
5455
} );
5556

56-
const wrapper = mount(
57+
const screen = render(
5758
<BlockContextProvider value={ { value: 'Ok' } }>
5859
<Edit name="core/test-block" />
5960
</BlockContextProvider>
6061
);
6162

62-
expect( wrapper.html() ).toBe( 'Ok' );
63+
expect( screen.getByText( 'Ok' ) ).toBeDefined();
6364
} );
6465
} );

packages/block-editor/src/components/block-media-update-progress/index.native.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ export class BlockMediaUpdateProgress extends Component {
281281
<View style={ styles.mediaUploadProgress } pointerEvents="box-none">
282282
{ showSpinner && (
283283
<View style={ styles.progressBar }>
284-
<Spinner progress={ progress } />
284+
<Spinner progress={ progress } testID="spinner" />
285285
</View>
286286
) }
287287
{ renderContent( {

0 commit comments

Comments
 (0)