mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
e0966df114
## Summary - migrate Cache Components, PPR, prefetching, prerendering, revalidation, and SSG deployment exclusions to `@force-gate` - remove the corresponding `skipDeployment` options and `skipped` control flow while preserving each suite's rationale This keeps caching-related exclusions together so their deployed semantics can be reviewed by the same owners. ## Verification - verified on the combined top-of-stack tree with `pnpm typescript` - compared ordinary-mode collection before and after: all 4,670 existing test names matched - collected all 510 affected files in deploy mode: 4,578 skipped tests, zero failures <!-- NEXT_JS_LLM -->
134 lines
4.7 KiB
TypeScript
134 lines
4.7 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
||
import { hasErrorToast, retry, waitFor, waitForNoRedbox } from 'next-test-utils'
|
||
import stripAnsi from 'strip-ansi'
|
||
|
||
// TODO(deploy-test-completion): Re-enable this suite in deploy mode.
|
||
// It likely asserts local CLI or runtime output that deploy tests do not expose.
|
||
// @force-gate !deploy
|
||
describe('app-custom-cache-handler-errors - get throws', () => {
|
||
const { next, isNextDev, isTurbopack } = nextTestSetup({
|
||
files: __dirname,
|
||
env: { CACHE_HANDLER_THROW_ON: 'get' },
|
||
})
|
||
|
||
it('surfaces the cache handler error', async () => {
|
||
const outputIndex = next.cliOutput.length
|
||
const browser = await next.browser('/?input=x')
|
||
|
||
if (isNextDev) {
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "CustomCacheHandler.get failed",
|
||
"environmentLabel": "Prefetch",
|
||
"label": "Runtime Error",
|
||
"source": "app/page.tsx (19:14) @ CachedData
|
||
> 19 | return <p>{await getCachedData(input)}</p>
|
||
| ^",
|
||
"stack": [
|
||
"Object.get throwing-cache-handler.js (24:13)",
|
||
"CachedData app/page.tsx (19:14)",
|
||
],
|
||
}
|
||
`)
|
||
} else {
|
||
// TODO(veil): Webpack renders the cache handler frame as a file://
|
||
// URL, which the redbox matcher flags as unintended.
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "CustomCacheHandler.get failed",
|
||
"environmentLabel": "Prefetch",
|
||
"label": "Runtime Error",
|
||
"source": "app/page.tsx (19:14) @ CachedData
|
||
> 19 | return <p>{await getCachedData(input)}</p>
|
||
| ^",
|
||
"stack": [
|
||
"<FIXME-file-protocol>",
|
||
"CachedData app/page.tsx (19:14)",
|
||
],
|
||
}
|
||
`)
|
||
}
|
||
}
|
||
|
||
await retry(async () => {
|
||
expect(next.cliOutput.slice(outputIndex)).toContain(
|
||
'⨯ Error: CustomCacheHandler.get failed'
|
||
)
|
||
})
|
||
|
||
// Give a potential unhandled rejection a chance to be reported before
|
||
// asserting its absence.
|
||
await waitFor(1000)
|
||
|
||
const cliOutput = stripAnsi(next.cliOutput.slice(outputIndex))
|
||
|
||
const errorBlock = isNextDev
|
||
? 'Error: CustomCacheHandler.get failed' +
|
||
'\n at Object.get (throwing-cache-handler.js:24:13)' +
|
||
'\n at async CachedData (app/page.tsx:19:14)' +
|
||
"\n 17 | const { input = 'default' } = await searchParams" +
|
||
'\n 18 |' +
|
||
'\n> 19 | return <p>{await getCachedData(input)}</p>' +
|
||
'\n | ^' +
|
||
'\n 20 | }' +
|
||
'\n 21 |' +
|
||
'\n 22 | export default function Page({ {' +
|
||
"\n digest: '"
|
||
: // In production, the frames below the cache handler frame are bundled
|
||
// code, and are therefore not stable across bundlers and builds.
|
||
'Error: CustomCacheHandler.get failed' +
|
||
'\n at Object.get (throwing-cache-handler.js:24:13)' +
|
||
'\n at '
|
||
|
||
expect(cliOutput).toContain('⨯ ' + errorBlock)
|
||
|
||
if (!isNextDev) {
|
||
expect(cliOutput).toContain(" digest: '")
|
||
}
|
||
|
||
// The error must be logged exactly once, as a rendering error, and in
|
||
// particular not additionally as an unhandled rejection.
|
||
expect(cliOutput).not.toContain('unhandledRejection')
|
||
expect(cliOutput.split(errorBlock).length - 1).toBe(1)
|
||
})
|
||
})
|
||
|
||
// TODO(deploy-test-completion): Re-enable this suite in deploy mode.
|
||
// It likely asserts local CLI or runtime output that deploy tests do not expose.
|
||
// @force-gate !deploy
|
||
describe('app-custom-cache-handler-errors - set throws', () => {
|
||
const { next, isNextDev } = nextTestSetup({
|
||
files: __dirname,
|
||
env: { CACHE_HANDLER_THROW_ON: 'set' },
|
||
})
|
||
|
||
it('renders the page successfully', async () => {
|
||
const outputIndex = next.cliOutput.length
|
||
const browser = await next.browser('/?input=x')
|
||
|
||
expect(await browser.elementByCss('p').text()).toBe(
|
||
'cached data for input: x'
|
||
)
|
||
|
||
if (isNextDev) {
|
||
// A throwing set() is currently completely silent in dev: the cache
|
||
// handler is called and its rejection is swallowed without being logged
|
||
// or reported to the dev overlay.
|
||
await waitForNoRedbox(browser)
|
||
expect(await hasErrorToast(browser)).toBe(false)
|
||
expect(next.cliOutput.slice(outputIndex)).not.toContain(
|
||
'CustomCacheHandler.set failed'
|
||
)
|
||
} else {
|
||
await retry(async () => {
|
||
expect(stripAnsi(next.cliOutput.slice(outputIndex))).toContain(
|
||
'Error: CustomCacheHandler.set failed' +
|
||
'\n at Object.set (throwing-cache-handler.js:50:13)' +
|
||
'\n at <unknown> ('
|
||
)
|
||
})
|
||
}
|
||
})
|
||
})
|