@@ -351,131 +351,176 @@ describe('ppr-full', () => {
351351 expect ( $ ( '[data-agent]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
352352 } )
353353
354- it ( 'should render the dynamic shell on the second visit' , async ( ) => {
355- const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
356- const pathname = `/fallback/dynamic/params/on-second-visit-${ random } `
354+ if ( isNextDeploy ) {
355+ it ( 'should render the fallback shell every time' , async ( ) => {
356+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
357+ const pathname = `/fallback/dynamic/params/on-second-visit-${ random } `
357358
358- let $ = await next . render$ ( pathname )
359- expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
360- expect ( $ ( '[data-agent]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
359+ let $ = await next . render$ ( pathname )
360+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
361+ expect ( $ ( '[data-agent]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
361362
362- await retry ( async ( ) => {
363+ for ( let i = 0 ; i < 10 ; i ++ ) {
364+ $ = await next . render$ ( pathname )
365+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
366+ expect ( $ ( '[data-agent]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
367+ }
368+ } )
369+
370+ it ( 'should render the fallback shell even if the page is static' , async ( ) => {
371+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
372+ const pathname = `/fallback/params/on-second-visit-${ random } `
373+
374+ // Expect that the slug had to be resumed.
375+ let $ = await next . render$ ( pathname )
376+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
377+
378+ for ( let i = 0 ; i < 10 ; i ++ ) {
379+ $ = await next . render$ ( pathname )
380+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
381+ }
382+ } )
383+
384+ it ( 'will not revalidate the fallback shell' , async ( ) => {
385+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
386+ const pathname = `/fallback/dynamic/params/revalidate-${ random } `
387+
388+ let $ = await next . render$ ( pathname )
389+ const fallbackID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
390+
391+ // Now let's revalidate the page.
392+ await next . fetch (
393+ `/api/revalidate?pathname=${ encodeURIComponent ( pathname ) } `
394+ )
395+
396+ // We expect to get the fallback shell again.
363397 $ = await next . render$ ( pathname )
364- expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 0 )
398+ expect ( $ ( '[data-layout]' ) . data ( 'layout' ) ) . toBe ( fallbackID )
399+
400+ // Let's wait for the page to be revalidated.
401+ await retry ( async ( ) => {
402+ $ = await next . render$ ( pathname )
403+ const newDynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
404+ expect ( newDynamicID ) . toBe ( fallbackID )
405+ } )
406+ } )
407+ } else {
408+ it ( 'should render the route shell on the second visit' , async ( ) => {
409+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
410+ const pathname = `/fallback/dynamic/params/on-second-visit-${ random } `
411+
412+ let $ = await next . render$ ( pathname )
413+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
365414 expect ( $ ( '[data-agent]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
415+
416+ await retry ( async ( ) => {
417+ $ = await next . render$ ( pathname )
418+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 0 )
419+ expect ( $ ( '[data-agent]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
420+ } )
366421 } )
367- } )
368422
369- it ( 'should render the dynamic shell as static if the page is static' , async ( ) => {
370- const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
371- const pathname = `/fallback/params/on-second-visit-${ random } `
423+ it ( 'should render the dynamic shell as static if the page is static' , async ( ) => {
424+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
425+ const pathname = `/fallback/params/on-second-visit-${ random } `
372426
373- // Expect that the slug had to be resumed.
374- let $ = await next . render$ ( pathname )
375- expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
427+ // Expect that the slug had to be resumed.
428+ let $ = await next . render$ ( pathname )
429+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 1 )
376430
377- // The slug didn't have to be resumed, and it should all be static.
378- await retry ( async ( ) => {
379- $ = await next . render$ ( pathname )
380- expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 0 )
431+ // The slug didn't have to be resumed, and it should all be static.
432+ await retry ( async ( ) => {
433+ $ = await next . render$ ( pathname )
434+ expect ( $ ( '[data-slug]' ) . closest ( '[hidden]' ) . length ) . toBe ( 0 )
381435
382- const {
383- timings : { streamFirstChunk, start, streamEnd } ,
384- chunks,
385- } = await measurePPRTimings ( async ( ) => {
386- const res = await next . fetch ( pathname )
387- expect ( res . status ) . toBe ( 200 )
388- if ( isNextDeploy ) {
389- expect ( res . headers . get ( 'x-vercel-cache' ) ) . toBe ( 'HIT' )
390- } else {
436+ const {
437+ timings : { streamFirstChunk, start, streamEnd } ,
438+ chunks,
439+ } = await measurePPRTimings ( async ( ) => {
440+ const res = await next . fetch ( pathname )
441+ expect ( res . status ) . toBe ( 200 )
391442 expect ( res . headers . get ( 'x-nextjs-cache' ) ) . toBe ( 'HIT' )
392- }
393443
394- return res . body
395- } , 1000 )
444+ return res . body
445+ } , 1000 )
396446
397- expect ( chunks . dynamic ) . toBe ( '' )
398- expect ( streamFirstChunk - start ) . toBeLessThan ( 500 )
399- expect ( streamEnd - start ) . toBeLessThan ( 500 )
447+ expect ( chunks . dynamic ) . toBe ( '' )
448+ expect ( streamFirstChunk - start ) . toBeLessThan ( 500 )
449+ expect ( streamEnd - start ) . toBeLessThan ( 500 )
450+ } )
400451 } )
401- } )
402452
403- it ( 'will only revalidate the page' , async ( ) => {
404- const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
405- const pathname = `/fallback/dynamic/params/revalidate-${ random } `
453+ it ( 'will only revalidate the page' , async ( ) => {
454+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
455+ const pathname = `/fallback/dynamic/params/revalidate-${ random } `
406456
407- let $ = await next . render$ ( pathname )
408- const fallbackID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
457+ let $ = await next . render$ ( pathname )
458+ const fallbackID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
409459
410- let dynamicID : string
411- await retry ( async ( ) => {
412- $ = await next . render$ ( pathname )
413- dynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
460+ let dynamicID : string
461+ await retry ( async ( ) => {
462+ $ = await next . render$ ( pathname )
463+ dynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
414464
415- // These should be different,
416- expect ( dynamicID ) . not . toBe ( fallbackID )
417- } )
465+ // These should be different,
466+ expect ( dynamicID ) . not . toBe ( fallbackID )
467+ } )
418468
419- // Now let's revalidate the page.
420- await next . fetch (
421- `/api/revalidate?pathname=${ encodeURIComponent ( pathname ) } `
422- )
469+ // Now let's revalidate the page.
470+ await next . fetch (
471+ `/api/revalidate?pathname=${ encodeURIComponent ( pathname ) } `
472+ )
423473
424- // We expect to get the fallback shell again.
425- if ( ! isNextDeploy ) {
474+ // We expect to get the fallback shell again.
426475 $ = await next . render$ ( pathname )
427476 expect ( $ ( '[data-layout]' ) . data ( 'layout' ) ) . toBe ( fallbackID )
428- }
429477
430- // Let's wait for the page to be revalidated.
431- await retry ( async ( ) => {
432- $ = await next . render$ ( pathname )
433- const newDynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
434- expect ( newDynamicID ) . not . toBe ( dynamicID )
478+ // Let's wait for the page to be revalidated.
479+ await retry ( async ( ) => {
480+ $ = await next . render$ ( pathname )
481+ const newDynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
482+ expect ( newDynamicID ) . not . toBe ( dynamicID )
483+ } )
435484 } )
436- } )
437485
438- it ( 'will revalidate the page and fallback shell' , async ( ) => {
439- const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
440- const pathname = `/fallback/dynamic/params/revalidate-${ random } `
486+ it ( 'will revalidate the page and fallback shell' , async ( ) => {
487+ const random = Math . random ( ) . toString ( 16 ) . slice ( 2 )
488+ const pathname = `/fallback/dynamic/params/revalidate-${ random } `
441489
442- let $ = await next . render$ ( pathname )
443- const fallbackID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
490+ let $ = await next . render$ ( pathname )
491+ const fallbackID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
444492
445- let dynamicID : string
446- await retry ( async ( ) => {
447- $ = await next . render$ ( pathname )
448- dynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
493+ let dynamicID : string
494+ await retry ( async ( ) => {
495+ $ = await next . render$ ( pathname )
496+ dynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
449497
450- // These should be different,
451- expect ( dynamicID ) . not . toBe ( fallbackID )
452- } )
498+ // These should be different,
499+ expect ( dynamicID ) . not . toBe ( fallbackID )
500+ } )
453501
454- // Now let's revalidate the page.
455- await next . fetch (
456- `/api/revalidate?pathname=${ encodeURIComponent ( pathname ) } `
457- )
502+ // Now let's revalidate the page.
503+ await next . fetch (
504+ `/api/revalidate?pathname=${ encodeURIComponent ( pathname ) } `
505+ )
458506
459- // We expect to get the fallback shell.
460- $ = await next . render$ ( pathname )
507+ // We expect to get the fallback shell.
508+ $ = await next . render$ ( pathname )
461509
462- // When deployed to Vercel, it will serve a stale version of the dynamic shell
463- // Whereas with `next start` it will serve the fallback shell
464- if ( isNextDeploy ) {
465- expect ( $ ( '[data-layout]' ) . data ( 'layout' ) ) . toBe ( dynamicID )
466- } else {
510+ // When deployed to Vercel, it will serve a stale version of the dynamic shell
511+ // Whereas with `next start` it will serve the fallback shell
467512 expect ( $ ( '[data-layout]' ) . data ( 'layout' ) ) . toBe ( fallbackID )
468- }
469513
470- // Let's wait for the page to be revalidated.
471- let revalidatedDynamicID : string
472- await retry ( async ( ) => {
473- $ = await next . render$ ( pathname )
474- revalidatedDynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
475- expect ( revalidatedDynamicID ) . not . toBe ( dynamicID )
476- expect ( revalidatedDynamicID ) . not . toBe ( fallbackID )
514+ // Let's wait for the page to be revalidated.
515+ let revalidatedDynamicID : string
516+ await retry ( async ( ) => {
517+ $ = await next . render$ ( pathname )
518+ revalidatedDynamicID = $ ( '[data-layout]' ) . data ( 'layout' ) as string
519+ expect ( revalidatedDynamicID ) . not . toBe ( dynamicID )
520+ expect ( revalidatedDynamicID ) . not . toBe ( fallbackID )
521+ } )
477522 } )
478- } )
523+ }
479524
480525 /**
481526 * This test is really here to just to force the the suite to have the expected route
0 commit comments