first commit
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled

This commit is contained in:
Arian Tron
2026-03-10 19:37:31 +03:30
commit 61f56f997c
27684 changed files with 2784175 additions and 0 deletions

View File

@@ -0,0 +1,791 @@
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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
  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 <anonymous>",
],
}
`)
} 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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
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:<line>:<col>)
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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
  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 <anonymous>",
],
}
`)
} 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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
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:<line>:<col>)
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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
  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:<line>:<col>)
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:<line>:<col>)
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:<line>:<col>)
  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 <anonymous>",
],
}
`)
} 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:<line>:<col>)
  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<string | null, StreamGroups>
type StreamGroups = Map<string | null, Lines>
type Lines = Array<string>
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:<line>:<col>'))
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')
}