mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
### Why? Current behavior: https://github.com/vercel/next.js/actions/runs/28225010081/job/83615571987?pr=95184#step:31:8732 For a minimal-mode resume request carrying the Instant Navigation testing cookie, Next.js skips the postponed render so the test receives only the prefetched static shell. The resulting empty continuation was represented as `PAGES`, but the App Page handler requires `APP_PAGE`, causing error: ``` Error: Invariant app-page handler received invalid cache entry PAGES ``` ### How? Return an empty `APP_PAGE` response with the correct HTML or RSC content type and postponed metadata. If the document continuation has no `<head>` chunk, insert the Instant Navigation bootstrap while flushing the stream. Add production regression coverage for document and RSC-prefetch resume requests using build-generated postponed state. <!-- NEXT_JS_LLM_PR -->
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
|
|
describe('instant-navigation-resume', () => {
|
|
const { next } = nextTestSetup({
|
|
files: __dirname,
|
|
// This test directly emulates the platform's internal resume request using
|
|
// locally generated postponed state and private runtime switches.
|
|
skipDeployment: true,
|
|
env: {
|
|
NEXT_PRIVATE_TEST_HEADERS: '1',
|
|
NEXT_PRIVATE_MINIMAL_MODE: '1',
|
|
},
|
|
})
|
|
|
|
async function getPostponedState() {
|
|
const { postponed } = await next.readJSON('.next/server/app/index.meta')
|
|
|
|
expect(postponed).toEqual(expect.any(String))
|
|
expect(postponed.length).toBeGreaterThan(0)
|
|
return postponed as string
|
|
}
|
|
|
|
it('handles an instant-navigation document resume', async () => {
|
|
const postponed = await getPostponedState()
|
|
const cliOutputIndex = next.cliOutput.length
|
|
const response = await next.fetch('/', {
|
|
method: 'POST',
|
|
headers: {
|
|
cookie: 'next-instant-navigation-testing=1',
|
|
'next-resume': '1',
|
|
'x-matched-path': '/',
|
|
},
|
|
body: postponed,
|
|
})
|
|
|
|
expect(response.status).toBe(200)
|
|
await response.text()
|
|
expect(
|
|
next.cliOutput
|
|
.slice(cliOutputIndex)
|
|
.match(/Invariant app-page handler received invalid cache entry PAGES/)
|
|
).toBeNull()
|
|
})
|
|
|
|
it('handles an instant-navigation RSC prefetch resume', async () => {
|
|
const postponed = await getPostponedState()
|
|
const cliOutputIndex = next.cliOutput.length
|
|
const response = await next.fetch('/', {
|
|
method: 'POST',
|
|
headers: {
|
|
cookie: 'next-instant-navigation-testing=1',
|
|
'next-resume': '1',
|
|
'next-router-prefetch': '1',
|
|
rsc: '1',
|
|
'x-matched-path': '/',
|
|
},
|
|
body: postponed,
|
|
})
|
|
|
|
expect(response.status).toBe(200)
|
|
await response.text()
|
|
expect(
|
|
next.cliOutput
|
|
.slice(cliOutputIndex)
|
|
.match(/Invariant app-page handler received invalid cache entry PAGES/)
|
|
).toBeNull()
|
|
})
|
|
})
|