Skip to content

Commit

Permalink
[ppr] Fixed deployment tests (#72428)
Browse files Browse the repository at this point in the history
  • Loading branch information
wyattjoh authored Nov 7, 2024
1 parent 856521b commit f668af2
Showing 1 changed file with 137 additions and 92 deletions.
229 changes: 137 additions & 92 deletions test/e2e/app-dir/ppr-full/ppr-full.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit f668af2

Please sign in to comment.