import { isNextDev, nextTestSetup } from 'e2e-utils' import { retry } from 'next-test-utils' import stripAnsi from 'strip-ansi' // TODO(restart-on-cache-miss): cacheSignal timing changes break console log dimming/hiding tests describe.skip('cache-components - Console Dimming - Validation', () => { const { next, skipped, isTurbopack } = nextTestSetup({ env: { FORCE_COLOR: '1', }, files: __dirname + '/fixtures/default', skipDeployment: true, skipStart: !isNextDev, }) if (skipped) { return } it('dims console calls during prospective rendering', async () => { const path: string = '/console' if (isNextDev) { const browser = await next.browser(path, {}) await retry(() => { expect(stripAnsi(next.cliOutput)).toContain(`GET ${path} 200`) }) // do not strip ANSI codes here since we're explicitly testing coloring. const cliOutputFromPage = next.cliOutput.match( new RegExp(`Compiled ${path}[^\n]+\n(.*)`, 's') )[1] const reorderedLines = reorderLinesByBadge(cliOutputFromPage) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console: template(one: one, two: two) :::0:out::: /console: This is a console page. Don't match the codeframe. :::0:out::: /console: template(one: one, two: two) :::0:out::: /console: This is a console page. Don't match the codeframe.  Cache  :::0:out::: /console: template(one: one, two: two)  Cache  :::0:out::: /console: This is a console page. Don't match the codeframe. :::0:err::: /console: not a template { foo: 'just-some-object' } Error: :::0:err::: /console: test at ConsolePage (app/console/page.tsx::)   40 | })  41 | await 1 > 42 | console.error(new Error(\`\${errBadge} /console: test\`))  | ^  43 | await 1  44 | console.assert(  45 | false, Assertion failed: :::0:err::: /console: This is an assert message with a template :::0:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::0:err::: /console: This is an assert message with a template  Cache  :::0:err::: /console: not a template { foo: 'just-some-object' } Assertion failed:  Cache  :::0:err::: /console: This is an assert message with a template  Cache  Assertion failed: :::0:err::: /console: This is an assert message with a template :::1:out::: /console: template(one: one, two: two) :::1:out::: /console: This is a console page. Don't match the codeframe. :::1:out::: /console: template(one: one, two: two) :::1:out::: /console: This is a console page. Don't match the codeframe.  Cache  :::1:out::: /console: template(one: one, two: two)  Cache  :::1:out::: /console: This is a console page. Don't match the codeframe. :::1:err::: /console: not a template { foo: 'just-some-object' } Error: :::1:err::: /console: test at ConsolePage (app/console/page.tsx::)   40 | })  41 | await 1 > 42 | console.error(new Error(\`\${errBadge} /console: test\`))  | ^  43 | await 1  44 | console.assert(  45 | false, Assertion failed: :::1:err::: /console: This is an assert message with a template :::1:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::1:err::: /console: This is an assert message with a template  Cache  :::1:err::: /console: not a template { foo: 'just-some-object' } Assertion failed:  Cache  :::1:err::: /console: This is an assert message with a template  Cache  Assertion failed: :::1:err::: /console: This is an assert message with a template :::2:out::: /console: template(one: one, two: two) :::2:out::: /console: This is a console page. Don't match the codeframe. :::2:out::: /console: template(one: one, two: two) :::2:out::: /console: This is a console page. Don't match the codeframe.  Cache  :::2:out::: /console: template(one: one, two: two)  Cache  :::2:out::: /console: This is a console page. Don't match the codeframe. :::2:err::: /console: not a template { foo: 'just-some-object' } Error: :::2:err::: /console: test at ConsolePage (app/console/page.tsx::)   40 | })  41 | await 1 > 42 | console.error(new Error(\`\${errBadge} /console: test\`))  | ^  43 | await 1  44 | console.assert(  45 | false, Assertion failed: :::2:err::: /console: This is an assert message with a template :::2:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::2:err::: /console: This is an assert message with a template  Cache  :::2:err::: /console: not a template { foo: 'just-some-object' } Assertion failed:  Cache  :::2:err::: /console: This is an assert message with a template  Cache  Assertion failed: :::2:err::: /console: This is an assert message with a template " `) await expect(browser).toDisplayCollapsedRedbox(` { "description": ":::0:err::: /console: test", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/console/page.tsx (42:17) @ ConsolePage > 42 | console.error(new Error(\`\${errBadge} /console: test\`)) | ^", "stack": [ "ConsolePage app/console/page.tsx (42:17)", "ConsolePage ", ], } `) } else { try { await next.build({ args: ['--debug-build-paths', `app${path}/page.tsx`], }) } catch (err) { const error = new Error( 'Expected build to complete successfully, but it failed' ) error.cause = err throw error } // do not strip ANSI codes here since we're explicitly testing coloring. const cliOutputFromPage = next.cliOutput.match( /Collecting page data[^\n]+\n(.*)\n.*Finalizing page optimization /s )[1] const reorderedLines = reorderLinesByBadge(cliOutputFromPage) if (isTurbopack) { expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console: template(one: one, two: two) :::0:out::: /console: This is a console page. Don't match the codeframe. :::0:out::: /console: template(one: one, two: two) :::0:out::: /console: This is a console page. Don't match the codeframe. :::0:err::: /console: not a template { foo: 'just-some-object' } Error: :::0:err::: /console: test at e (turbopack:///[project]/app/console/page.tsx::)   40 | })  41 | await 1 > 42 | console.error(new Error(\`\${errBadge} /console: test\`))  | ^  43 | await 1  44 | console.assert(  45 | false, Assertion failed: :::0:err::: /console: This is an assert message with a template :::0:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::0:err::: /console: This is an assert message with a template :::1:out::: /console: template(one: one, two: two) :::1:out::: /console: This is a console page. Don't match the codeframe. :::1:out::: /console: template(one: one, two: two) :::1:out::: /console: This is a console page. Don't match the codeframe. :::1:err::: /console: not a template { foo: 'just-some-object' } Error: :::1:err::: /console: test at e (turbopack:///[project]/app/console/page.tsx::)   40 | })  41 | await 1 > 42 | console.error(new Error(\`\${errBadge} /console: test\`))  | ^  43 | await 1  44 | console.assert(  45 | false, Assertion failed: :::1:err::: /console: This is an assert message with a template :::1:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::1:err::: /console: This is an assert message with a template" `) } else { expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console: template(one: one, two: two) :::0:out::: /console: This is a console page. Don't match the codeframe. :::0:out::: /console: template(one: one, two: two) :::0:out::: /console: This is a console page. Don't match the codeframe. :::0:err::: /console: not a template { foo: 'just-some-object' } Error: :::0:err::: /console: test at g (.next/server/app/console/page.js::) Assertion failed: :::0:err::: /console: This is an assert message with a template :::0:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::0:err::: /console: This is an assert message with a template :::1:out::: /console: template(one: one, two: two) :::1:out::: /console: This is a console page. Don't match the codeframe. :::1:out::: /console: template(one: one, two: two) :::1:out::: /console: This is a console page. Don't match the codeframe. :::1:err::: /console: not a template { foo: 'just-some-object' } Error: :::1:err::: /console: test at g (.next/server/app/console/page.js::) Assertion failed: :::1:err::: /console: This is an assert message with a template :::1:err::: /console: not a template { foo: 'just-some-object' } Assertion failed: :::1:err::: /console: This is an assert message with a template" `) } } }) }) // TODO(restart-on-cache-miss): cacheSignal timing changes break console log dimming/hiding tests describe.skip('cache-components - Logging after Abort', () => { describe('(default) With Dimming - Server', () => { const { next, skipped, isTurbopack } = nextTestSetup({ env: { FORCE_COLOR: '1', }, files: __dirname + '/fixtures/default', skipDeployment: true, skipStart: !isNextDev, }) if (skipped) { return } it('dims console calls after a prerender has aborted', async () => { const path: string = '/console-after-abort/server' if (isNextDev) { const browser = await next.browser(path, {}) await retry(() => { expect(stripAnsi(next.cliOutput)).toContain(`GET ${path} 200`) }) // do not strip ANSI codes here since we're explicitly testing coloring. const cliOutputFromPage = next.cliOutput.match( new RegExp(`Compiled ${path}[^\n]+\n(.*)`, 's') )[1] const reorderedLines = reorderLinesByBadge(cliOutputFromPage) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/server: logging before trying await headers() :::0:out::: /console-after-abort/server: template(one: one, two: two) :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::0:out::: /console-after-abort/server: template(one: one, two: two) :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe.  Cache  :::0:out::: /console-after-abort/server: template(one: one, two: two)  Cache  :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/server: test at ConsolePage (app/console-after-abort/server/page.tsx::)   57 | foo: 'just-some-object',  58 | }) > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`))  | ^  60 | console.assert(  61 | false,  62 | \`\${errBadge} /console-after-abort/server: This is an assert message with a %s\`, Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template  Cache  :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Assertion failed:  Cache  :::0:err::: /console-after-abort/server: This is an assert message with a template  Cache  Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template :::1:out::: /console-after-abort/server: logging before trying await headers() :::1:out::: /console-after-abort/server: template(one: one, two: two) :::1:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::1:err::: /console-after-abort/server: caught error trying await headers() :::1:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::1:err::: /console-after-abort/server: test at ConsolePage (app/console-after-abort/server/page.tsx::)   57 | foo: 'just-some-object',  58 | }) > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`))  | ^  60 | console.assert(  61 | false,  62 | \`\${errBadge} /console-after-abort/server: This is an assert message with a %s\`, Assertion failed: :::1:err::: /console-after-abort/server: This is an assert message with a template :::2:out::: /console-after-abort/server: logging before trying await headers() :::2:out::: /console-after-abort/server: template(one: one, two: two) :::2:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::2:err::: /console-after-abort/server: caught error trying await headers() :::2:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::2:err::: /console-after-abort/server: test at ConsolePage (app/console-after-abort/server/page.tsx::)   57 | foo: 'just-some-object',  58 | }) > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`))  | ^  60 | console.assert(  61 | false,  62 | \`\${errBadge} /console-after-abort/server: This is an assert message with a %s\`, Assertion failed: :::2:err::: /console-after-abort/server: This is an assert message with a template " `) await expect(browser).toDisplayCollapsedRedbox(` { "description": ":::0:err::: /console-after-abort/server: test", "environmentLabel": "Server", "label": "Console Error", "source": "app/console-after-abort/server/page.tsx (59:17) @ ConsolePage > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`)) | ^", "stack": [ "ConsolePage app/console-after-abort/server/page.tsx (59:17)", "ConsolePage ", ], } `) } else { try { await next.build({ args: ['--debug-build-paths', `app${path}/page.tsx`], }) } catch (err) { const error = new Error( 'Expected build to complete successfully, but it failed' ) error.cause = err throw error } const unorderedLines = next.cliOutput.match( /Collecting page data[^\n]+\n(.*)\n.*Finalizing page optimization /s )[1] const reorderedLines = reorderLinesByBadge(unorderedLines) if (isTurbopack) { expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/server: logging before trying await headers() :::0:out::: /console-after-abort/server: template(one: one, two: two) :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/server: caught error trying await headers() :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/server: test at g (turbopack:///[project]/app/console-after-abort/server/page.tsx::)   57 | foo: 'just-some-object',  58 | }) > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`))  | ^  60 | console.assert(  61 | false,  62 | \`\${errBadge} /console-after-abort/server: This is an assert message with a %s\`, Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template :::1:out::: /console-after-abort/server: logging before trying await headers() :::1:out::: /console-after-abort/server: template(one: one, two: two) :::1:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::1:err::: /console-after-abort/server: caught error trying await headers() :::1:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::1:err::: /console-after-abort/server: test at g (turbopack:///[project]/app/console-after-abort/server/page.tsx::)   57 | foo: 'just-some-object',  58 | }) > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`))  | ^  60 | console.assert(  61 | false,  62 | \`\${errBadge} /console-after-abort/server: This is an assert message with a %s\`, Assertion failed: :::1:err::: /console-after-abort/server: This is an assert message with a template" `) } else { expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/server: logging before trying await headers() :::0:out::: /console-after-abort/server: template(one: one, two: two) :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/server: caught error trying await headers() :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/server: test at i (.next/server/app/console-after-abort/server/page.js::) Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template :::1:out::: /console-after-abort/server: logging before trying await headers() :::1:out::: /console-after-abort/server: template(one: one, two: two) :::1:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::1:err::: /console-after-abort/server: caught error trying await headers() :::1:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::1:err::: /console-after-abort/server: test at i (.next/server/app/console-after-abort/server/page.js::) Assertion failed: :::1:err::: /console-after-abort/server: This is an assert message with a template" `) } } }) }) describe('(default) With Dimming - Client', () => { const { next, skipped, isTurbopack } = nextTestSetup({ env: { FORCE_COLOR: '1', }, files: __dirname + '/fixtures/default', skipDeployment: true, skipStart: !isNextDev, }) if (skipped) { return } it('dims console calls after a prerender has aborted', async () => { const path: string = '/console-after-abort/client' if (isNextDev) { const browser = await next.browser(path, {}) await retry(() => { expect(stripAnsi(next.cliOutput)).toContain(`GET ${path} 200`) }) // do not strip ANSI codes here since we're explicitly testing coloring. const cliOutputFromPage = next.cliOutput.match( new RegExp(`Compiled ${path}[^\n]+\n(.*)`, 's') )[1] const reorderedLines = reorderLinesByBadge(cliOutputFromPage) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/client: logging before prerender abort :::0:out::: /console-after-abort/client: logging before prerender aborts in client component :::0:out::: /console-after-abort/client: template(one: one, two: two) :::0:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/client: test at log (app/console-after-abort/client/client.tsx::)   15 | foo: 'just-some-object',  16 | }) > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`))  | ^  18 | console.assert(  19 | false,  20 | \`\${errBadge} /console-after-abort/client: This is an assert message with a %s\`, Assertion failed: :::0:err::: /console-after-abort/client: This is an assert message with a template :::1:out::: /console-after-abort/client: logging before prerender abort :::1:out::: /console-after-abort/client: logging before prerender aborts in client component :::1:out::: /console-after-abort/client: template(one: one, two: two) :::1:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::1:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::1:err::: /console-after-abort/client: test at log (app/console-after-abort/client/client.tsx::)   15 | foo: 'just-some-object',  16 | }) > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`))  | ^  18 | console.assert(  19 | false,  20 | \`\${errBadge} /console-after-abort/client: This is an assert message with a %s\`, Assertion failed: :::1:err::: /console-after-abort/client: This is an assert message with a template :::2:out::: /console-after-abort/client: logging before prerender abort :::2:out::: /console-after-abort/client: logging before prerender aborts in client component :::2:out::: /console-after-abort/client: template(one: one, two: two) :::2:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::2:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::2:err::: /console-after-abort/client: test at log (app/console-after-abort/client/client.tsx::)   15 | foo: 'just-some-object',  16 | }) > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`))  | ^  18 | console.assert(  19 | false,  20 | \`\${errBadge} /console-after-abort/client: This is an assert message with a %s\`, Assertion failed: :::2:err::: /console-after-abort/client: This is an assert message with a template " `) await expect(browser).toDisplayCollapsedRedbox(` { "description": ":::0:err::: /console-after-abort/client: test", "environmentLabel": null, "label": "Console Error", "source": "app/console-after-abort/client/client.tsx (17:17) @ log > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`)) | ^", "stack": [ "log app/console-after-abort/client/client.tsx (17:17)", ], } `) } else { try { await next.build({ args: ['--debug-build-paths', `app${path}/page.tsx`], }) } catch (err) { const error = new Error( 'Expected build to complete successfully, but it failed' ) error.cause = err throw error } const unorderedLines = next.cliOutput.match( /Collecting page data[^\n]+\n(.*)\n.*Finalizing page optimization /s )[1] const reorderedLines = reorderLinesByBadge(unorderedLines) if (isTurbopack) { expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/client: logging before prerender abort :::0:out::: /console-after-abort/client: logging before prerender aborts in client component :::0:out::: /console-after-abort/client: template(one: one, two: two) :::0:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/client: test at c (turbopack:///[project]/app/console-after-abort/client/client.tsx::)   15 | foo: 'just-some-object',  16 | }) > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`))  | ^  18 | console.assert(  19 | false,  20 | \`\${errBadge} /console-after-abort/client: This is an assert message with a %s\`, Assertion failed: :::0:err::: /console-after-abort/client: This is an assert message with a template :::1:out::: /console-after-abort/client: logging before prerender abort :::1:out::: /console-after-abort/client: logging before prerender aborts in client component :::1:out::: /console-after-abort/client: template(one: one, two: two) :::1:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::1:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::1:err::: /console-after-abort/client: test at c (turbopack:///[project]/app/console-after-abort/client/client.tsx::)   15 | foo: 'just-some-object',  16 | }) > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`))  | ^  18 | console.assert(  19 | false,  20 | \`\${errBadge} /console-after-abort/client: This is an assert message with a %s\`, Assertion failed: :::1:err::: /console-after-abort/client: This is an assert message with a template" `) } else { expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/client: logging before prerender abort :::0:out::: /console-after-abort/client: logging before prerender aborts in client component :::0:out::: /console-after-abort/client: template(one: one, two: two) :::0:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/client: test at e (.next/server/app/console-after-abort/client/page.js::) Assertion failed: :::0:err::: /console-after-abort/client: This is an assert message with a template :::1:out::: /console-after-abort/client: logging before prerender abort :::1:out::: /console-after-abort/client: logging before prerender aborts in client component :::1:out::: /console-after-abort/client: template(one: one, two: two) :::1:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::1:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::1:err::: /console-after-abort/client: test at e (.next/server/app/console-after-abort/client/page.js::) Assertion failed: :::1:err::: /console-after-abort/client: This is an assert message with a template" `) } } }) }) describe('With Hiding - Server', () => { const { next, skipped } = nextTestSetup({ env: { FORCE_COLOR: '1', }, files: __dirname + '/fixtures/hide-logs-after-abort', skipDeployment: true, skipStart: !isNextDev, }) if (skipped) { return } it('hides console calls after a prerender has aborted', async () => { const path: string = '/console-after-abort/server' if (isNextDev) { const browser = await next.browser(path, {}) await retry(() => { expect(stripAnsi(next.cliOutput)).toContain(`GET ${path} 200`) }) // do not strip ANSI codes here since we're explicitly testing coloring. const cliOutputFromPage = next.cliOutput.match( new RegExp(`Compiled ${path}[^\n]+\n(.*)`, 's') )[1] const reorderedLines = reorderLinesByBadge(cliOutputFromPage) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/server: logging before trying await headers() :::0:out::: /console-after-abort/server: template(one: one, two: two) :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::0:out::: /console-after-abort/server: template(one: one, two: two) :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe.  Cache  :::0:out::: /console-after-abort/server: template(one: one, two: two)  Cache  :::0:out::: /console-after-abort/server: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/server: test at ConsolePage (app/console-after-abort/server/page.tsx::)   57 | foo: 'just-some-object',  58 | }) > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`))  | ^  60 | console.assert(  61 | false,  62 | \`\${errBadge} /console-after-abort/server: This is an assert message with a %s\`, Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template  Cache  :::0:err::: /console-after-abort/server: not a template { foo: 'just-some-object' } Assertion failed:  Cache  :::0:err::: /console-after-abort/server: This is an assert message with a template  Cache  Assertion failed: :::0:err::: /console-after-abort/server: This is an assert message with a template :::1:out::: /console-after-abort/server: logging before trying await headers() :::2:out::: /console-after-abort/server: logging before trying await headers() " `) await expect(browser).toDisplayCollapsedRedbox(` { "description": ":::0:err::: /console-after-abort/server: test", "environmentLabel": "Server", "label": "Console Error", "source": "app/console-after-abort/server/page.tsx (59:17) @ ConsolePage > 59 | console.error(new Error(\`\${errBadge} /console-after-abort/server: test\`)) | ^", "stack": [ "ConsolePage app/console-after-abort/server/page.tsx (59:17)", "ConsolePage ", ], } `) } else { try { await next.build({ args: ['--debug-build-paths', `app${path}/page.tsx`], }) } catch (err) { const error = new Error( 'Expected build to complete successfully, but it failed' ) error.cause = err throw error } const unorderedLines = next.cliOutput.match( /Collecting page data[^\n]+\n(.*)\n.*Finalizing page optimization /s )[1] const reorderedLines = reorderLinesByBadge(unorderedLines) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/server: logging before trying await headers() :::1:out::: /console-after-abort/server: logging before trying await headers()" `) } }) }) describe('With Hiding - Client', () => { const { next, skipped } = nextTestSetup({ env: { FORCE_COLOR: '1', }, files: __dirname + '/fixtures/hide-logs-after-abort', skipDeployment: true, skipStart: !isNextDev, }) if (skipped) { return } it('hides console calls after a prerender has aborted', async () => { const path: string = '/console-after-abort/client' if (isNextDev) { const browser = await next.browser(path, {}) await retry(() => { expect(stripAnsi(next.cliOutput)).toContain(`GET ${path} 200`) }) // do not strip ANSI codes here since we're explicitly testing coloring. const cliOutputFromPage = next.cliOutput.match( new RegExp(`Compiled ${path}[^\n]+\n(.*)`, 's') )[1] const reorderedLines = reorderLinesByBadge(cliOutputFromPage) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/client: logging before prerender abort :::0:out::: /console-after-abort/client: logging before prerender aborts in client component :::0:out::: /console-after-abort/client: template(one: one, two: two) :::0:out::: /console-after-abort/client: This is a console page. Don't match the codeframe. :::0:err::: /console-after-abort/client: not a template { foo: 'just-some-object' } Error: :::0:err::: /console-after-abort/client: test at log (app/console-after-abort/client/client.tsx::)   15 | foo: 'just-some-object',  16 | }) > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`))  | ^  18 | console.assert(  19 | false,  20 | \`\${errBadge} /console-after-abort/client: This is an assert message with a %s\`, Assertion failed: :::0:err::: /console-after-abort/client: This is an assert message with a template :::1:out::: /console-after-abort/client: logging before prerender abort :::1:out::: /console-after-abort/client: logging before prerender aborts in client component :::2:out::: /console-after-abort/client: logging before prerender abort :::2:out::: /console-after-abort/client: logging before prerender aborts in client component " `) await expect(browser).toDisplayCollapsedRedbox(` { "description": ":::0:err::: /console-after-abort/client: test", "environmentLabel": null, "label": "Console Error", "source": "app/console-after-abort/client/client.tsx (17:17) @ log > 17 | console.error(new Error(\`\${errBadge} /console-after-abort/client: test\`)) | ^", "stack": [ "log app/console-after-abort/client/client.tsx (17:17)", ], } `) } else { try { await next.build({ args: ['--debug-build-paths', `app${path}/page.tsx`], }) } catch (err) { const error = new Error( 'Expected build to complete successfully, but it failed' ) error.cause = err throw error } const unorderedLines = next.cliOutput.match( /Collecting page data[^\n]+\n(.*)\n.*Finalizing page optimization /s )[1] const reorderedLines = reorderLinesByBadge(unorderedLines) expect(reorderedLines).toMatchInlineSnapshot(` ":::0:out::: /console-after-abort/client: logging before prerender abort :::0:out::: /console-after-abort/client: logging before prerender aborts in client component :::1:out::: /console-after-abort/client: logging before prerender abort :::1:out::: /console-after-abort/client: logging before prerender aborts in client component" `) } }) }) }) type RenderGroups = Map type StreamGroups = Map type Lines = Array function reorderLinesByBadge(selectedOutput: string) { const unorderedLines = selectedOutput .split('\n') .filter( (l) => !(l.includes('Generating static pages') || l.includes(' GET ')) ) .map((l) => l.replace(/( at .*):\d+:\d+/, '$1::')) let currentLines: Lines = [] const renderGroups: RenderGroups = new Map([ [null, new Map([[null, currentLines]]) satisfies StreamGroups], ]) for (let line of unorderedLines) { let match = line.match(/:::([^: \n]+):([^: \n]+):::/) if (match) { const [_, render, stream] = match const streamGroups = renderGroups.get(render) if (!streamGroups) { currentLines = [] renderGroups.set(render, new Map([[stream, currentLines]])) } else { currentLines = streamGroups.get(stream) if (!currentLines) { streamGroups.set(stream, (currentLines = [])) } } } currentLines.push(line) } const orderedRenders = Array.from(renderGroups.values()) const orderedStreams = orderedRenders.map((s) => Array.from(s.values()).flat() ) return orderedStreams.flat().join('\n') }