chore: add single versioned implementation of act for DevTools tests (#28186)
- Moving `act` implementation to a single getter-function, which is based on React version we are testing RDT against. - Removing unused mocks for `act`, which were designed for legacy versions of React, validated with running tests against React 16 build.
Ruslan Lesiutin committed
Feb 5, 2024 at 15:38 UTC
9a1db2d21fac88a42094fa3fc266d1692551a5bd
3 files changed
+32
-40
packages/react-devtools-shared/src/__tests__/utils.js
+32
-8
@@ -7,6 +7,8 @@
7
* @flow
8
*/
9
10
+import semver from 'semver';
11
+
12
import typeof ReactTestRenderer from 'react-test-renderer';
13
14
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
@@ -14,16 +16,38 @@ import type Store from 'react-devtools-shared/src/devtools/store';
16
import type {ProfilingDataFrontend} from 'react-devtools-shared/src/devtools/views/Profiler/types';
17
import type {ElementType} from 'react-devtools-shared/src/frontend/types';
18
19
+import {ReactVersion} from '../../../../ReactVersions';
20
+
21
+const requestedReactVersion = process.env.REACT_VERSION || ReactVersion;
22
+export function getActDOMImplementation(): () => void | Promise<void> {
23
+ // This is for React < 18, where act was distributed in react-dom/test-utils.
24
+ if (semver.lt(requestedReactVersion, '18.0.0')) {
25
+ const ReactDOMTestUtils = require('react-dom/test-utils');
26
+ return ReactDOMTestUtils.act;
27
+ }
28
+
29
+ const React = require('react');
30
+ // This is for React 18, where act was distributed in react as unstable.
31
+ if (React.unstable_act) {
32
+ return React.unstable_act;
33
+ }
34
+
35
+ // This is for React > 18, where act is marked as stable.
36
+ if (React.act) {
37
+ return React.act;
38
+ }
39
+
40
+ throw new Error("Couldn't find any available act implementation");
41
+}
42
+
43
export function act(
44
callback: Function,
45
recursivelyFlush: boolean = true,
46
): void {
47
+ // act from react-test-renderer has some side effects on React DevTools
48
+ // it injects the renderer for DevTools, see ReactTestRenderer.js
49
const {act: actTestRenderer} = require('react-test-renderer');
22
- // Use `require('react-dom/test-utils').act` as a fallback for React 17, which can be used in integration tests for React DevTools.
23
- const actDOM =
24
- require('react').act ||
25
- require('react').unstable_act ||
26
- require('react-dom/test-utils').act;
50
+ const actDOM = getActDOMImplementation();
51
52
actDOM(() => {
53
actTestRenderer(() => {
@@ -47,10 +71,10 @@ export async function actAsync(
71
cb: () => *,
72
recursivelyFlush: boolean = true,
73
): Promise<void> {
74
+ // act from react-test-renderer has some side effects on React DevTools
75
+ // it injects the renderer for DevTools, see ReactTestRenderer.js
76
const {act: actTestRenderer} = require('react-test-renderer');
51
- // Use `require('react-dom/test-utils').act` as a fallback for React 17, which can be used in integration tests for React DevTools.
52
- const actDOM =
53
- require('react').unstable_act || require('react-dom/test-utils').act;
77
+ const actDOM = getActDOMImplementation();
78
79
await actDOM(async () => {
80
await actTestRenderer(async () => {
scripts/jest/devtools/config.build-devtools-regression.js
-2
@@ -31,8 +31,6 @@ if (REACT_VERSION) {
31
'^react-dom/client$'
32
] = `<rootDir>/build/${NODE_MODULES_DIR}/react-dom`;
33
}
34
-
35
- setupFiles.push(require.resolve('./setupTests.build-devtools-regression'));
34
}
35
36
module.exports = {
scripts/jest/devtools/setupTests.build-devtools-regression.js
deleted
-30
@@ -1,30 +0,0 @@
1
-'use strict';
2
-
3
-// Regression tests use a React DOM profiling, so we need
4
-// to replace these tests with scheduler/tracing-profiling
5
-jest.mock('scheduler/tracing', () => {
6
- return jest.requireActual('scheduler/tracing-profiling');
7
-});
8
-
9
-// act doesn't exist in older versions of React, but
10
-// DevTools tests sometimes import and depend on act to run.
11
-// If act doesn't exist for a particular version of React, we will
12
-// mock it with a function. This should work in most tests
13
-// that we want to call with older versions of React.
14
-// TODO (luna) Refactor act in DevTools test utils to not depend
15
-// on act in react-dom or react-test-renderer so we don't need to do this
16
-jest.mock('react-test-renderer', () => {
17
- const reactTestRenderer = jest.requireActual('react-test-renderer');
18
- if (!reactTestRenderer.act) {
19
- reactTestRenderer.act = fn => fn();
20
- }
21
- return reactTestRenderer;
22
-});
23
-
24
-jest.mock('react-dom/test-utils', () => {
25
- const testUtils = jest.requireActual('react-dom/test-utils');
26
- if (!testUtils.act) {
27
- testUtils.act = fn => fn();
28
- }
29
- return testUtils;
30
-});