rsnext/test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts
Zack Tanner 5f98e9bc6e
fix behavior when revisiting an intercepted route (#59168)
### What?
When using rewrites, in the scenario where a user visits an intercepted
route, reloads the page, goes back, and then revisits the same route, we
serve the page rather than the intercepted route.

### Why?
#59094 fixed the case where `ACTION_RESTORE` was not restoring `nextUrl`
properly. However there's a separate issue where when the `SERVER_PATCH`
action comes in, `handleMutable` attempts to compute `nextUrl` by
comparing the patched tree with the current tree. In the case of the
popstate event, both trees are the same, so the logic is currently
configured to fallback to `canonicalUrl`, which is not the correct URL
to use in the case of rewrites.

### How?
If the computed changed path is null, we should only fallback to using
`canonicalUrl` if we don't have a valid `nextUrl` that we can use.

Closes NEXT-1747
Fixes #56072
2023-12-01 08:54:01 -08:00

90 lines
2.7 KiB
TypeScript

import { createNextDescribe } from 'e2e-utils'
import { check } from 'next-test-utils'
createNextDescribe(
'interception-middleware-rewrite',
{
files: __dirname,
// TODO: remove after deployment handling is updated
skipDeployment: true,
},
({ next }) => {
it('should support intercepting routes with a middleware rewrite', async () => {
const browser = await next.browser('/')
await check(() => browser.waitForElementByCss('#children').text(), 'root')
await check(
() =>
browser
.elementByCss('[href="/feed"]')
.click()
.waitForElementByCss('#modal')
.text(),
'intercepted'
)
await check(
() => browser.refresh().waitForElementByCss('#children').text(),
'not intercepted'
)
await check(() => browser.waitForElementByCss('#modal').text(), '')
})
it('should continue to work after using browser back button and following another intercepting route', async () => {
const browser = await next.browser('/')
await check(() => browser.elementById('children').text(), 'root')
await browser.elementByCss('[href="/photos/1"]').click()
await check(
() => browser.elementById('modal').text(),
'Intercepted Photo ID: 1'
)
await browser.back()
await browser.elementByCss('[href="/photos/2"]').click()
await check(
() => browser.elementById('modal').text(),
'Intercepted Photo ID: 2'
)
})
it('should continue to show the intercepted page when revisiting it', async () => {
const browser = await next.browser('/')
await check(() => browser.elementById('children').text(), 'root')
await browser.elementByCss('[href="/photos/1"]').click()
// we should be showing the modal and not the page
await check(
() => browser.elementById('modal').text(),
'Intercepted Photo ID: 1'
)
await browser.refresh()
// page should show after reloading the browser
await check(
() => browser.elementById('children').text(),
'Page Photo ID: 1'
)
// modal should no longer be showing
await check(() => browser.elementById('modal').text(), '')
await browser.back()
// revisit the same page that was intercepted
await browser.elementByCss('[href="/photos/1"]').click()
// ensure that we're still showing the modal and not the page
await check(
() => browser.elementById('modal').text(),
'Intercepted Photo ID: 1'
)
// page content should not have changed
await check(() => browser.elementById('children').text(), 'root')
})
}
)