From 9a1db2d21fac88a42094fa3fc266d1692551a5bd Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Mon, 5 Feb 2024 15:38:48 +0000 Subject: [PATCH] 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. --- .../src/__tests__/utils.js | 40 +++++++++++++++---- .../config.build-devtools-regression.js | 2 - .../setupTests.build-devtools-regression.js | 30 -------------- 3 files changed, 32 insertions(+), 40 deletions(-) delete mode 100644 scripts/jest/devtools/setupTests.build-devtools-regression.js diff --git a/packages/react-devtools-shared/src/__tests__/utils.js b/packages/react-devtools-shared/src/__tests__/utils.js index 21a6314eebb57..50798c3ba70b2 100644 --- a/packages/react-devtools-shared/src/__tests__/utils.js +++ b/packages/react-devtools-shared/src/__tests__/utils.js @@ -7,6 +7,8 @@ * @flow */ +import semver from 'semver'; + import typeof ReactTestRenderer from 'react-test-renderer'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; @@ -14,16 +16,38 @@ import type Store from 'react-devtools-shared/src/devtools/store'; import type {ProfilingDataFrontend} from 'react-devtools-shared/src/devtools/views/Profiler/types'; import type {ElementType} from 'react-devtools-shared/src/frontend/types'; +import {ReactVersion} from '../../../../ReactVersions'; + +const requestedReactVersion = process.env.REACT_VERSION || ReactVersion; +export function getActDOMImplementation(): () => void | Promise { + // This is for React < 18, where act was distributed in react-dom/test-utils. + if (semver.lt(requestedReactVersion, '18.0.0')) { + const ReactDOMTestUtils = require('react-dom/test-utils'); + return ReactDOMTestUtils.act; + } + + const React = require('react'); + // This is for React 18, where act was distributed in react as unstable. + if (React.unstable_act) { + return React.unstable_act; + } + + // This is for React > 18, where act is marked as stable. + if (React.act) { + return React.act; + } + + throw new Error("Couldn't find any available act implementation"); +} + export function act( callback: Function, recursivelyFlush: boolean = true, ): void { + // act from react-test-renderer has some side effects on React DevTools + // it injects the renderer for DevTools, see ReactTestRenderer.js const {act: actTestRenderer} = require('react-test-renderer'); - // Use `require('react-dom/test-utils').act` as a fallback for React 17, which can be used in integration tests for React DevTools. - const actDOM = - require('react').act || - require('react').unstable_act || - require('react-dom/test-utils').act; + const actDOM = getActDOMImplementation(); actDOM(() => { actTestRenderer(() => { @@ -47,10 +71,10 @@ export async function actAsync( cb: () => *, recursivelyFlush: boolean = true, ): Promise { + // act from react-test-renderer has some side effects on React DevTools + // it injects the renderer for DevTools, see ReactTestRenderer.js const {act: actTestRenderer} = require('react-test-renderer'); - // Use `require('react-dom/test-utils').act` as a fallback for React 17, which can be used in integration tests for React DevTools. - const actDOM = - require('react').unstable_act || require('react-dom/test-utils').act; + const actDOM = getActDOMImplementation(); await actDOM(async () => { await actTestRenderer(async () => { diff --git a/scripts/jest/devtools/config.build-devtools-regression.js b/scripts/jest/devtools/config.build-devtools-regression.js index 2b8b650173c1e..672cb98258fde 100644 --- a/scripts/jest/devtools/config.build-devtools-regression.js +++ b/scripts/jest/devtools/config.build-devtools-regression.js @@ -31,8 +31,6 @@ if (REACT_VERSION) { '^react-dom/client$' ] = `/build/${NODE_MODULES_DIR}/react-dom`; } - - setupFiles.push(require.resolve('./setupTests.build-devtools-regression')); } module.exports = { diff --git a/scripts/jest/devtools/setupTests.build-devtools-regression.js b/scripts/jest/devtools/setupTests.build-devtools-regression.js deleted file mode 100644 index d0126731512bd..0000000000000 --- a/scripts/jest/devtools/setupTests.build-devtools-regression.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -// Regression tests use a React DOM profiling, so we need -// to replace these tests with scheduler/tracing-profiling -jest.mock('scheduler/tracing', () => { - return jest.requireActual('scheduler/tracing-profiling'); -}); - -// act doesn't exist in older versions of React, but -// DevTools tests sometimes import and depend on act to run. -// If act doesn't exist for a particular version of React, we will -// mock it with a function. This should work in most tests -// that we want to call with older versions of React. -// TODO (luna) Refactor act in DevTools test utils to not depend -// on act in react-dom or react-test-renderer so we don't need to do this -jest.mock('react-test-renderer', () => { - const reactTestRenderer = jest.requireActual('react-test-renderer'); - if (!reactTestRenderer.act) { - reactTestRenderer.act = fn => fn(); - } - return reactTestRenderer; -}); - -jest.mock('react-dom/test-utils', () => { - const testUtils = jest.requireActual('react-dom/test-utils'); - if (!testUtils.act) { - testUtils.act = fn => fn(); - } - return testUtils; -});