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
644 lines
20 KiB
TypeScript
644 lines
20 KiB
TypeScript
import { waitForNoRedbox, check, getDistDir, retry } from 'next-test-utils'
|
||
import stripAnsi from 'strip-ansi'
|
||
import { nextTestSetup } from 'e2e-utils'
|
||
|
||
describe('middleware - development errors', () => {
|
||
const { next, isTurbopack, isRspack } = nextTestSetup({
|
||
files: __dirname,
|
||
patchFileDelay: 500,
|
||
})
|
||
|
||
beforeEach(async () => {
|
||
await next.stop()
|
||
})
|
||
|
||
describe('when middleware throws synchronously', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile(
|
||
'middleware.js',
|
||
`
|
||
export default function () {
|
||
throw new Error('boom')
|
||
}`
|
||
)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
|
||
await retry(() => {
|
||
expect(stripAnsi(next.cliOutput)).toContain('boom')
|
||
})
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
isTurbopack
|
||
? '\n⨯ Error: boom' +
|
||
// TODO(veil): Sourcemap to original name i.e. "default"
|
||
'\n at __TURBOPACK__default__export__ (middleware.js:3:15)' +
|
||
'\n 1 |'
|
||
: isRspack
|
||
? '\n⨯ Error: boom' +
|
||
'\n at __rspack_default_export (middleware.js:3:15)' +
|
||
'\n 1 |'
|
||
: '\n⨯ Error: boom' +
|
||
'\n at default (middleware.js:3:15)' +
|
||
'\n 1 |'
|
||
)
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
'' +
|
||
"\n> 3 | throw new Error('boom')" +
|
||
'\n | ^'
|
||
)
|
||
})
|
||
|
||
it('renders the error correctly and recovers', async () => {
|
||
const browser = await next.browser('/')
|
||
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "boom",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": "middleware.js (3:15) @ {default export}
|
||
> 3 | throw new Error('boom')
|
||
| ^",
|
||
"stack": [
|
||
"{default export} middleware.js (3:15)",
|
||
],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "boom",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": "middleware.js (3:15) @ __rspack_default_export
|
||
> 3 | throw new Error('boom')
|
||
| ^",
|
||
"stack": [
|
||
"__rspack_default_export middleware.js (3:15)",
|
||
],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "boom",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": "middleware.js (3:15) @ default
|
||
> 3 | throw new Error('boom')
|
||
| ^",
|
||
"stack": [
|
||
"default middleware.js (3:15)",
|
||
],
|
||
}
|
||
`)
|
||
}
|
||
|
||
await next.patchFile('middleware.js', `export default function () {}`)
|
||
|
||
await waitForNoRedbox(browser)
|
||
})
|
||
})
|
||
|
||
describe('when middleware contains an unhandled rejection', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile(
|
||
'middleware.js',
|
||
`
|
||
import { NextResponse } from 'next/server'
|
||
async function throwError() {
|
||
throw new Error('async boom!')
|
||
}
|
||
export default function () {
|
||
throwError()
|
||
return NextResponse.next()
|
||
}`
|
||
)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
|
||
await retry(() => {
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
'unhandledRejection: Error: async boom!'
|
||
)
|
||
})
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
isTurbopack
|
||
? '⨯ unhandledRejection: Error: async boom!' +
|
||
'\n at throwError (middleware.js:4:15)' +
|
||
// TODO(veil): Sourcemap to original name i.e. "default"
|
||
'\n at __TURBOPACK__default__export__ (middleware.js:7:9)' +
|
||
"\n 2 | import { NextResponse } from 'next/server'"
|
||
: isRspack
|
||
? '\n⨯ unhandledRejection: Error: async boom!' +
|
||
'\n at throwError (middleware.js:4:15)' +
|
||
'\n at __rspack_default_export (middleware.js:7:9)' +
|
||
"\n 2 | import { NextResponse } from 'next/server'"
|
||
: '\n⨯ unhandledRejection: Error: async boom!' +
|
||
'\n at throwError (middleware.js:4:15)' +
|
||
'\n at default (middleware.js:7:9)' +
|
||
"\n 2 | import { NextResponse } from 'next/server'"
|
||
)
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
'' +
|
||
"\n> 4 | throw new Error('async boom!')" +
|
||
'\n | ^'
|
||
)
|
||
})
|
||
|
||
it('does not render the error', async () => {
|
||
const browser = await next.browser('/')
|
||
await waitForNoRedbox(browser)
|
||
expect(await browser.elementByCss('#page-title')).toBeTruthy()
|
||
})
|
||
})
|
||
|
||
describe('when running invalid dynamic code with eval', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile(
|
||
'middleware.js',
|
||
`
|
||
import { NextResponse } from 'next/server'
|
||
export default function () {
|
||
eval('test')
|
||
return NextResponse.next()
|
||
}`
|
||
)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
|
||
await retry(() => {
|
||
expect(stripAnsi(next.cliOutput)).toContain('Dynamic Code Evaluation')
|
||
})
|
||
if (isTurbopack) {
|
||
// Locally, prefixes the "test is not defined".
|
||
// In CI, it prefixes "Dynamic Code Evaluation".
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
// TODO(veil): Should be sourcemapped
|
||
'\n at __TURBOPACK__default__export__ (.next/'
|
||
)
|
||
}
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
isTurbopack
|
||
? '\n⨯ Error [ReferenceError]: test is not defined' +
|
||
'\n at eval (middleware.js:4:9)' +
|
||
'\n at <unknown> (middleware.js:4:9)' +
|
||
// TODO(veil): Should be sourcemapped
|
||
'\n at __TURBOPACK__default__export__ ('
|
||
: '\n⨯ Error [ReferenceError]: test is not defined' +
|
||
// TODO(veil): Redundant and not clickable
|
||
'\n at eval (file://webpack-internal:///(middleware)/./middleware.js)' +
|
||
'\n at eval (middleware.js:4:9)' +
|
||
'\n at default (middleware.js:4:9)' +
|
||
"\n 2 | import { NextResponse } from 'next/server'"
|
||
)
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
isTurbopack
|
||
? "\n⚠ DynamicCodeEvaluationWarning: Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime" +
|
||
'\nLearn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation' +
|
||
// TODO(veil): Should be sourcemapped
|
||
'\n at __TURBOPACK__default__export__ ('
|
||
: "\n⚠ DynamicCodeEvaluationWarning: Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime" +
|
||
'\nLearn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation' +
|
||
'\n at default (middleware.js:4:9)' +
|
||
"\n 2 | import { NextResponse } from 'next/server'"
|
||
)
|
||
})
|
||
|
||
it('renders the error correctly and recovers', async () => {
|
||
const browser = await next.browser('/')
|
||
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "test is not defined",
|
||
"environmentLabel": null,
|
||
"label": "Runtime ReferenceError",
|
||
"source": "middleware.js (4:9) @ eval
|
||
> 4 | eval('test')
|
||
| ^",
|
||
"stack": [
|
||
"eval middleware.js (4:9)",
|
||
"<unknown> middleware.js (4:9)",
|
||
"{default export} middleware.js (3:22)",
|
||
],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "test is not defined",
|
||
"environmentLabel": null,
|
||
"label": "Runtime ReferenceError",
|
||
"source": "middleware.js (4:9) @ __rspack_default_export
|
||
> 4 | eval('test')
|
||
| ^",
|
||
"stack": [
|
||
"<FIXME-file-protocol>",
|
||
"__rspack_default_export middleware.js (4:9)",
|
||
],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "test is not defined",
|
||
"environmentLabel": null,
|
||
"label": "Runtime ReferenceError",
|
||
"source": "middleware.js (4:9) @ eval
|
||
> 4 | eval('test')
|
||
| ^",
|
||
"stack": [
|
||
"<FIXME-file-protocol>",
|
||
"eval middleware.js (4:9)",
|
||
"default middleware.js (4:9)",
|
||
],
|
||
}
|
||
`)
|
||
}
|
||
|
||
const lengthOfLogs = next.cliOutput.length
|
||
await next.patchFile('middleware.js', `export default function () {}`)
|
||
|
||
retry(() => {
|
||
expect(next.cliOutput.slice(lengthOfLogs)).toContain('GET / 200')
|
||
}, 10000) // middleware rebuild takes a while in CI
|
||
|
||
await waitForNoRedbox(browser)
|
||
})
|
||
})
|
||
|
||
describe('when throwing while loading the module', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile(
|
||
'middleware.js',
|
||
`
|
||
import { NextResponse } from 'next/server'
|
||
throw new Error('booooom!')
|
||
export default function () {
|
||
return NextResponse.next()
|
||
}`
|
||
)
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
|
||
await retry(() => {
|
||
expect(stripAnsi(next.cliOutput)).toContain(`Error: booooom!`)
|
||
})
|
||
expect(stripAnsi(next.cliOutput)).toContain(
|
||
isTurbopack
|
||
? '\n⨯ Error: booooom!' +
|
||
// TODO(veil): Should be sourcemapped
|
||
'\n at module evaluation (middleware.js:3:13)'
|
||
: isRspack
|
||
? '\n⨯ Error: booooom!' +
|
||
`\n at <unknown> (${getDistDir()}/server/edge-runtime-webpack.js:35)` +
|
||
'\n at eval (middleware.js:3:13)' +
|
||
`\n at (middleware)/./middleware.js (${getDistDir()}/server/middleware.js:26:1)` +
|
||
'\n at __webpack_require__ '
|
||
: '\n⨯ Error: booooom!' +
|
||
// TODO: Should be anonymous method without a method name
|
||
'\n at <unknown> (middleware.js:3)' +
|
||
// TODO: Should be ignore-listed
|
||
'\n at eval (middleware.js:3:13)' +
|
||
`\n at (middleware)/./middleware.js (${getDistDir()}/server/middleware.js:18:1)` +
|
||
'\n at __webpack_require__ '
|
||
)
|
||
})
|
||
|
||
it('renders the error correctly and recovers', async () => {
|
||
const browser = await next.browser('/')
|
||
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "booooom!",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": "middleware.js (3:13) @ module evaluation
|
||
> 3 | throw new Error('booooom!')
|
||
| ^",
|
||
"stack": [
|
||
"module evaluation middleware.js (3:13)",
|
||
],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "booooom!",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": "middleware.js (3:13) @ eval
|
||
> 3 | throw new Error('booooom!')
|
||
| ^",
|
||
"stack": [
|
||
"<FIXME-next-dist-dir>",
|
||
"eval middleware.js (3:13)",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"code": "E394",
|
||
"description": "booooom!",
|
||
"environmentLabel": null,
|
||
"label": "Runtime Error",
|
||
"source": "middleware.js (3:13) @ eval
|
||
> 3 | throw new Error('booooom!')
|
||
| ^",
|
||
"stack": [
|
||
"<unknown> middleware.js (3)",
|
||
"eval middleware.js (3:13)",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
"<FIXME-next-dist-dir>",
|
||
],
|
||
}
|
||
`)
|
||
}
|
||
|
||
await next.patchFile('middleware.js', `export default function () {}`)
|
||
|
||
await waitForNoRedbox(browser)
|
||
})
|
||
})
|
||
|
||
describe('when there is an unhandled rejection while loading the module', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile(
|
||
'middleware.js',
|
||
`
|
||
import { NextResponse } from 'next/server'
|
||
(async function(){
|
||
throw new Error('you shall see me')
|
||
})()
|
||
|
||
export default function () {
|
||
return NextResponse.next()
|
||
}`
|
||
)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
await check(
|
||
() => stripAnsi(next.cliOutput),
|
||
new RegExp(`unhandledRejection: Error: you shall see me`, 'm')
|
||
)
|
||
// expect(output).not.toContain(
|
||
// 'webpack-internal:///(middleware)/./middleware.js'
|
||
// )
|
||
})
|
||
|
||
it('does not render the error', async () => {
|
||
const browser = await next.browser('/')
|
||
await waitForNoRedbox(browser)
|
||
expect(await browser.elementByCss('#page-title')).toBeTruthy()
|
||
})
|
||
})
|
||
|
||
describe('when there is an unhandled rejection while loading a dependency', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile(
|
||
'middleware.js',
|
||
`
|
||
import { NextResponse } from 'next/server'
|
||
import './lib/unhandled'
|
||
|
||
export default function () {
|
||
return NextResponse.next()
|
||
}`
|
||
)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
const output = stripAnsi(next.cliOutput)
|
||
await check(
|
||
() => stripAnsi(next.cliOutput),
|
||
new RegExp(
|
||
` uncaughtException: Error: This file asynchronously fails while loading`,
|
||
'm'
|
||
)
|
||
)
|
||
expect(output).not.toContain(
|
||
'webpack-internal:///(middleware)/./middleware.js'
|
||
)
|
||
})
|
||
|
||
it('does not render the error', async () => {
|
||
const browser = await next.browser('/')
|
||
await waitForNoRedbox(browser)
|
||
expect(await browser.elementByCss('#page-title')).toBeTruthy()
|
||
})
|
||
})
|
||
|
||
describe('when there is a compilation error from boot', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile('middleware.js', `export default function () }`)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.fetch('/')
|
||
await check(async () => {
|
||
expect(next.cliOutput).toContain(`Expected '{', got '}'`)
|
||
expect(
|
||
next.cliOutput.split(`Expected '{', got '}'`).length
|
||
).toBeGreaterThanOrEqual(2)
|
||
|
||
return 'success'
|
||
}, 'success')
|
||
})
|
||
|
||
it('renders the error correctly and recovers', async () => {
|
||
const browser = await next.browser('/')
|
||
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "Expected '{', got '}'",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./middleware.js (1:28)
|
||
Expected '{', got '}'
|
||
> 1 | export default function () }
|
||
| ^",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": " ╰─▶ × Error: x Expected '{', got '}'",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./middleware.js
|
||
╰─▶ × Error: x Expected '{', got '}'
|
||
│ ,----
|
||
│ 1 | export default function () }
|
||
│ : ^
|
||
│ \`----
|
||
│
|
||
│
|
||
│ Caused by:
|
||
│ Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": " x Expected '{', got '}'",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./middleware.js
|
||
Error: x Expected '{', got '}'
|
||
,----
|
||
1 | export default function () }
|
||
: ^
|
||
\`----
|
||
Caused by:
|
||
Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
}
|
||
|
||
await next.patchFile('middleware.js', `export default function () {}`)
|
||
|
||
await waitForNoRedbox(browser)
|
||
expect(await browser.elementByCss('#page-title')).toBeTruthy()
|
||
})
|
||
})
|
||
|
||
describe('when there is a compilation error after boot', () => {
|
||
beforeEach(async () => {
|
||
await next.patchFile('middleware.js', `export default function () {}`)
|
||
|
||
await next.start()
|
||
})
|
||
|
||
it('logs the error correctly', async () => {
|
||
await next.patchFile('middleware.js', `export default function () }`)
|
||
await next.fetch('/')
|
||
|
||
await check(() => {
|
||
expect(next.cliOutput).toContain(`Expected '{', got '}'`)
|
||
expect(
|
||
next.cliOutput.split(`Expected '{', got '}'`).length
|
||
).toBeGreaterThanOrEqual(2)
|
||
return 'success'
|
||
}, 'success')
|
||
})
|
||
|
||
it('renders the error correctly and recovers', async () => {
|
||
const browser = await next.browser('/')
|
||
|
||
await waitForNoRedbox(browser)
|
||
|
||
await next.patchFile('middleware.js', `export default function () }`)
|
||
|
||
if (isTurbopack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "Expected '{', got '}'",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./middleware.js (1:28)
|
||
Expected '{', got '}'
|
||
> 1 | export default function () }
|
||
| ^",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else if (isRspack) {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": " ╰─▶ × Error: x Expected '{', got '}'",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./middleware.js
|
||
╰─▶ × Error: x Expected '{', got '}'
|
||
│ ,----
|
||
│ 1 | export default function () }
|
||
│ : ^
|
||
│ \`----
|
||
│
|
||
│
|
||
│ Caused by:
|
||
│ Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
} else {
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": " x Expected '{', got '}'",
|
||
"environmentLabel": null,
|
||
"label": "Build Error",
|
||
"source": "./middleware.js
|
||
Error: x Expected '{', got '}'
|
||
,----
|
||
1 | export default function () }
|
||
: ^
|
||
\`----
|
||
Caused by:
|
||
Syntax Error",
|
||
"stack": [],
|
||
}
|
||
`)
|
||
}
|
||
|
||
await next.patchFile('middleware.js', `export default function () {}`)
|
||
|
||
await waitForNoRedbox(browser)
|
||
expect(await browser.elementByCss('#page-title')).toBeTruthy()
|
||
})
|
||
})
|
||
})
|