@@ -2,8 +2,13 @@ import * as React from 'react';
22import { Suspense } from 'react' ;
33import { renderToReadableStream } from 'react-dom/server' ;
44import { hydrateRoot } from 'react-dom/client' ;
5+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
6+ // @ts -ignore - TypeScript error can be ignored because:
7+ // 1. This test file is only executed when Node version >= 18
8+ // 2. The package is guaranteed to be available at runtime in Node 18+ environments
59import { screen , act , waitFor } from '@testing-library/react' ;
610import '@testing-library/jest-dom' ;
11+ import { getNodeVersion } from './testUtils.js' ;
712
813/**
914 * Tests React's Suspense hydration behavior for async components
@@ -147,55 +152,59 @@ async function renderAndHydrate() {
147152 } ;
148153}
149154
150- beforeEach ( ( ) => {
151- jest . clearAllMocks ( ) ;
152- document . body . innerHTML = '' ;
153- } ) ;
154-
155- it ( 'hydrates the container when its content is written to the document' , async ( ) => {
156- const { onContainerHydrated, onAsyncComponentHydrated, writeFirstChunk, hydrate } =
157- await renderAndHydrate ( ) ;
158-
159- await act ( async ( ) => {
160- hydrate ( ) ;
161- await writeFirstChunk ( ) ;
162- } ) ;
163- await waitFor ( ( ) => {
164- expect ( screen . queryByText ( 'Loading...' ) ) . toBeInTheDocument ( ) ;
165- } ) ;
166- expect ( onContainerHydrated ) . toHaveBeenCalled ( ) ;
167-
168- // The async component is not hydrated until the second chunk is written to the document
169- await new Promise ( ( resolve ) => {
170- setTimeout ( resolve , 1000 ) ;
155+ // React Server Components tests are compatible with React 19
156+ // That only run with node version 18 and above
157+ ( getNodeVersion ( ) >= 18 ? describe : describe . skip ) ( 'RSCClientRoot' , ( ) => {
158+ beforeEach ( ( ) => {
159+ jest . clearAllMocks ( ) ;
160+ document . body . innerHTML = '' ;
171161 } ) ;
172- expect ( onAsyncComponentHydrated ) . not . toHaveBeenCalled ( ) ;
173- expect ( screen . queryByText ( 'Loading...' ) ) . toBeInTheDocument ( ) ;
174- expect ( screen . queryByText ( 'Hello World' ) ) . not . toBeInTheDocument ( ) ;
175- } ) ;
176-
177- it ( 'hydrates the container when its content is written to the document' , async ( ) => {
178- const { writeFirstChunk, writeSecondChunk, onAsyncComponentHydrated, onContainerHydrated, hydrate } =
179- await renderAndHydrate ( ) ;
180162
181- await act ( async ( ) => {
182- hydrate ( ) ;
183- await writeFirstChunk ( ) ;
184- } ) ;
185- await waitFor ( ( ) => {
163+ it ( 'hydrates the container when its content is written to the document' , async ( ) => {
164+ const { onContainerHydrated, onAsyncComponentHydrated, writeFirstChunk, hydrate } =
165+ await renderAndHydrate ( ) ;
166+
167+ await act ( async ( ) => {
168+ hydrate ( ) ;
169+ await writeFirstChunk ( ) ;
170+ } ) ;
171+ await waitFor ( ( ) => {
172+ expect ( screen . queryByText ( 'Loading...' ) ) . toBeInTheDocument ( ) ;
173+ } ) ;
174+ expect ( onContainerHydrated ) . toHaveBeenCalled ( ) ;
175+
176+ // The async component is not hydrated until the second chunk is written to the document
177+ await new Promise ( ( resolve ) => {
178+ setTimeout ( resolve , 1000 ) ;
179+ } ) ;
180+ expect ( onAsyncComponentHydrated ) . not . toHaveBeenCalled ( ) ;
186181 expect ( screen . queryByText ( 'Loading...' ) ) . toBeInTheDocument ( ) ;
182+ expect ( screen . queryByText ( 'Hello World' ) ) . not . toBeInTheDocument ( ) ;
187183 } ) ;
188184
189- await act ( async ( ) => {
190- const secondChunk = await writeSecondChunk ( ) ;
191- expect ( secondChunk ) . toContain ( 'script' ) ;
192- console . log ( secondChunk ) ;
193- } ) ;
194- await waitFor ( ( ) => {
195- expect ( screen . queryByText ( 'Loading...' ) ) . not . toBeInTheDocument ( ) ;
196- expect ( screen . queryByText ( 'Hello World' ) ) . toBeInTheDocument ( ) ;
185+ it ( 'hydrates the container when its content is written to the document' , async ( ) => {
186+ const { writeFirstChunk, writeSecondChunk, onAsyncComponentHydrated, onContainerHydrated, hydrate } =
187+ await renderAndHydrate ( ) ;
188+
189+ await act ( async ( ) => {
190+ hydrate ( ) ;
191+ await writeFirstChunk ( ) ;
192+ } ) ;
193+ await waitFor ( ( ) => {
194+ expect ( screen . queryByText ( 'Loading...' ) ) . toBeInTheDocument ( ) ;
195+ } ) ;
196+
197+ await act ( async ( ) => {
198+ const secondChunk = await writeSecondChunk ( ) ;
199+ expect ( secondChunk ) . toContain ( 'script' ) ;
200+ console . log ( secondChunk ) ;
201+ } ) ;
202+ await waitFor ( ( ) => {
203+ expect ( screen . queryByText ( 'Loading...' ) ) . not . toBeInTheDocument ( ) ;
204+ expect ( screen . queryByText ( 'Hello World' ) ) . toBeInTheDocument ( ) ;
205+ } ) ;
206+
207+ expect ( onContainerHydrated ) . toHaveBeenCalled ( ) ;
208+ expect ( onAsyncComponentHydrated ) . toHaveBeenCalled ( ) ;
197209 } ) ;
198-
199- expect ( onContainerHydrated ) . toHaveBeenCalled ( ) ;
200- expect ( onAsyncComponentHydrated ) . toHaveBeenCalled ( ) ;
201210} ) ;
0 commit comments