@@ -327,10 +327,21 @@ describe("API (plugin)", () => {
327327 }
328328 } ) ;
329329
330- it ( "should work with output.clean: true" , async ( t ) => {
330+ it ( "should serve rebuilt assets from memory with output.clean: true" , async ( ) => {
331+ // A dedicated, editable entry so a rebuild produces observably different
332+ // output. `output.clean` wipes the output directory before each build, so
333+ // this exercises that the fresh assets are written back to the in-memory
334+ // file system (and the stale ones are gone) rather than the real disk.
335+ const entryPath = path . join (
336+ os . tmpdir ( ) ,
337+ `wds-clean-entry-${ Date . now ( ) } .js` ,
338+ ) ;
339+ fs . writeFileSync ( entryPath , 'globalThis.MARKER = "before-rebuild";\n' ) ;
340+
331341 const server = new Server ( { port } ) ;
332342 const compiler = webpack ( {
333343 ...config ,
344+ entry : entryPath ,
334345 output : {
335346 ...config . output ,
336347 clean : true ,
@@ -340,32 +351,48 @@ describe("API (plugin)", () => {
340351
341352 await compile ( compiler , port ) ;
342353
343- const { page, browser } = await runBrowser ( ) ;
344-
345354 try {
346- const pageErrors = [ ] ;
347- const consoleMessages = [ ] ;
348-
349- page
350- . on ( "console" , ( message ) => {
351- consoleMessages . push ( message ) ;
352- } )
353- . on ( "pageerror" , ( error ) => {
354- pageErrors . push ( error ) ;
355- } ) ;
356-
357- const response = await page . goto ( `http://127.0.0.1:${ port } /` , {
358- waitUntil : "networkidle0" ,
355+ const fetchBundle = async ( ) => {
356+ const response = await fetch ( `http://127.0.0.1:${ port } /main.js` ) ;
357+ return response . text ( ) ;
358+ } ;
359+
360+ // The first build is served from the in-memory file system.
361+ expect ( await fetchBundle ( ) ) . toContain ( "before-rebuild" ) ;
362+
363+ // Edit the source and let the watcher rebuild it under `output.clean`.
364+ fs . writeFileSync ( entryPath , 'globalThis.MARKER = "after-rebuild";\n' ) ;
365+ await new Promise ( ( resolve , reject ) => {
366+ const start = Date . now ( ) ;
367+ const interval = setInterval ( async ( ) => {
368+ let bundle ;
369+ try {
370+ bundle = await fetchBundle ( ) ;
371+ } catch {
372+ return ;
373+ }
374+ if ( bundle . includes ( "after-rebuild" ) ) {
375+ clearInterval ( interval ) ;
376+ resolve ( ) ;
377+ } else if ( Date . now ( ) - start > 30000 ) {
378+ clearInterval ( interval ) ;
379+ reject ( new Error ( "rebuild was not served in time" ) ) ;
380+ }
381+ } , 200 ) ;
359382 } ) ;
360383
361- expect ( response . status ( ) ) . toBe ( 200 ) ;
362- t . assert . snapshot ( consoleMessages . map ( ( message ) => message . text ( ) ) ) ;
363- t . assert . snapshot ( pageErrors ) ;
384+ // The rebuilt bundle is served fresh and the stale build is gone.
385+ const rebuilt = await fetchBundle ( ) ;
386+ expect ( rebuilt ) . toContain ( "after-rebuild" ) ;
387+ expect ( rebuilt ) . not . toContain ( "before-rebuild" ) ;
388+
389+ // ...and it still lives in the in-memory file system, not the disk.
390+ expect ( compiler . outputFileSystem ) . not . toBe ( fs ) ;
364391 } finally {
365- await browser . close ( ) ;
366392 await new Promise ( ( resolve ) => {
367393 compiler . close ( resolve ) ;
368394 } ) ;
395+ fs . unlinkSync ( entryPath ) ;
369396 }
370397 } ) ;
371398 } ) ;
0 commit comments