@@ -9,22 +9,27 @@ import handler from 'serve-handler'
99import http from 'http'
1010import rmfr from 'rmfr'
1111import * as cheerio from 'cheerio'
12+ import { ChildProcess } from 'child_process'
1213
1314jest . setTimeout ( 30000 )
1415
15- describe ( 'hydration' , ( ) => {
16+ describe ( 'hydration - production ' , ( ) => {
1617 beforeAll ( ( ) => {
1718 buildFixture ( 'basic' )
1819 } )
1920
21+ afterAll ( async ( ) => {
22+ await cleanupNextDirectory ( 'basic' )
23+ } )
24+
2025 test ( 'server rendered output' , ( ) => {
2126 const result = readOutputFile ( 'basic' , 'index' )
2227 const $ = cheerio . load ( result )
2328
2429 const htmlOutput = $ ( '#__next' ) . html ( )
2530
2631 // server renders correctly
27- expect ( htmlOutput ) . toContain ( `<h1>foo</h1><h1 >Headline</h1 >
32+ expect ( htmlOutput ) . toContain ( `<h1>foo</h1><h2 >Headline</h2 >
2833<!-- --><p>hello <!-- -->jeff<!-- --></p><button>Count: <!-- -->0<!-- --></button>
2934<!-- --><p class=\"context\">Context value: \"<!-- -->foo<!-- -->\"<!-- --></p>
3035<!-- --><p>Some <!-- --><strong class=\"custom-strong\">markdown</strong> content<!-- --></p>
@@ -73,9 +78,36 @@ describe('hydration', () => {
7378 } )
7479} )
7580
76- afterAll ( async ( ) => {
77- await rmfr ( path . join ( __dirname , 'fixtures/basic/out' ) )
78- await rmfr ( path . join ( __dirname , 'fixtures/basic/.next' ) )
81+ describe ( 'hydration - dev server' , ( ) => {
82+ let childProcess
83+ let browser : Browser
84+
85+ beforeAll ( async ( ) => {
86+ childProcess = await startDevServer ( 'basic' )
87+ browser = await puppeteer . launch ( )
88+ } )
89+
90+ afterAll ( async ( ) => {
91+ // close the browser and dev server
92+ await stopDevServer ( childProcess )
93+ await browser . close ( )
94+ await cleanupNextDirectory ( 'basic' )
95+ } )
96+
97+ test ( 'loads in development' , async ( ) => {
98+ const page = await browser . newPage ( )
99+ page . on ( 'console' , ( msg ) => console . log ( msg . text ( ) ) )
100+
101+ await page . goto ( 'http://localhost:12333' )
102+
103+ // @ts -expect-error
104+ await page . waitForFunction ( ( ) => Boolean ( window . __NEXT_HYDRATED ) )
105+
106+ // @ts -expect-error -- el is typed as Element, but reasonable to assume it is an HTMLElement at this point
107+ const headingText = await page . $eval ( 'h1' , ( el ) => el . innerText )
108+
109+ expect ( headingText ) . toEqual ( 'foo' )
110+ } )
79111} )
80112
81113//
@@ -112,3 +144,53 @@ function serveStatic(fixture: string): Promise<Server> {
112144 server . listen ( 1235 , ( ) => resolve ( server ) )
113145 } )
114146}
147+
148+ async function cleanupNextDirectory ( fixture : string ) {
149+ await rmfr ( path . join ( __dirname , `fixtures/${ fixture } /out` ) )
150+ await rmfr ( path . join ( __dirname , `fixtures/${ fixture } /.next` ) )
151+ }
152+
153+ async function startDevServer ( fixture : string ) {
154+ const dir = path . join ( __dirname , 'fixtures' , fixture )
155+
156+ const childProcess = spawn ( 'next' , [ 'dev' , '-p' , '12333' ] , {
157+ stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
158+ cwd : dir ,
159+ env : { ...process . env , NODE_ENV : 'development' , __NEXT_TEST_MODE : 'true' } ,
160+ } )
161+
162+ childProcess . stderr ?. on ( 'data' , ( chunk ) => {
163+ process . stdout . write ( chunk )
164+ } )
165+
166+ async function waitForStarted ( ) {
167+ return new Promise < undefined > ( ( resolve ) => {
168+ childProcess . stdout ?. on ( 'data' , ( chunk ) => {
169+ const msg = chunk . toString ( )
170+ process . stdout . write ( chunk )
171+
172+ if ( msg . includes ( 'started server on' ) && msg . includes ( 'url:' ) ) {
173+ resolve ( undefined )
174+ }
175+ } )
176+ } )
177+ }
178+
179+ await waitForStarted ( )
180+
181+ return childProcess
182+ }
183+
184+ async function stopDevServer ( childProcess : ChildProcess ) {
185+ console . log ( 'stopping development server...' )
186+ const promise = new Promise ( ( resolve ) => {
187+ childProcess . on ( 'close' , ( ) => {
188+ console . log ( 'development server stopped' )
189+ resolve ( undefined )
190+ } )
191+ } )
192+
193+ childProcess . kill ( 'SIGINT' )
194+
195+ await promise
196+ }
0 commit comments