1481b2649f
### What? When accessing `params` on a `RootLayout`, while also using parallel routes, two potential errors would occur: - A `Warning: React.createElement: type is invalid` error when attempting to render a `NotFound` component that doesn't exist - A `TypeError: Cannot read properties of undefined` error when attempting to access params in the root layout. ### Why? `createComponentTree` will render a duplicate `RootLayout` (to ensure the `notFound()` fallback in unmatched parallel slots have a `NotFoundBoundary` to catch them) but it currently doesn't ensure a `NotFound` component exists nor does it forward `params` to the layout. ### How? This forwards the params to the `RootLayout` and doesn't render a `NotFoundComponent` if one doesn't exist. This replaces a few `any` types with more sound types that would have helped catch these mistakes. There's still a lot more typing that needs to be done (left a comment below with some additional details) but I opted to make the minimal changes related to this issue. Longer term we should remove this duplicate `RootLayout` (see #60220) which will require special UI to show unmatched slots (similar to the error overlay, but less harsh) Closes NEXT-1909 Fixes #59711
73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
import { createNextDescribe } from 'e2e-utils'
|
|
import { check } from 'next-test-utils'
|
|
|
|
createNextDescribe(
|
|
'parallel-route-not-found',
|
|
{
|
|
files: __dirname,
|
|
},
|
|
({ next }) => {
|
|
it('should behave correctly without any errors', async () => {
|
|
const browser = await next.browser('/en')
|
|
await check(() => {
|
|
if (
|
|
next.cliOutput.includes('TypeError') ||
|
|
next.cliOutput.includes('Warning')
|
|
) {
|
|
return 'has-errors'
|
|
}
|
|
|
|
return 'success'
|
|
}, 'success')
|
|
|
|
expect(await browser.elementByCss('body').text()).not.toContain(
|
|
'Interception Modal'
|
|
)
|
|
expect(await browser.elementByCss('body').text()).toContain('Locale: en')
|
|
|
|
await browser.elementByCss("[href='/en/show']").click()
|
|
|
|
await check(() => {
|
|
if (
|
|
next.cliOutput.includes('TypeError') ||
|
|
next.cliOutput.includes('Warning')
|
|
) {
|
|
return 'has-errors'
|
|
}
|
|
|
|
return 'success'
|
|
}, 'success')
|
|
|
|
await check(
|
|
() => browser.elementByCss('body').text(),
|
|
/Interception Modal/
|
|
)
|
|
await check(() => browser.elementByCss('body').text(), /Locale: en/)
|
|
|
|
await browser.refresh()
|
|
await check(
|
|
() => browser.elementByCss('body').text(),
|
|
/Regular Modal Page/
|
|
)
|
|
await check(() => browser.elementByCss('body').text(), /Locale: en/)
|
|
})
|
|
|
|
it('should handle the not found case correctly without any errors', async () => {
|
|
const browser = await next.browser('/de/show')
|
|
await check(() => {
|
|
if (
|
|
next.cliOutput.includes('TypeError') ||
|
|
next.cliOutput.includes('Warning')
|
|
) {
|
|
return 'has-errors'
|
|
}
|
|
|
|
return 'success'
|
|
}, 'success')
|
|
|
|
expect(await browser.elementByCss('body').text()).toContain(
|
|
'Custom Not Found'
|
|
)
|
|
})
|
|
}
|
|
)
|