rsnext/test/e2e/app-dir/interception-route-prefetch-cache/interception-route-prefetch-cache.test.ts
Zack Tanner 3e3c012726
provide interception rewrites to edge runtime (#61414)
In #61794, the routes manifest is used to find the interception route rewrites in `next-server` and computed on the fly in `next-dev-server` based on `appPaths`.

The edge runtime doesn't have access to the routes manifest nor a full list of app paths. This writes an entry for the edge runtime to make the interception routes readable, and adds plumbing to return them in the `getInterceptionRouteRewrites` handling in `web-server`. This is what we use to signal to the server whether to return ‘Next-URL’ in the Vary for RSC requests. 

This piggybacks on the existing interception routes test but adds an edge runtime case.

Closes NEXT-2304
2024-02-09 10:30:58 -08:00

100 lines
3.5 KiB
TypeScript

import { nextTestSetup, FileRef } from 'e2e-utils'
import { check } from 'next-test-utils'
import { join } from 'path'
import { Response } from 'playwright-chromium'
describe('interception-route-prefetch-cache', () => {
function runTests({ next }: ReturnType<typeof nextTestSetup>) {
it('should render the correct interception when two distinct layouts share the same path structure', async () => {
const browser = await next.browser('/')
await browser.elementByCss('[href="/foo"]').click()
await check(() => browser.elementById('children').text(), /Foo Page/)
await browser.elementByCss('[href="/post/1"]').click()
// Ensure the existing page content is still the same
await check(() => browser.elementById('children').text(), /Foo Page/)
// Verify we got the right interception
await check(
() => browser.elementById('slot').text(),
/Intercepted on Foo Page/
)
// Go back home. At this point, the router cache should have content from /foo
// Now we want to ensure that /bar doesn't share that same prefetch cache entry
await browser.elementByCss('[href="/"]').click()
await browser.elementByCss('[href="/bar"]').click()
await check(() => browser.elementById('children').text(), /Bar Page/)
await browser.elementByCss('[href="/post/1"]').click()
// Ensure the existing page content is still the same. If the prefetch cache resolved the wrong cache node
// then we'd see the content from /foo
await check(() => browser.elementById('children').text(), /Bar Page/)
await check(
() => browser.elementById('slot').text(),
/Intercepted on Bar Page/
)
})
}
describe('runtime = nodejs', () => {
const testSetup = nextTestSetup({
files: __dirname,
})
runTests(testSetup)
const { next, isNextStart } = testSetup
// this is a node runtime specific test as edge doesn't support static rendering
if (isNextStart) {
it('should not be a cache HIT when prefetching an interception route', async () => {
const responses: { cacheStatus: string; pathname: string }[] = []
const browser = await next.browser('/baz', {
beforePageLoad(page) {
page.on('response', (response: Response) => {
const url = new URL(response.url())
const request = response.request()
const responseHeaders = response.headers()
const requestHeaders = request.headers()
if (requestHeaders['next-router-prefetch']) {
responses.push({
cacheStatus: responseHeaders['x-nextjs-cache'],
pathname: url.pathname,
})
}
})
},
})
expect(await browser.elementByCss('body').text()).toContain(
'Open Interception Modal'
)
const interceptionPrefetchResponse = responses.find(
(response) => response.pathname === '/baz/modal'
)
const homePrefetchResponse = responses.find(
(response) => response.pathname === '/'
)
expect(homePrefetchResponse.cacheStatus).toBe('HIT') // sanity check to ensure we're seeing cache statuses
expect(interceptionPrefetchResponse.cacheStatus).toBeUndefined()
})
}
})
describe('runtime = edge', () => {
runTests(
nextTestSetup({
files: {
app: new FileRef(join(__dirname, 'app')),
'app/layout.tsx': new FileRef(join(__dirname, 'app/layout-edge.tsx')),
},
})
)
})
})