From d4ea75dc4258095593b6ac764289f42bddeb835c Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 23 Apr 2024 15:01:25 -0400 Subject: [PATCH] ReactDOMTestUtils deprecation warnings Adds a deprecation warning to ReactDOMTestUtils.renderIntoDocument, which is removed in version 19. Also backports the deprecation warning for ReactDOMTestUtils.act. --- .../__tests__/ReactDOMHydrationDiff-test.js | 5 +++ .../src/__tests__/ReactTestUtilsAct-test.js | 12 +++++-- .../src/test-utils/ReactTestUtils.js | 36 +++++++++++++++++-- scripts/jest/shouldIgnoreConsoleError.js | 4 ++- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js b/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js index e8e7dffee5d6d..2bb7d934d1ffc 100644 --- a/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js @@ -16,6 +16,8 @@ let usingPartialRenderer; const util = require('util'); const realConsoleError = console.error; +const shouldIgnoreConsoleError = require('../../../../scripts/jest/shouldIgnoreConsoleError'); + describe('ReactDOMServerHydration', () => { let container; @@ -57,6 +59,9 @@ describe('ReactDOMServerHydration', () => { // We only want console errors in this suite. return null; } + if (shouldIgnoreConsoleError(format, ...rest)) { + return null; + } rest[rest.length - 1] = normalizeCodeLocInfo(rest[rest.length - 1]); return util.format(format, ...rest); } diff --git a/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js b/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js index ca7aa3317c5cc..13f576059e842 100644 --- a/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js +++ b/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js @@ -493,8 +493,11 @@ function runActTests(label, render, unmount, rerender) { // it's annoying that we have to wait a tick before this warning comes in await sleep(0); if (__DEV__) { - expect(console.error.calls.count()).toEqual(1); + expect(console.error.calls.count()).toEqual(2); expect(console.error.calls.argsFor(0)[0]).toMatch( + '`ReactDOMTestUtils.act` is deprecated ', + ); + expect(console.error.calls.argsFor(1)[0]).toMatch( 'You called act(async () => ...) without await.', ); } @@ -516,13 +519,16 @@ function runActTests(label, render, unmount, rerender) { await sleep(150); if (__DEV__) { - expect(console.error).toHaveBeenCalledTimes(2); + expect(console.error).toHaveBeenCalledTimes(3); expect(console.error.calls.argsFor(0)[0]).toMatch( - 'You seem to have overlapping act() calls', + '`ReactDOMTestUtils.act` is deprecated ', ); expect(console.error.calls.argsFor(1)[0]).toMatch( 'You seem to have overlapping act() calls', ); + expect(console.error.calls.argsFor(2)[0]).toMatch( + 'You seem to have overlapping act() calls', + ); } }); diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js index 2c89baf398a90..c5542b94b7ff9 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtils.js +++ b/packages/react-dom/src/test-utils/ReactTestUtils.js @@ -34,7 +34,7 @@ const getFiberCurrentPropsFromNode = EventInternals[2]; const enqueueStateRestore = EventInternals[3]; const restoreStateIfNeeded = EventInternals[4]; -const act = React.unstable_act; +const reactAct = React.unstable_act; function Event(suffix) {} @@ -121,7 +121,23 @@ function validateClassInstance(inst, methodName) { * utilities will suffice for testing purposes. * @lends ReactTestUtils */ + +let didWarnAboutReactTestUtilsDeprecation = false; + function renderIntoDocument(element) { + if (__DEV__) { + if (!didWarnAboutReactTestUtilsDeprecation) { + didWarnAboutReactTestUtilsDeprecation = true; + console.error( + 'ReactDOMTestUtils is deprecated and will be removed in a future ' + + 'major release, because it exposes internal implementation details ' + + 'that are highly likely to change between releases. Upgrade to a ' + + 'modern testing library, such as @testing-library/react. See ' + + 'https://react.dev/warnings/react-dom-test-utils for more info.', + ); + } + } + const div = document.createElement('div'); // None of our tests actually require attaching the container to the // DOM, and doing so creates a mess that we rely on test isolation to @@ -711,6 +727,23 @@ function buildSimulators() { } buildSimulators(); +let didWarnAboutUsingAct = false; +export const act = __DEV__ + ? function actWithWarning(callback) { + if (__DEV__) { + if (!didWarnAboutUsingAct) { + didWarnAboutUsingAct = true; + console.error( + '`ReactDOMTestUtils.act` is deprecated in favor of `React.act`. ' + + 'Import `act` from `react` instead of `react-dom/test-utils`. ' + + 'See https://react.dev/warnings/react-dom-test-utils for more info.', + ); + } + } + return reactAct(callback); + } + : reactAct; + export { renderIntoDocument, isElement, @@ -729,5 +762,4 @@ export { mockComponent, nativeTouchData, Simulate, - act, }; diff --git a/scripts/jest/shouldIgnoreConsoleError.js b/scripts/jest/shouldIgnoreConsoleError.js index 04bec92c39636..cbe2cfb6180b6 100644 --- a/scripts/jest/shouldIgnoreConsoleError.js +++ b/scripts/jest/shouldIgnoreConsoleError.js @@ -29,7 +29,9 @@ module.exports = function shouldIgnoreConsoleError(format, args) { ) !== -1 || format.indexOf( 'uses the legacy childContextTypes API which is no longer supported and will be removed' - ) !== -1 + ) !== -1 || + format.indexOf('ReactDOMTestUtils is deprecated') !== -1 || + format.indexOf('`ReactDOMTestUtils.act` is deprecated') !== -1 ) { // This is a backported warning. In `main`, there's a different warning // (and it's fully tested). Not going to bother upgrading all the tests