From f668af206134cde2963b4971a26f517598e92ee6 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 7 Nov 2024 02:25:50 -0700 Subject: [PATCH] [ppr] Fixed deployment tests (#72428) --- test/e2e/app-dir/ppr-full/ppr-full.test.ts | 229 ++++++++++++--------- 1 file changed, 137 insertions(+), 92 deletions(-) diff --git a/test/e2e/app-dir/ppr-full/ppr-full.test.ts b/test/e2e/app-dir/ppr-full/ppr-full.test.ts index b95730f39e8ae..9f42aa03e0bbd 100644 --- a/test/e2e/app-dir/ppr-full/ppr-full.test.ts +++ b/test/e2e/app-dir/ppr-full/ppr-full.test.ts @@ -351,131 +351,176 @@ describe('ppr-full', () => { expect($('[data-agent]').closest('[hidden]').length).toBe(1) }) - it('should render the dynamic shell on the second visit', async () => { - const random = Math.random().toString(16).slice(2) - const pathname = `/fallback/dynamic/params/on-second-visit-${random}` + if (isNextDeploy) { + it('should render the fallback shell every time', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/dynamic/params/on-second-visit-${random}` - let $ = await next.render$(pathname) - expect($('[data-slug]').closest('[hidden]').length).toBe(1) - expect($('[data-agent]').closest('[hidden]').length).toBe(1) + let $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(1) + expect($('[data-agent]').closest('[hidden]').length).toBe(1) - await retry(async () => { + for (let i = 0; i < 10; i++) { + $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(1) + expect($('[data-agent]').closest('[hidden]').length).toBe(1) + } + }) + + it('should render the fallback shell even if the page is static', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/params/on-second-visit-${random}` + + // Expect that the slug had to be resumed. + let $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(1) + + for (let i = 0; i < 10; i++) { + $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(1) + } + }) + + it('will not revalidate the fallback shell', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/dynamic/params/revalidate-${random}` + + let $ = await next.render$(pathname) + const fallbackID = $('[data-layout]').data('layout') as string + + // Now let's revalidate the page. + await next.fetch( + `/api/revalidate?pathname=${encodeURIComponent(pathname)}` + ) + + // We expect to get the fallback shell again. $ = await next.render$(pathname) - expect($('[data-slug]').closest('[hidden]').length).toBe(0) + expect($('[data-layout]').data('layout')).toBe(fallbackID) + + // Let's wait for the page to be revalidated. + await retry(async () => { + $ = await next.render$(pathname) + const newDynamicID = $('[data-layout]').data('layout') as string + expect(newDynamicID).toBe(fallbackID) + }) + }) + } else { + it('should render the route shell on the second visit', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/dynamic/params/on-second-visit-${random}` + + let $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(1) expect($('[data-agent]').closest('[hidden]').length).toBe(1) + + await retry(async () => { + $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(0) + expect($('[data-agent]').closest('[hidden]').length).toBe(1) + }) }) - }) - it('should render the dynamic shell as static if the page is static', async () => { - const random = Math.random().toString(16).slice(2) - const pathname = `/fallback/params/on-second-visit-${random}` + it('should render the dynamic shell as static if the page is static', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/params/on-second-visit-${random}` - // Expect that the slug had to be resumed. - let $ = await next.render$(pathname) - expect($('[data-slug]').closest('[hidden]').length).toBe(1) + // Expect that the slug had to be resumed. + let $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(1) - // The slug didn't have to be resumed, and it should all be static. - await retry(async () => { - $ = await next.render$(pathname) - expect($('[data-slug]').closest('[hidden]').length).toBe(0) + // The slug didn't have to be resumed, and it should all be static. + await retry(async () => { + $ = await next.render$(pathname) + expect($('[data-slug]').closest('[hidden]').length).toBe(0) - const { - timings: { streamFirstChunk, start, streamEnd }, - chunks, - } = await measurePPRTimings(async () => { - const res = await next.fetch(pathname) - expect(res.status).toBe(200) - if (isNextDeploy) { - expect(res.headers.get('x-vercel-cache')).toBe('HIT') - } else { + const { + timings: { streamFirstChunk, start, streamEnd }, + chunks, + } = await measurePPRTimings(async () => { + const res = await next.fetch(pathname) + expect(res.status).toBe(200) expect(res.headers.get('x-nextjs-cache')).toBe('HIT') - } - return res.body - }, 1000) + return res.body + }, 1000) - expect(chunks.dynamic).toBe('') - expect(streamFirstChunk - start).toBeLessThan(500) - expect(streamEnd - start).toBeLessThan(500) + expect(chunks.dynamic).toBe('') + expect(streamFirstChunk - start).toBeLessThan(500) + expect(streamEnd - start).toBeLessThan(500) + }) }) - }) - it('will only revalidate the page', async () => { - const random = Math.random().toString(16).slice(2) - const pathname = `/fallback/dynamic/params/revalidate-${random}` + it('will only revalidate the page', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/dynamic/params/revalidate-${random}` - let $ = await next.render$(pathname) - const fallbackID = $('[data-layout]').data('layout') as string + let $ = await next.render$(pathname) + const fallbackID = $('[data-layout]').data('layout') as string - let dynamicID: string - await retry(async () => { - $ = await next.render$(pathname) - dynamicID = $('[data-layout]').data('layout') as string + let dynamicID: string + await retry(async () => { + $ = await next.render$(pathname) + dynamicID = $('[data-layout]').data('layout') as string - // These should be different, - expect(dynamicID).not.toBe(fallbackID) - }) + // These should be different, + expect(dynamicID).not.toBe(fallbackID) + }) - // Now let's revalidate the page. - await next.fetch( - `/api/revalidate?pathname=${encodeURIComponent(pathname)}` - ) + // Now let's revalidate the page. + await next.fetch( + `/api/revalidate?pathname=${encodeURIComponent(pathname)}` + ) - // We expect to get the fallback shell again. - if (!isNextDeploy) { + // We expect to get the fallback shell again. $ = await next.render$(pathname) expect($('[data-layout]').data('layout')).toBe(fallbackID) - } - // Let's wait for the page to be revalidated. - await retry(async () => { - $ = await next.render$(pathname) - const newDynamicID = $('[data-layout]').data('layout') as string - expect(newDynamicID).not.toBe(dynamicID) + // Let's wait for the page to be revalidated. + await retry(async () => { + $ = await next.render$(pathname) + const newDynamicID = $('[data-layout]').data('layout') as string + expect(newDynamicID).not.toBe(dynamicID) + }) }) - }) - it('will revalidate the page and fallback shell', async () => { - const random = Math.random().toString(16).slice(2) - const pathname = `/fallback/dynamic/params/revalidate-${random}` + it('will revalidate the page and fallback shell', async () => { + const random = Math.random().toString(16).slice(2) + const pathname = `/fallback/dynamic/params/revalidate-${random}` - let $ = await next.render$(pathname) - const fallbackID = $('[data-layout]').data('layout') as string + let $ = await next.render$(pathname) + const fallbackID = $('[data-layout]').data('layout') as string - let dynamicID: string - await retry(async () => { - $ = await next.render$(pathname) - dynamicID = $('[data-layout]').data('layout') as string + let dynamicID: string + await retry(async () => { + $ = await next.render$(pathname) + dynamicID = $('[data-layout]').data('layout') as string - // These should be different, - expect(dynamicID).not.toBe(fallbackID) - }) + // These should be different, + expect(dynamicID).not.toBe(fallbackID) + }) - // Now let's revalidate the page. - await next.fetch( - `/api/revalidate?pathname=${encodeURIComponent(pathname)}` - ) + // Now let's revalidate the page. + await next.fetch( + `/api/revalidate?pathname=${encodeURIComponent(pathname)}` + ) - // We expect to get the fallback shell. - $ = await next.render$(pathname) + // We expect to get the fallback shell. + $ = await next.render$(pathname) - // When deployed to Vercel, it will serve a stale version of the dynamic shell - // Whereas with `next start` it will serve the fallback shell - if (isNextDeploy) { - expect($('[data-layout]').data('layout')).toBe(dynamicID) - } else { + // When deployed to Vercel, it will serve a stale version of the dynamic shell + // Whereas with `next start` it will serve the fallback shell expect($('[data-layout]').data('layout')).toBe(fallbackID) - } - // Let's wait for the page to be revalidated. - let revalidatedDynamicID: string - await retry(async () => { - $ = await next.render$(pathname) - revalidatedDynamicID = $('[data-layout]').data('layout') as string - expect(revalidatedDynamicID).not.toBe(dynamicID) - expect(revalidatedDynamicID).not.toBe(fallbackID) + // Let's wait for the page to be revalidated. + let revalidatedDynamicID: string + await retry(async () => { + $ = await next.render$(pathname) + revalidatedDynamicID = $('[data-layout]').data('layout') as string + expect(revalidatedDynamicID).not.toBe(dynamicID) + expect(revalidatedDynamicID).not.toBe(fallbackID) + }) }) - }) + } /** * This test is really here to just to force the the suite to have the expected route