From e204d76e0266cd26fc7b55f1f632afda3f815da8 Mon Sep 17 00:00:00 2001 From: Ricky Hanlon Date: Sat, 27 Jan 2024 17:48:31 -0500 Subject: [PATCH 1/2] Add ReactDOMClient to ServerIntegrationTestUtils --- .../ReactDOMServerIntegrationCheckbox-test.js | 6 ++--- ...MServerIntegrationClassContextType-test.js | 6 ++--- .../ReactDOMServerIntegrationFragment-test.js | 6 ++--- .../ReactDOMServerIntegrationInput-test.js | 6 ++--- .../ReactDOMServerIntegrationModes-test.js | 6 ++--- .../ReactDOMServerIntegrationRefs-test.js | 6 ++--- ...ctDOMServerIntegrationSpecialTypes-test.js | 6 ++--- .../ReactDOMServerIntegrationTextarea-test.js | 6 ++--- ...OMServerIntegrationUserInteraction-test.js | 6 ++--- .../ReactDOMserverIntegrationProgress-test.js | 6 ++--- .../ReactDOMServerIntegrationTestUtils.js | 26 ++++++++++++++++--- scripts/jest/shouldIgnoreConsoleError.js | 15 ++++++++++- 12 files changed, 66 insertions(+), 35 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationCheckbox-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationCheckbox-test.js index 606ec88b89893..178ed7982a44f 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationCheckbox-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationCheckbox-test.js @@ -15,7 +15,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegratio const {disableInputAttributeSyncing} = require('shared/ReactFeatureFlags'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -23,13 +23,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationClassContextType-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationClassContextType-test.js index dda475b7ced3e..2df2d66b9b9fa 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationClassContextType-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationClassContextType-test.js @@ -13,7 +13,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -21,13 +21,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationFragment-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationFragment-test.js index 680f283b6dbf2..8e8fc2aa8fe27 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationFragment-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationFragment-test.js @@ -13,7 +13,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -21,13 +21,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationInput-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationInput-test.js index afbbf28a41ecb..54780dae52cdb 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationInput-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationInput-test.js @@ -15,7 +15,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegratio const {disableInputAttributeSyncing} = require('shared/ReactFeatureFlags'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -23,13 +23,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationModes-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationModes-test.js index e551a72b9ace4..99cf33b821f17 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationModes-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationModes-test.js @@ -13,7 +13,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -21,13 +21,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationRefs-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationRefs-test.js index 76da3e92c82ad..e5564d3d9348c 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationRefs-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationRefs-test.js @@ -12,7 +12,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -20,13 +20,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationSpecialTypes-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationSpecialTypes-test.js index f3a8b869ad818..8ea1c9d53baee 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationSpecialTypes-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationSpecialTypes-test.js @@ -13,7 +13,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; let forwardRef; @@ -26,7 +26,7 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); forwardRef = React.forwardRef; @@ -44,7 +44,7 @@ function initModules() { // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationTextarea-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationTextarea-test.js index 697ec7f340d88..dd19385e62c56 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationTextarea-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationTextarea-test.js @@ -13,7 +13,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -21,13 +21,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUserInteraction-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUserInteraction-test.js index b335b03b01d38..bc5980f23dda2 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUserInteraction-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationUserInteraction-test.js @@ -12,7 +12,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -20,13 +20,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/ReactDOMserverIntegrationProgress-test.js b/packages/react-dom/src/__tests__/ReactDOMserverIntegrationProgress-test.js index b949e0ab522f9..cf51eff4aced3 100644 --- a/packages/react-dom/src/__tests__/ReactDOMserverIntegrationProgress-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMserverIntegrationProgress-test.js @@ -13,7 +13,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -21,13 +21,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; diff --git a/packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js b/packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js index 8392b57af03cf..e9c4479b028fb 100644 --- a/packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js +++ b/packages/react-dom/src/__tests__/utils/ReactDOMServerIntegrationTestUtils.js @@ -14,11 +14,12 @@ const shouldIgnoreConsoleError = require('../../../../../scripts/jest/shouldIgno module.exports = function (initModules) { let ReactDOM; + let ReactDOMClient; let ReactDOMServer; let act; function resetModules() { - ({ReactDOM, ReactDOMServer} = initModules()); + ({ReactDOM, ReactDOMClient, ReactDOMServer} = initModules()); act = require('internal-test-utils').act; } @@ -51,11 +52,24 @@ module.exports = function (initModules) { async function asyncReactDOMRender(reactElement, domElement, forceHydrate) { if (forceHydrate) { await act(() => { - ReactDOM.hydrate(reactElement, domElement); + if (ReactDOMClient) { + ReactDOMClient.hydrateRoot(domElement, reactElement, { + onRecoverableError: () => { + // TODO: assert on recoverable error count. + }, + }); + } else { + ReactDOM.hydrate(reactElement, domElement); + } }); } else { await act(() => { - ReactDOM.render(reactElement, domElement); + if (ReactDOMClient) { + const root = ReactDOMClient.createRoot(domElement); + root.render(reactElement); + } else { + ReactDOM.render(reactElement, domElement); + } }); } } @@ -80,7 +94,11 @@ module.exports = function (initModules) { for (let i = 0; i < console.error.mock.calls.length; i++) { const args = console.error.mock.calls[i]; const [format, ...rest] = args; - if (!shouldIgnoreConsoleError(format, rest)) { + if ( + !shouldIgnoreConsoleError(format, rest, { + TODO_ignoreHydrationErrors: true, + }) + ) { filteredWarnings.push(args); } } diff --git a/scripts/jest/shouldIgnoreConsoleError.js b/scripts/jest/shouldIgnoreConsoleError.js index 42aae220debed..79ec7fc2ad7d6 100644 --- a/scripts/jest/shouldIgnoreConsoleError.js +++ b/scripts/jest/shouldIgnoreConsoleError.js @@ -1,6 +1,10 @@ 'use strict'; -module.exports = function shouldIgnoreConsoleError(format, args) { +module.exports = function shouldIgnoreConsoleError( + format, + args, + {TODO_ignoreHydrationErrors} = {TODO_ignoreHydrationErrors: false} +) { if (__DEV__) { if (typeof format === 'string') { if (format.indexOf('Error: Uncaught [') === 0) { @@ -23,6 +27,15 @@ module.exports = function shouldIgnoreConsoleError(format, args) { // We haven't finished migrating our tests to use createRoot. return true; } + if ( + TODO_ignoreHydrationErrors && + format.indexOf( + 'An error occurred during hydration. The server HTML was replaced with client content in' + ) !== -1 + ) { + // This also gets logged by onRecoverableError, so we can ignore it. + return true; + } } else if ( format != null && typeof format.message === 'string' && From 1773579c1a081997d8bb53b7099d1e68496092f6 Mon Sep 17 00:00:00 2001 From: Ricky Hanlon Date: Sat, 27 Jan 2024 18:53:07 -0500 Subject: [PATCH 2/2] Add ReactDOMClient to ServerIntegrationBasic --- .../__tests__/ReactDOMServerIntegrationBasic-test.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationBasic-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationBasic-test.js index a0793a6215b66..2821dd088bb48 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationBasic-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationBasic-test.js @@ -15,7 +15,7 @@ const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegratio const TEXT_NODE_TYPE = 3; let React; -let ReactDOM; +let ReactDOMClient; let ReactDOMServer; let ReactTestUtils; @@ -23,13 +23,13 @@ function initModules() { // Reset warning cache. jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactDOMServer = require('react-dom/server'); ReactTestUtils = require('react-dom/test-utils'); // Make them available to the helpers. return { - ReactDOM, + ReactDOMClient, ReactDOMServer, ReactTestUtils, }; @@ -149,8 +149,10 @@ describe('ReactDOMServerIntegration', () => { expect(await render([])).toBe(null); expect(await render(false)).toBe(null); expect(await render(true)).toBe(null); - expect(await render(undefined)).toBe(null); expect(await render([[[false]], undefined])).toBe(null); + + // hydrateRoot errors for undefined children. + expect(await render(undefined, 1)).toBe(null); }); }); });