88window . __webpack_require__ = jest . fn ( ) ;
99window . __webpack_chunk_load__ = jest . fn ( ) ;
1010
11- import * as React from 'react' ;
1211import { enableFetchMocks } from 'jest-fetch-mock' ;
13- import { render , screen , act } from '@testing-library/react' ;
12+ import { screen , act } from '@testing-library/react' ;
1413import '@testing-library/jest-dom' ;
1514import path from 'path' ;
1615import fs from 'fs' ;
1716import { createNodeReadableStream , getNodeVersion } from './testUtils' ;
1817
19- import RSCClientRoot , { resetRenderCache } from '../src/RSCClientRoot' ;
18+ import RSCClientRoot from '../src/RSCClientRoot' ;
2019
2120enableFetchMocks ( ) ;
2221
2322// React Server Components tests are not compatible with Experimental React 18 and React 19
2423// That only run with node version 18 and above
2524( getNodeVersion ( ) >= 18 ? describe : describe . skip ) ( 'RSCClientRoot' , ( ) => {
25+ let container ;
26+ const mockDomNodeId = 'test-container' ;
27+
2628 beforeEach ( ( ) => {
29+ // Setup DOM element
30+ container = document . createElement ( 'div' ) ;
31+ container . id = mockDomNodeId ;
32+ document . body . appendChild ( container ) ;
2733 jest . clearAllMocks ( ) ;
2834
2935 jest . resetModules ( ) ;
30- resetRenderCache ( ) ;
36+ } ) ;
37+
38+ afterEach ( ( ) => {
39+ document . body . removeChild ( container ) ;
3140 } ) ;
3241
3342 it ( 'throws error when React.use is not defined' , ( ) => {
@@ -60,27 +69,32 @@ enableFetchMocks();
6069 rscPayloadGenerationUrlPath,
6170 } ;
6271
63- const { rerender } = await act ( async ( ) => render ( < RSCClientRoot { ...props } /> ) ) ;
72+ // Execute the render
73+ const render = ( ) =>
74+ act ( async ( ) => {
75+ await RSCClientRoot ( props , undefined , mockDomNodeId ) ;
76+ } ) ;
6477
6578 return {
66- rerender : ( ) => rerender ( < RSCClientRoot { ... props } /> ) ,
79+ render ,
6780 pushFirstChunk : ( ) => push ( `${ JSON . stringify ( chunk1 ) } \n` ) ,
6881 pushSecondChunk : ( ) => push ( `${ JSON . stringify ( chunk2 ) } \n` ) ,
6982 pushCustomChunk : ( chunk ) => push ( `${ chunk } \n` ) ,
7083 endStream : ( ) => push ( null ) ,
7184 } ;
7285 } ;
7386
74- it ( 'fetches and caches component data ' , async ( ) => {
75- const { rerender , pushFirstChunk, pushSecondChunk, endStream } = await mockRSCRequest ( ) ;
87+ it ( 'renders component progressively ' , async ( ) => {
88+ const { render , pushFirstChunk, pushSecondChunk, endStream } = await mockRSCRequest ( ) ;
7689
77- expect ( window . fetch ) . toHaveBeenCalledWith ( '/rsc-render/TestComponent' ) ;
78- expect ( window . fetch ) . toHaveBeenCalledTimes ( 1 ) ;
7990 expect ( screen . queryByText ( 'StaticServerComponent' ) ) . not . toBeInTheDocument ( ) ;
8091
8192 await act ( async ( ) => {
8293 pushFirstChunk ( ) ;
94+ render ( ) ;
8395 } ) ;
96+ expect ( window . fetch ) . toHaveBeenCalledWith ( '/rsc-render/TestComponent?props=undefined' ) ;
97+ expect ( window . fetch ) . toHaveBeenCalledTimes ( 1 ) ;
8498 expect ( screen . getByText ( 'StaticServerComponent' ) ) . toBeInTheDocument ( ) ;
8599 expect ( screen . getByText ( 'Loading AsyncComponent...' ) ) . toBeInTheDocument ( ) ;
86100 expect ( screen . queryByText ( 'AsyncComponent' ) ) . not . toBeInTheDocument ( ) ;
@@ -91,24 +105,21 @@ enableFetchMocks();
91105 } ) ;
92106 expect ( screen . getByText ( 'AsyncComponent' ) ) . toBeInTheDocument ( ) ;
93107 expect ( screen . queryByText ( 'Loading AsyncComponent...' ) ) . not . toBeInTheDocument ( ) ;
94-
95- // Second render - should use cache
96- rerender ( ) ;
97-
98- expect ( screen . getByText ( 'AsyncComponent' ) ) . toBeInTheDocument ( ) ;
99- expect ( window . fetch ) . toHaveBeenCalledTimes ( 1 ) ;
100108 } ) ;
101109
102110 it ( 'replays console logs' , async ( ) => {
103111 const consoleSpy = jest . spyOn ( console , 'log' ) ;
104- const { rerender , pushFirstChunk, pushSecondChunk, endStream } = await mockRSCRequest ( ) ;
112+ const { render , pushFirstChunk, pushSecondChunk, endStream } = await mockRSCRequest ( ) ;
105113
106114 await act ( async ( ) => {
115+ render ( ) ;
107116 pushFirstChunk ( ) ;
108117 } ) ;
109118 expect ( consoleSpy ) . toHaveBeenCalledWith (
110119 expect . stringContaining ( 'Console log at first chunk' ) ,
111- expect . anything ( ) , expect . anything ( ) , expect . anything ( )
120+ expect . anything ( ) ,
121+ expect . anything ( ) ,
122+ expect . anything ( ) ,
112123 ) ;
113124 expect ( consoleSpy ) . toHaveBeenCalledTimes ( 1 ) ;
114125
@@ -117,28 +128,27 @@ enableFetchMocks();
117128 } ) ;
118129 expect ( consoleSpy ) . toHaveBeenCalledWith (
119130 expect . stringContaining ( 'Console log at second chunk' ) ,
120- expect . anything ( ) , expect . anything ( ) , expect . anything ( )
131+ expect . anything ( ) ,
132+ expect . anything ( ) ,
133+ expect . anything ( ) ,
121134 ) ;
122135 await act ( async ( ) => {
123136 endStream ( ) ;
124137 } ) ;
125138 expect ( consoleSpy ) . toHaveBeenCalledTimes ( 2 ) ;
126-
127- // On rerender, console logs should not be replayed again
128- rerender ( ) ;
129- expect ( consoleSpy ) . toHaveBeenCalledTimes ( 2 ) ;
130139 } ) ;
131140
132141 it ( 'strips leading and trailing slashes from rscPayloadGenerationUrlPath' , async ( ) => {
133- const { pushFirstChunk, pushSecondChunk, endStream } = await mockRSCRequest ( '/rsc-render/' ) ;
142+ const { render , pushFirstChunk, pushSecondChunk, endStream } = await mockRSCRequest ( '/rsc-render/' ) ;
134143
135144 await act ( async ( ) => {
145+ render ( ) ;
136146 pushFirstChunk ( ) ;
137147 pushSecondChunk ( ) ;
138148 endStream ( ) ;
139149 } ) ;
140150
141- expect ( window . fetch ) . toHaveBeenCalledWith ( '/rsc-render/TestComponent' ) ;
151+ expect ( window . fetch ) . toHaveBeenCalledWith ( '/rsc-render/TestComponent?props=undefined ' ) ;
142152 expect ( window . fetch ) . toHaveBeenCalledTimes ( 1 ) ;
143153
144154 expect ( screen . getByText ( 'StaticServerComponent' ) ) . toBeInTheDocument ( ) ;
0 commit comments