|
| 1 | +import { nextTestSetup } from 'e2e-utils' |
| 2 | + |
| 3 | +// Only Turbopack runs the transform on the layout once in edge and non-edge contexts |
| 4 | +// so we only test this on Turbopack |
| 5 | +import { |
| 6 | + assertHasRedbox, |
| 7 | + getRedboxDescription, |
| 8 | + getRedboxSource, |
| 9 | +} from 'next-test-utils' |
| 10 | +;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)( |
| 11 | + 'cache-components-edge-deduplication', |
| 12 | + () => { |
| 13 | + const { next, skipped, isNextDev } = nextTestSetup({ |
| 14 | + files: __dirname + '/fixtures/edge-deduplication', |
| 15 | + skipStart: true, |
| 16 | + skipDeployment: true, |
| 17 | + }) |
| 18 | + |
| 19 | + if (skipped) { |
| 20 | + return |
| 21 | + } |
| 22 | + |
| 23 | + it('should not duplicate errors when layout is compiled for both edge and non-edge contexts', async () => { |
| 24 | + try { |
| 25 | + await next.start() |
| 26 | + } catch { |
| 27 | + // we expect the build to fail |
| 28 | + } |
| 29 | + |
| 30 | + if (isNextDev) { |
| 31 | + const browser = await next.browser('/edge-with-layout/edge') |
| 32 | + assertHasRedbox(browser) |
| 33 | + const redbox = { |
| 34 | + description: await getRedboxDescription(browser), |
| 35 | + source: await getRedboxSource(browser), |
| 36 | + } |
| 37 | + expect(redbox.description).toMatchInlineSnapshot( |
| 38 | + `"Ecmascript file had an error"` |
| 39 | + ) |
| 40 | + expect(redbox.source).toMatchInlineSnapshot(` |
| 41 | + "./app/edge-with-layout/edge/page.tsx (1:14) |
| 42 | + Ecmascript file had an error |
| 43 | + > 1 | export const runtime = 'edge' |
| 44 | + | ^^^^^^^ |
| 45 | + 2 | |
| 46 | + 3 | export default function Page() { |
| 47 | + 4 | return <div>Test page under app/</div> |
| 48 | +
|
| 49 | + Route segment config "runtime" is not compatible with \`nextConfig.cacheComponents\`. Please remove it." |
| 50 | + `) |
| 51 | + // Count occurrences of the layout error at the specific location |
| 52 | + const layoutErrorMatches = next.cliOutput.match( |
| 53 | + /\.\/app\/edge-with-layout\/layout\.tsx:1:14/g |
| 54 | + ) |
| 55 | + // We don't show an error stack, just the individual error messages at each location |
| 56 | + expect(layoutErrorMatches?.length).toBe(1) |
| 57 | + } else { |
| 58 | + // Check that both the layout and edge page errors appear |
| 59 | + expect(next.cliOutput).toContain('./app/edge-with-layout/layout.tsx') |
| 60 | + expect(next.cliOutput).toContain('./app/edge-with-layout/edge/page.tsx') |
| 61 | + expect(next.cliOutput).toContain( |
| 62 | + '"dynamic" is not compatible with `nextConfig.cacheComponents`. Please remove it.' |
| 63 | + ) |
| 64 | + expect(next.cliOutput).toContain( |
| 65 | + '"runtime" is not compatible with `nextConfig.cacheComponents`. Please remove it.' |
| 66 | + ) |
| 67 | + // Count occurrences of the layout error at the specific location |
| 68 | + const layoutErrorMatches = next.cliOutput.match( |
| 69 | + /\.\/app\/layout\.tsx:1:14/g |
| 70 | + ) |
| 71 | + |
| 72 | + // Should appear exactly twice: once in the formatted error message, once in the stack trace |
| 73 | + expect(layoutErrorMatches?.length).toBe(2) |
| 74 | + } |
| 75 | + }) |
| 76 | + } |
| 77 | +) |
0 commit comments