Replace hasRedbox() (#67025)

...with `assertHasRedbox` and `assertNoRedbox`.

`hasRedbox()` has a hardcoded timeout of 5s that is only required for
the negative assertion.
Instead, we now have dedicated assertions for the positive
(`assertHasRedbox`) and negative case (`assertNoRedbox`).
The negative assertion still has the hardcoded timeout.
But the positive assertion just retries until we find the Redbox.

This speeds up tests using the positive assertion.
Removing `hasRedbox` also uncovered some unused expressions e.g. `await
hasRedbox(browser)`.
These expressions probably wanted to use `expect(await
hasRedbox(browser)).toBe(true)
This commit is contained in:
Sebastian Silbermann 2024-06-20 10:37:32 +02:00 committed by GitHub
parent 503fa921ab
commit fe8d953e2d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
87 changed files with 608 additions and 555 deletions

View file

@ -45,7 +45,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.env.TURBOPACK) {
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./node_modules/my-package/index.js:1:13
@ -92,7 +92,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
if (process.env.TURBOPACK) {
@ -145,7 +145,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
if (process.env.TURBOPACK) {
@ -195,7 +195,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
if (process.env.TURBOPACK) {
@ -234,7 +234,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.documentElement.innerHTML)
).toContain('index page')

View file

@ -33,17 +33,17 @@ describe.skip('ReactRefreshLogBox scss app', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Syntax error
await session.patch('index.module.scss', `.button { font-size: :5px; }`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source).toMatchSnapshot()
// Fix syntax error
await session.patch('index.module.scss', `.button { font-size: 5px; }`)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -69,7 +69,7 @@ describe.skip('ReactRefreshLogBox scss app', () => {
// Checks for selectors that can't be prefixed.
// Selector "button" is not pure (pure selectors must contain at least one local class or id)
await session.patch('index.module.scss', `button { font-size: 5px; }`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source2 = await session.getRedboxSource()
expect(source2).toMatchSnapshot()

View file

@ -5,14 +5,13 @@ import {
check,
describeVariants as describe,
expandCallStack,
retry,
} from 'next-test-utils'
import path from 'path'
import { outdent } from 'outdent'
const IS_TURBOPACK = Boolean(process.env.TURBOPACK)
describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
const { next } = nextTestSetup({
const { next, isTurbopack } = nextTestSetup({
files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')),
skipStart: true,
})
@ -85,7 +84,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.platform === 'win32') {
expect(await session.getRedboxSource()).toMatchSnapshot()
} else {
@ -175,7 +174,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// We internally only check the script path, not including the line number
// and error message because the error comes from an external library.
// This test ensures that the errored script path is correctly resolved.
@ -202,7 +201,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -217,23 +216,24 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
console.log({ isTurbopack })
const source = next.normalizeTestDirContent(await session.getRedboxSource())
if (IS_TURBOPACK) {
expect(source).toMatchInlineSnapshot(`
"./index.js:7:1
if (isTurbopack) {
expect(source).toEqual(outdent`
./index.js:7:1
Parsing ecmascript source code failed
5 | div
6 | )
> 7 | }
| ^
Unexpected token. Did you mean \`{'}'}\` or \`}\`?"
Unexpected token. Did you mean \`{'}'}\` or \`}\`?
`)
} else {
expect(source).toMatchInlineSnapshot(`
"./index.js
expect(source).toEqual(outdent`
./index.js
Error:
x Unexpected token. Did you mean \`{'}'}\` or \`}\`?
,-[TEST_DIR/index.js:4:1]
@ -257,7 +257,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
Import trace for requested module:
./index.js
./app/page.js"
./app/page.js
`)
}
@ -292,7 +292,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('hello')
@ -309,7 +309,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
await session.patch(
@ -324,7 +324,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('hello new')
@ -350,26 +350,26 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Syntax error
await session.patch('index.module.css', `.button`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source).toMatch(
IS_TURBOPACK ? './index.module.css:1:9' : './index.module.css:1:1'
isTurbopack ? './index.module.css:1:9' : './index.module.css:1:1'
)
if (!IS_TURBOPACK) {
if (!isTurbopack) {
expect(source).toMatch('Syntax error: ')
expect(source).toMatch('Unknown word')
}
expect(source).toMatch('> 1 | .button')
expect(source).toMatch(IS_TURBOPACK ? ' | ^' : ' | ^')
expect(source).toMatch(isTurbopack ? ' | ^' : ' | ^')
// Checks for selectors that can't be prefixed.
// Selector "button" is not pure (pure selectors must contain at least one local class or id)
await session.patch('index.module.css', `button {}`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source2 = await session.getRedboxSource()
expect(source2).toMatchSnapshot()
@ -536,8 +536,8 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
await session.waitForAndOpenRuntimeError()
const header4 = await session.getRedboxDescription()
expect(header4).toMatchInlineSnapshot(
`"Error: multiple https://nextjs.org links http://example.com"`
expect(header4).toEqual(
`Error: multiple https://nextjs.org links http://example.com`
)
// Do not highlight example.com but do highlight nextjs.org
expect(
@ -593,9 +593,9 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: {"a":1,"b":"x"}"`
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toEqual(
`Error: {"a":1,"b":"x"}`
)
// fix previous error
@ -609,7 +609,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
outdent`
@ -623,7 +623,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toContain(
`Error: class Hello {`
)
@ -639,7 +639,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
outdent`
@ -651,10 +651,8 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: string error"`
)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toEqual(`Error: string error`)
// fix previous error
await session.patch(
@ -667,7 +665,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
outdent`
@ -679,7 +677,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toContain(
`Error: A null error was thrown`
)
@ -703,7 +701,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
await cleanup()
@ -764,7 +762,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
() => browser.elementByCss('.nextjs-toast-errors').text(),
/4 errors/
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Add Component error
await session.patch(
@ -776,7 +774,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
)
// Render error should "win" and show up in fullscreen
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await cleanup()
})
@ -815,7 +813,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
])('Call stack count is correct for %s error', async (_, fixture) => {
const { session, browser, cleanup } = await sandbox(next, fixture)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await expandCallStack(browser)
@ -856,7 +854,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await expandCallStack(browser)
let callStackFrames = await browser.elementsByCss(
'[data-nextjs-call-stack-frame]'
@ -884,7 +882,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await expandCallStack(browser)
// Should still show the errored line in source code
@ -919,7 +917,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// Remove error
await session.patch(
@ -933,7 +931,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
expect(await browser.waitForElementByCss('#text').text()).toBe(
'Hello world'
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Re-add error
await session.patch(
@ -946,7 +944,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await cleanup()
})
@ -974,7 +972,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
await cleanup()
@ -1005,8 +1003,32 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
expect(await session.getRedboxSource()).toMatchSnapshot()
// Wait for patch to apply and new error to show.
await session.assertHasRedbox()
if (isTurbopack) {
await retry(async () => {
expect(await session.getRedboxSource()).toEqual(outdent`
./app/styles2.css:1:2
Module not found: Can't resolve './boom.css'
> 1 | @import "./boom.css"
| ^
https://nextjs.org/docs/messages/module-not-found
`)
})
} else {
await retry(async () => {
expect(await session.getRedboxSource()).toEqual(outdent`
./app/styles2.css
Module not found: Can't resolve './boom.css'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./app/styles1.css
`)
})
}
await cleanup()
})
@ -1017,12 +1039,12 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => {
const { session, cleanup } = await sandbox(next, undefined, '/' + type)
await next.patchFile('index.js', "throw new Error('module error')")
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await next.patchFile(
'index.js',
'export default function Page() {return <p>hello world</p>}'
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})

View file

@ -30,7 +30,7 @@ describe.skip('ReactRefreshLogBox app', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: Multiple children were passed to <Link> with \`href\` of \`/\` but only one child is supported https://nextjs.org/docs/messages/link-multiple-children"`
)
@ -64,7 +64,7 @@ describe.skip('ReactRefreshLogBox app', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: Failed prop type: The prop \`href\` expects a \`string\` or \`object\` in \`<Link>\`, but got \`undefined\` instead."`
)
@ -79,7 +79,7 @@ describe.skip('ReactRefreshLogBox app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -103,7 +103,7 @@ describe.skip('ReactRefreshLogBox app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -127,7 +127,7 @@ describe.skip('ReactRefreshLogBox app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -151,7 +151,7 @@ describe.skip('ReactRefreshLogBox app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -175,7 +175,7 @@ describe.skip('ReactRefreshLogBox app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchSnapshot()
await session.patch(
@ -200,7 +200,7 @@ describe.skip('ReactRefreshLogBox app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchSnapshot()
await cleanup()
@ -227,7 +227,7 @@ describe.skip('ReactRefreshLogBox app', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await cleanup()
})
})

View file

@ -11,7 +11,7 @@ describe('ReactRefreshModule app', () => {
it('should allow any variable names', async () => {
const { session, cleanup } = await sandbox(next, new Map([]))
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
const variables = [
'_a',
@ -33,7 +33,7 @@ describe('ReactRefreshModule app', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(next.cliOutput).not.toContain(
`'${variable}' has already been declared`
)

View file

@ -74,7 +74,7 @@ describe('ReactRefreshRegression app', () => {
)
// Verify no hydration mismatch:
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -279,7 +279,7 @@ describe('ReactRefreshRegression app', () => {
`export default function () { throw new Error('boom'); }`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(`
@ -298,7 +298,7 @@ describe('ReactRefreshRegression app', () => {
`export default function Page() { throw new Error('boom'); }`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(`
@ -320,7 +320,7 @@ describe('ReactRefreshRegression app', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(`
@ -371,7 +371,7 @@ describe('ReactRefreshRegression app', () => {
let didNotReload = await session.patch('app/content.mdx', `Hello Foo!`)
expect(didNotReload).toBe(true)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(
() => document.querySelector('#content').textContent
@ -380,7 +380,7 @@ describe('ReactRefreshRegression app', () => {
didNotReload = await session.patch('app/content.mdx', `Hello Bar!`)
expect(didNotReload).toBe(true)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(
() => document.querySelector('#content').textContent

View file

@ -1,15 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ReactRefreshLogBox app default Can't resolve @import in CSS file 1`] = `
"./app/styles2.css
Module not found: Can't resolve './boom.css'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./app/styles1.css"
`;
exports[`ReactRefreshLogBox app default Import trace when module not found in layout 1`] = `
"./app/module.js:1:1
Module not found: Can't resolve 'non-existing-module'
@ -72,7 +62,7 @@ exports[`ReactRefreshLogBox app default logbox: anchors links in error messages
exports[`ReactRefreshLogBox app default logbox: anchors links in error messages 6`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app default logbox: anchors links in error messages 8`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app default logbox: anchors links in error messages 7`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app default module init error not shown 1`] = `
"index.js (3:7) @ eval
@ -98,15 +88,6 @@ exports[`ReactRefreshLogBox app default should strip whitespace correctly with n
10 | </a>"
`;
exports[`ReactRefreshLogBox app turbo Can't resolve @import in CSS file 1`] = `
"./app/styles2.css:1:2
Module not found: Can't resolve './boom.css'
> 1 | @import "./boom.css"
| ^
https://nextjs.org/docs/messages/module-not-found"
`;
exports[`ReactRefreshLogBox app turbo Import trace when module not found in layout 1`] = `
"./app/module.js:1:1
Module not found: Can't resolve 'non-existing-module'
@ -164,7 +145,7 @@ exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 5`
exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 6`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 8`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app turbo logbox: anchors links in error messages 7`] = `"https://nextjs.org/"`;
exports[`ReactRefreshLogBox app turbo module init error not shown 1`] = `
"index.js (3:7) @ <unknown>

View file

@ -51,12 +51,12 @@ describe('Error overlay - RSC build errors', () => {
await session.patch(pagePath, break2.replace('break 3', '<Hello />'))
await session.patch(pagePath, break2)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await session.patch(pagePath, break1)
await session.patch(pagePath, originalPage)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
}
expect(

View file

@ -30,7 +30,7 @@ describe('dynamic = "error" in devmode', () => {
`
)
await session.hasRedbox()
await session.assertHasRedbox()
console.log(await session.getRedboxDescription())
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: Route /server with \`dynamic = "error"\` couldn't be rendered statically because it used \`cookies\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering"`

View file

@ -65,7 +65,7 @@ describe('Error overlay - editor links', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await clickSourceFile(browser)
await check(() => editorRequestsCount, /1/)
@ -110,7 +110,7 @@ describe('Error overlay - editor links', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await clickImportTraceFiles(browser)
await check(() => editorRequestsCount, /4/)
@ -153,7 +153,7 @@ describe('Error overlay - editor links', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await clickImportTraceFiles(browser)
await check(() => editorRequestsCount, /3/)

View file

@ -19,7 +19,7 @@ describe('Error overlay - error message urls', () => {
content + '\nexport function getServerSideProps() {}'
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const link = await browser.elementByCss('[data-nextjs-terminal] a')
const text = await link.text()

View file

@ -39,7 +39,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
await session.patch('index.js', `export default () => <div/`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'export default () => <div/'
)
@ -62,7 +62,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await check(
() => session.evaluate(() => document.querySelector('p').textContent),
@ -89,7 +89,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
return <p>Hello world</p>
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// Fix syntax error
await session.patch(
@ -170,7 +170,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(await session.hasErrorToast()).toBe(false)
expect(
@ -181,7 +181,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('Count: 2')
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(await session.hasErrorToast()).toBe(false)
await cleanup()
@ -232,7 +232,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'export default function Child()'
)
@ -249,7 +249,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
// TODO-APP: re-enable when error recovery doesn't reload the page.
// expect(didNotReload).toBe(true)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('Hello')
@ -310,14 +310,14 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
)
await new Promise((resolve) => setTimeout(resolve, 1000))
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
"Expected '}', got '<eof>'"
)
// Test that runtime error does not take over:
await new Promise((resolve) => setTimeout(resolve, 2000))
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
"Expected '}', got '<eof>'"
)
@ -368,7 +368,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
)
// We get an error because Foo didn't import React. Fair.
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
"return React.createElement('h1', null, 'Foo');"
)
@ -385,7 +385,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
)
// Expected: this fixes the problem
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -428,7 +428,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
export default ClassDefault;
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// Now change the code to introduce a runtime error without fixing the syntax error:
await session.patch(
@ -446,7 +446,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
export default ClassDefault;
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// Now fix the syntax error:
await session.patch(
@ -464,7 +464,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
export default ClassDefault;
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(async () => {
const source = await session.getRedboxSource()
@ -484,7 +484,7 @@ describe.each(['default', 'turbo'])('Error recovery app %s', () => {
new Map([['app/page.js', '{{{']])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(() => session.getRedboxSource(true), /Failed to compile/)
await cleanup()

View file

@ -83,7 +83,7 @@ describe('Error overlay for hydration errors', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(await browser.elementByCss('.child').text()).toBe('Value')
@ -336,7 +336,7 @@ describe('Error overlay for hydration errors', () => {
)
await session.waitForAndOpenRuntimeError()
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await getRedboxTotalErrorCount(browser)).toBe(1)
@ -396,7 +396,7 @@ describe('Error overlay for hydration errors', () => {
)
await session.waitForAndOpenRuntimeError()
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await getRedboxTotalErrorCount(browser)).toBe(1)
@ -451,7 +451,7 @@ describe('Error overlay for hydration errors', () => {
)
await session.waitForAndOpenRuntimeError()
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const description = await session.getRedboxDescription()
expect(description).toContain(
@ -523,7 +523,7 @@ describe('Error overlay for hydration errors', () => {
)
await session.waitForAndOpenRuntimeError()
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await cleanup()
})
@ -569,7 +569,7 @@ describe('Error overlay for hydration errors', () => {
)
await session.waitForAndOpenRuntimeError()
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const pseudoHtml = await session.getRedboxComponentStack()
if (isTurbopack) {

View file

@ -63,7 +63,7 @@ describe('Error Overlay invalid imports', () => {
const withoutUseClient = content.replace("'use client'", '')
await session.patch(pageFile, withoutUseClient)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.env.TURBOPACK) {
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./app
@ -147,7 +147,7 @@ describe('Error Overlay invalid imports', () => {
const withoutUseClient = content.replace("'use client'", '')
await session.patch(pageFile, withoutUseClient)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.env.TURBOPACK) {
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./node_modules/client-only-package
@ -229,7 +229,7 @@ describe('Error Overlay invalid imports', () => {
const content = await next.readFile(file)
await session.patch(file, "'use client'\n" + content)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.env.TURBOPACK) {
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./node_modules/server-only-package

View file

@ -25,7 +25,7 @@ describe('Error overlay - RSC build errors', () => {
)
await session.patch(pageFile, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'"getServerSideProps" is not supported in app/'
)
@ -49,14 +49,14 @@ describe('Error overlay - RSC build errors', () => {
'export const metadata'
)
await session.patch(pageFile, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'You are attempting to export "metadata" from a component marked with "use client", which is disallowed.'
)
// Restore file
await session.patch(pageFile, content)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Add `generateMetadata` error
uncomment = content.replace(
@ -64,14 +64,14 @@ describe('Error overlay - RSC build errors', () => {
'export async function generateMetadata'
)
await session.patch(pageFile, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'You are attempting to export "generateMetadata" from a component marked with "use client", which is disallowed.'
)
// Fix the error again to test error overlay works with hmr rebuild
await session.patch(pageFile, content)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -91,7 +91,7 @@ describe('Error overlay - RSC build errors', () => {
)
await session.patch(pageFile, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'"metadata" and "generateMetadata" cannot be exported at the same time, please keep one of them.'
)
@ -116,7 +116,7 @@ describe('Error overlay - RSC build errors', () => {
await session.patch(pageFile, uncomment)
await next.patchFile(pageFile, content)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'"getStaticProps" is not supported in app/'
)
@ -136,7 +136,7 @@ describe('Error overlay - RSC build errors', () => {
'export const a = 123'
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toInclude(
'The default export is not a React Component in page: "/server-with-errors/page-export"'
)
@ -151,7 +151,7 @@ describe('Error overlay - RSC build errors', () => {
'/server-with-errors/page-export-initial-error'
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toInclude(
'The default export is not a React Component in page: "/server-with-errors/page-export-initial-error"'
)
@ -171,7 +171,7 @@ describe('Error overlay - RSC build errors', () => {
const uncomment = content.replace("// 'use client'", "'use client'")
await next.patchFile(pageFile, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'directive must be placed before other expressions'
)
@ -194,7 +194,7 @@ describe('Error overlay - RSC build errors', () => {
)
await session.patch(pageFile, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
`Youre importing a class component. It only works in a Client Component`
)
@ -218,7 +218,7 @@ describe('Error overlay - RSC build errors', () => {
)
await next.patchFile(file, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (isTurbopack) {
// TODO: fix the issue ordering.
// turbopack emits the resolve issue first instead of the transform issue.
@ -268,7 +268,7 @@ describe('Error overlay - RSC build errors', () => {
`/server-with-errors/react-apis/${api.toLowerCase()}`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
// `Component` has a custom error message
api === 'Component'
@ -294,7 +294,7 @@ describe('Error overlay - RSC build errors', () => {
`/server-with-errors/react-dom-apis/${api.toLowerCase()}`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
`You're importing a component that needs \`${api}\`. This React hook only works in a client component. To fix, mark the file (or its parent) with the \`"use client"\` directive.`
)
@ -320,7 +320,7 @@ describe('Error overlay - RSC build errors', () => {
await session.patch(file, uncomment)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
`You're importing a component that needs "server-only". That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.`
)
@ -342,7 +342,7 @@ describe('Error overlay - RSC build errors', () => {
content.replace('() => <p>hello dynamic world</p>', 'undefined')
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toInclude(
`Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function.`
)
@ -363,7 +363,7 @@ describe('Error overlay - RSC build errors', () => {
'export default function Error() {}'
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(
() => session.getRedboxSource(),
/must be a Client \n| Component/
@ -412,7 +412,7 @@ describe('Error overlay - RSC build errors', () => {
// Empty file
await session.patch('app/server-with-errors/error-file/error.js', '')
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(() => session.getRedboxSource(), /must be a Client Component/)
// TODO: investigate flakey snapshot due to spacing below
@ -459,10 +459,7 @@ describe('Error overlay - RSC build errors', () => {
await session.patch(pagePath, content)
await check(
async () => ((await session.hasRedbox()) ? 'success' : 'fail'),
/success/
)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toContain(
'Cannot add property x, object is not extensible'

View file

@ -2,12 +2,10 @@ import path from 'path'
import { outdent } from 'outdent'
import { FileRef, nextTestSetup } from 'e2e-utils'
import {
check,
assertHasRedbox,
getRedboxDescription,
getRedboxSource,
getVersionCheckerText,
hasRedbox,
retry,
} from 'next-test-utils'
describe('Error overlay - RSC runtime errors', () => {
@ -29,10 +27,7 @@ describe('Error overlay - RSC runtime errors', () => {
const browser = await next.browser('/server')
await check(
async () => ((await hasRedbox(browser)) ? 'success' : 'fail'),
/success/
)
await assertHasRedbox(browser)
const errorDescription = await getRedboxDescription(browser)
expect(errorDescription).toContain(
@ -55,12 +50,9 @@ describe('Error overlay - RSC runtime errors', () => {
const browser = await next.browser('/client')
await check(
async () => ((await hasRedbox(browser)) ? 'success' : 'fail'),
/success/
)
const errorDescription = await getRedboxDescription(browser)
await assertHasRedbox(browser)
const errorDescription = await getRedboxDescription(browser)
expect(errorDescription).toContain(
'Error: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context'
)
@ -77,10 +69,7 @@ describe('Error overlay - RSC runtime errors', () => {
)
const browser = await next.browser('/server')
await check(
async () => ((await hasRedbox(browser)) ? 'success' : 'fail'),
/success/
)
await assertHasRedbox(browser)
const errorDescription = await getRedboxDescription(browser)
@ -98,10 +87,7 @@ describe('Error overlay - RSC runtime errors', () => {
`
)
const browser = await next.browser('/server')
await check(
async () => ((await hasRedbox(browser)) ? 'success' : 'fail'),
/success/
)
await assertHasRedbox(browser)
const source = await getRedboxSource(browser)
// Can show the original source code
@ -120,11 +106,9 @@ describe('Error overlay - RSC runtime errors', () => {
)
const browser = await next.browser('/server')
await retry(async () => {
expect(await hasRedbox(browser)).toBe(true)
})
await assertHasRedbox(browser)
const versionText = await getVersionCheckerText(browser)
await expect(versionText).toMatch(/Next.js \([\w.-]+\)/)
expect(versionText).toMatch(/Next.js \([\w.-]+\)/)
})
it('should not show the bundle layer info in the file trace', async () => {
@ -138,9 +122,7 @@ describe('Error overlay - RSC runtime errors', () => {
)
const browser = await next.browser('/server')
await retry(async () => {
expect(await hasRedbox(browser)).toBe(true)
})
await assertHasRedbox(browser)
const source = await getRedboxSource(browser)
expect(source).toContain('app/server/page.js')
expect(source).not.toContain('//app/server/page.js')

View file

@ -541,7 +541,7 @@ describe('Error Overlay for server components', () => {
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// In webpack when the message too long it gets truncated with ` | ` with new lines.
// So we need to check for the first part of the message.
const normalizedSource = await session.getRedboxSource()

View file

@ -17,7 +17,7 @@ describe.each(['default', 'turbo'])(
next,
new Map([['pages/_app.js', ``]])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: The default export is not a React Component in page: "/_app""`
)
@ -31,7 +31,7 @@ describe.each(['default', 'turbo'])(
export default MyApp
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -40,7 +40,7 @@ describe.each(['default', 'turbo'])(
next,
new Map([['pages/_document.js', ``]])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: The default export is not a React Component in page: "/_document""`
)
@ -72,7 +72,7 @@ describe.each(['default', 'turbo'])(
export default MyDocument
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -91,7 +91,7 @@ describe.each(['default', 'turbo'])(
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const content = await session.getRedboxSource()
const source = next.normalizeTestDirContent(content)
if (process.env.TURBOPACK) {
@ -142,7 +142,7 @@ describe.each(['default', 'turbo'])(
export default MyApp
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -179,7 +179,7 @@ describe.each(['default', 'turbo'])(
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = next.normalizeTestDirContent(
await session.getRedboxSource()
)
@ -244,7 +244,7 @@ describe.each(['default', 'turbo'])(
export default MyDocument
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
}

View file

@ -44,7 +44,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.env.TURBOPACK) {
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./node_modules/my-package/index.js:1:13
@ -92,7 +92,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
if (process.env.TURBOPACK) {
@ -145,7 +145,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
if (process.env.TURBOPACK) {
@ -201,7 +201,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
if (process.env.TURBOPACK) {
@ -238,7 +238,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.documentElement.innerHTML)
).toContain('index page')

View file

@ -32,11 +32,11 @@ describe.skip('ReactRefreshLogBox scss', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Syntax error
await session.patch('index.module.scss', `.button { font-size: :5px; }`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source).toMatchSnapshot()
@ -64,7 +64,7 @@ describe.skip('ReactRefreshLogBox scss', () => {
// Checks for selectors that can't be prefixed.
// Selector "button" is not pure (pure selectors must contain at least one local class or id)
await session.patch('index.module.scss', `button { font-size: 5px; }`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source2 = await session.getRedboxSource()
expect(source2).toMatchSnapshot()

View file

@ -35,7 +35,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
)
await session.evaluate(() => document.querySelector('a').click())
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
await cleanup()
@ -80,7 +80,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
await cleanup()
@ -141,7 +141,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`export default function FunctionDefault() { throw new Error('no'); }`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
expect(
await session.evaluate(() => document.querySelector('h2').textContent)
@ -165,7 +165,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// We internally only check the script path, not including the line number
// and error message because the error comes from an external library.
// This test ensures that the errored script path is correctly resolved.
@ -192,7 +192,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -207,7 +207,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = next.normalizeTestDirContent(await session.getRedboxSource())
if (process.env.TURBOPACK) {
expect(source).toMatchInlineSnapshot(`
@ -281,7 +281,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('hello')
@ -298,7 +298,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toMatchSnapshot()
await session.patch(
@ -313,7 +313,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('hello new')
@ -339,11 +339,11 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
// Syntax error
await session.patch('index.module.css', `.button`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source).toMatch(
process.env.TURBOPACK
@ -365,7 +365,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
// Checks for selectors that can't be prefixed.
// Selector "button" is not pure (pure selectors must contain at least one local class or id)
await session.patch('index.module.css', `button {}`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source2 = await session.getRedboxSource()
expect(source2).toMatchSnapshot()
@ -393,9 +393,9 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.evaluate(() => document.querySelector('button').click())
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const header = await session.getRedboxDescription()
expect(header).toMatchSnapshot()
@ -439,9 +439,9 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.evaluate(() => document.querySelector('button').click())
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const header2 = await session.getRedboxDescription()
expect(header2).toMatchSnapshot()
@ -485,9 +485,9 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.evaluate(() => document.querySelector('button').click())
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const header3 = await session.getRedboxDescription()
expect(header3).toMatchSnapshot()
@ -531,9 +531,9 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.evaluate(() => document.querySelector('button').click())
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const header4 = await session.getRedboxDescription()
expect(header4).toMatchInlineSnapshot(
@ -592,9 +592,9 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.evaluate(() => document.querySelector('button').click())
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const header5 = await session.getRedboxDescription()
expect(header5).toMatchInlineSnapshot(
@ -653,7 +653,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: {"a":1,"b":"x"}"`
)
@ -669,7 +669,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
outdent`
@ -683,7 +683,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toContain(
`Error: class Hello {`
)
@ -699,7 +699,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
outdent`
@ -711,7 +711,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: string error"`
)
@ -727,7 +727,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
outdent`
@ -739,7 +739,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toContain(
`Error: A null error was thrown`
)
@ -765,7 +765,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await expandCallStack(browser)
@ -806,7 +806,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await expandCallStack(browser)
let callStackFrames = await browser.elementsByCss(
'[data-nextjs-call-stack-frame]'
@ -836,7 +836,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
],
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await expandCallStack(browser)
// Should still show the errored line in source code

View file

@ -30,7 +30,7 @@ describe.skip('ReactRefreshLogBox', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: Multiple children were passed to <Link> with \`href\` of \`/\` but only one child is supported https://nextjs.org/docs/messages/link-multiple-children"`
)
@ -64,7 +64,7 @@ describe.skip('ReactRefreshLogBox', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
`"Error: Failed prop type: The prop \`href\` expects a \`string\` or \`object\` in \`<Link>\`, but got \`undefined\` instead."`
)
@ -79,7 +79,7 @@ describe.skip('ReactRefreshLogBox', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -103,7 +103,7 @@ describe.skip('ReactRefreshLogBox', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -127,7 +127,7 @@ describe.skip('ReactRefreshLogBox', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -151,7 +151,7 @@ describe.skip('ReactRefreshLogBox', () => {
}
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await session.patch(
'index.js',
@ -175,7 +175,7 @@ describe.skip('ReactRefreshLogBox', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchSnapshot()
await session.patch(
@ -200,7 +200,7 @@ describe.skip('ReactRefreshLogBox', () => {
}
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchSnapshot()
await cleanup()
@ -226,7 +226,7 @@ describe.skip('ReactRefreshLogBox', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await cleanup()
})
})

View file

@ -10,7 +10,7 @@ describe('ReactRefreshModule', () => {
it('should allow any variable names', async () => {
const { session, cleanup } = await sandbox(next)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
const variables = [
'_a',
@ -29,7 +29,7 @@ describe('ReactRefreshModule', () => {
return null
}`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(next.cliOutput).not.toContain(
`'${variable}' has already been declared`
)

View file

@ -74,7 +74,7 @@ describe('ReactRefreshRegression', () => {
)
// Verify no hydration mismatch:
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -283,7 +283,7 @@ describe('ReactRefreshRegression', () => {
)
expect(didNotReload).toBe(false)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
const source = await session.getRedboxSource()
expect(source.split(/\r?\n/g).slice(2).join('\n')).toMatchInlineSnapshot(`
@ -326,7 +326,7 @@ describe('ReactRefreshRegression', () => {
let didNotReload = await session.patch('pages/mdx.mdx', `Hello Foo!`)
expect(didNotReload).toBe(true)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(
() => document.querySelector('#__next').textContent
@ -335,7 +335,7 @@ describe('ReactRefreshRegression', () => {
didNotReload = await session.patch('pages/mdx.mdx', `Hello Bar!`)
expect(didNotReload).toBe(true)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(
() => document.querySelector('#__next').textContent

View file

@ -39,7 +39,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
await session.patch('index.js', `export default () => <div/`)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'export default () => <div/'
)
@ -67,7 +67,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
/Count: 1/
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -104,7 +104,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('1')
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (isTurbopack) {
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"index.js (7:11) @ <unknown>
@ -148,7 +148,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
@ -158,7 +158,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('Count: 2')
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -204,7 +204,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
'export default function Child()'
)
@ -219,7 +219,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
)
expect(didNotReload).toBe(true)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(
await session.evaluate(() => document.querySelector('p').textContent)
).toBe('Hello')
@ -265,7 +265,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
export default ClassDefault;
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// Now change the code to introduce a runtime error without fixing the syntax error:
await session.patch(
@ -283,7 +283,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
export default ClassDefault;
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
// Now fix the syntax error:
await session.patch(
@ -301,7 +301,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
export default ClassDefault;
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(async () => {
const source = await session.getRedboxSource()
@ -358,7 +358,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
)
// We get an error because Foo didn't import React. Fair.
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource()).toInclude(
"return React.createElement('h1', null, 'Foo');"
)
@ -375,7 +375,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
)
// Expected: this fixes the problem
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await cleanup()
})
@ -412,7 +412,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
)
await new Promise((resolve) => setTimeout(resolve, 1000))
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
if (process.platform === 'win32') {
expect(await session.getRedboxSource()).toMatchSnapshot()
} else {
@ -433,7 +433,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
)
await new Promise((resolve) => setTimeout(resolve, 1000))
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
let redboxSource = next.normalizeTestDirContent(
await session.getRedboxSource()
)
@ -474,7 +474,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => {
// Test that runtime error does not take over:
await new Promise((resolve) => setTimeout(resolve, 2000))
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
redboxSource = next.normalizeTestDirContent(await session.getRedboxSource())
if (isTurbopack) {
// TODO: Remove this branching once import traces are implemented in Turbopack

View file

@ -30,7 +30,7 @@ describe('Error overlay for hydration errors', () => {
])
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(`
"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used
@ -59,7 +59,7 @@ describe('Error overlay for hydration errors', () => {
`
)
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
expect(await browser.elementByCss('.child').text()).toBe('Value')

View file

@ -44,7 +44,7 @@ describe('Error Overlay for server components compiler errors in pages', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(
() => session.getRedboxSource(),
/That only works in a Server Component/
@ -103,7 +103,7 @@ describe('Error Overlay for server components compiler errors in pages', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(
() => session.getRedboxSource(),
/That only works in a Server Component/
@ -161,7 +161,7 @@ describe('Error Overlay for server components compiler errors in pages', () => {
`
)
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
await check(
() => session.getRedboxSource(),
/That only works in a Server Component/

View file

@ -9,7 +9,7 @@ describe.each(['default', 'turbo'])('basic app-dir tests', () => {
it('should reload app pages without error', async () => {
const { session, cleanup, browser } = await sandbox(next, undefined, '/')
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
browser.refresh()
@ -17,7 +17,7 @@ describe.each(['default', 'turbo'])('basic app-dir tests', () => {
await waitForHydration(browser)
for (let i = 0; i < 15; i++) {
expect(await session.hasRedbox()).toBe(false)
await session.assertNoRedbox()
await waitFor(1000)
}

View file

@ -1,7 +1,7 @@
import { nextTestSetup } from 'e2e-utils'
import {
assertHasRedbox,
getRedboxCallStack,
hasRedbox,
shouldRunTurboDevTest,
expandCallStack,
getRedboxSource,
@ -29,7 +29,7 @@ describe('app dir - dynamic error trace', () => {
it('should show the error trace', async () => {
const browser = await next.browser('/')
await hasRedbox(browser)
await assertHasRedbox(browser)
await expandCallStack(browser)
const callStack = await getRedboxCallStack(browser)

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { hasRedbox } from 'next-test-utils'
import { assertHasRedbox, assertNoRedbox } from 'next-test-utils'
describe('develop - app-dir - edge errros hmr', () => {
const { next } = nextTestSetup({
@ -14,11 +14,11 @@ describe('develop - app-dir - edge errros hmr', () => {
return content.replace('{/* < */}', '<') // uncomment
})
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await next.patchFile('app/comp.server.js', clientComponentSource)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
it('should recover from build errors when client component error', async () => {
@ -29,10 +29,10 @@ describe('develop - app-dir - edge errros hmr', () => {
return content.replace('{/* < */}', '<') // uncomment
})
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await next.patchFile('app/comp.client.js', clientComponentSource)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
})

View file

@ -1,7 +1,7 @@
import { join } from 'path'
import { nextTestSetup, FileRef } from 'e2e-utils'
import { hasRedbox } from 'next-test-utils'
import { assertHasRedbox, assertNoRedbox } from 'next-test-utils'
import { waitForHydration } from 'development-sandbox'
describe('hmr-deleted-page', () => {
@ -19,12 +19,12 @@ describe('hmr-deleted-page', () => {
await next.deleteFile('app/page/style.css')
await waitForHydration(browser)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await next.deleteFile('app/page')
await waitForHydration(browser)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('h1').text()).toBe('404')
})
})

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { hasRedbox } from 'next-test-utils'
import { assertNoRedbox } from 'next-test-utils'
describe('HMR Move File', () => {
const { next } = nextTestSetup({
@ -17,7 +17,7 @@ describe('HMR Move File', () => {
content.replace('./button', './button2')
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('#hello-world-button').text()).toBe(
'hello world'

View file

@ -1,5 +1,11 @@
import { nextTestSetup } from 'e2e-utils'
import { getRedboxDescription, hasRedbox, retry } from 'next-test-utils'
import {
assertHasRedbox,
assertNoRedbox,
getRedboxDescription,
retry,
} from 'next-test-utils'
import { outdent } from 'outdent'
describe('app-dir - missing required html tags', () => {
const { next } = nextTestSetup({ files: __dirname })
@ -7,7 +13,7 @@ describe('app-dir - missing required html tags', () => {
it('should show error overlay', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(`
"The following tags are missing in the Root Layout: <html>, <body>.
Read more at https://nextjs.org/docs/messages/missing-root-layout-tags"
@ -21,11 +27,14 @@ describe('app-dir - missing required html tags', () => {
code.replace('return children', 'return <body>{children}</body>')
)
expect(await hasRedbox(browser)).toBe(true)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(`
"The following tags are missing in the Root Layout: <html>.
Read more at https://nextjs.org/docs/messages/missing-root-layout-tags"
`)
await assertHasRedbox(browser)
// Wait for the HMR to apply and the updated error to show.
await retry(async () => {
expect(await getRedboxDescription(browser)).toEqual(outdent`
The following tags are missing in the Root Layout: <html>.
Read more at https://nextjs.org/docs/messages/missing-root-layout-tags
`)
})
await next.patchFile('app/layout.js', (code) =>
code.replace(
@ -34,7 +43,7 @@ describe('app-dir - missing required html tags', () => {
)
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('p').text()).toBe('hello world')
// Reintroduce the bug, but only missing html tag
@ -45,9 +54,7 @@ describe('app-dir - missing required html tags', () => {
)
)
await retry(async () => {
expect(await hasRedbox(browser)).toBe(true)
})
await assertHasRedbox(browser)
// Fix the issue again
await next.patchFile('app/layout.js', (code) =>
@ -57,8 +64,6 @@ describe('app-dir - missing required html tags', () => {
)
)
await retry(async () => {
expect(await hasRedbox(browser)).toBe(false)
})
await assertNoRedbox(browser)
})
})

View file

@ -1,6 +1,6 @@
import { join } from 'path'
import { nextTestSetup } from 'e2e-utils'
import { hasRedbox } from 'next-test-utils'
import { assertNoRedbox } from 'next-test-utils'
// Skipped in Turbopack, will be added later.
;(process.env.TURBOPACK ? describe.skip : describe)(
@ -32,7 +32,7 @@ import { hasRedbox } from 'next-test-utils'
expect(await $('#typography').text()).toContain('typography')
const browser = await next.browser('/mui')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const modules = [...logs.matchAll(/\((\d+) modules\)/g)]
expect(modules.length).toBeGreaterThanOrEqual(1)

View file

@ -1,6 +1,6 @@
import { join } from 'path'
import { nextTestSetup } from 'e2e-utils'
import { hasRedbox } from 'next-test-utils'
import { assertNoRedbox } from 'next-test-utils'
describe('optimizePackageImports - mui', () => {
const { next } = nextTestSetup({
@ -20,6 +20,6 @@ describe('optimizePackageImports - mui', () => {
it('should work', async () => {
// Without barrel optimization, the reproduction breaks.
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
})

View file

@ -3,7 +3,12 @@
import { join } from 'path'
import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { check, getRedboxHeader, hasRedbox } from 'next-test-utils'
import {
assertHasRedbox,
assertNoRedbox,
check,
getRedboxHeader,
} from 'next-test-utils'
import { NextInstance } from 'e2e-utils'
const installCheckVisible = (browser) => {
@ -271,13 +276,13 @@ describe('GS(S)P Server-Side Change Reloading', () => {
try {
await next.patchFile(page, originalContent.replace('props:', 'propss:'))
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Additional keys were returned from'
)
await next.patchFile(page, originalContent)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
await next.patchFile(page, originalContent)
}
@ -301,11 +306,11 @@ describe('GS(S)P Server-Side Change Reloading', () => {
'throw new Error("custom oops"); const count'
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain('custom oops')
await next.patchFile(page, originalContent)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
await next.patchFile(page, originalContent)
}

View file

@ -2,12 +2,13 @@ import { join } from 'path'
import cheerio from 'cheerio'
import webdriver from 'next-webdriver'
import {
assertHasRedbox,
assertNoRedbox,
check,
getBrowserBodyText,
getRedboxHeader,
getRedboxDescription,
getRedboxSource,
hasRedbox,
renderViaHTTP,
retry,
waitFor,
@ -498,7 +499,7 @@ describe.each([[''], ['/docs']])(
await next.patchFile(aboutPage, aboutContent.replace('</div>', 'div'))
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const source = next.normalizeTestDirContent(
await getRedboxSource(browser)
)
@ -608,7 +609,7 @@ describe.each([[''], ['/docs']])(
browser = await webdriver(next.url, basePath + '/hmr/contact')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatch(/Unexpected eof/)
await next.patchFile(aboutPage, aboutContent)
@ -651,7 +652,7 @@ describe.each([[''], ['/docs']])(
aboutContent.replace('export', 'aa=20;\nexport')
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(/aa is not defined/)
await next.patchFile(aboutPage, aboutContent)
@ -687,7 +688,7 @@ describe.each([[''], ['/docs']])(
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatch(/an-expected-error/)
await next.patchFile(aboutPage, aboutContent)
@ -732,7 +733,7 @@ describe.each([[''], ['/docs']])(
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(
`"Error: The default export is not a React Component in page: "/hmr/about5""`
)
@ -780,7 +781,7 @@ describe.each([[''], ['/docs']])(
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
// TODO: Replace this when webpack 5 is the default
expect(await getRedboxHeader(browser)).toMatch(
`Objects are not valid as a React child (found: [object RegExp]). If you meant to render a collection of children, use an array instead.`
@ -830,7 +831,7 @@ describe.each([[''], ['/docs']])(
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(
`"Error: The default export is not a React Component in page: "/hmr/about7""`
)
@ -841,7 +842,7 @@ describe.each([[''], ['/docs']])(
() => getBrowserBodyText(browser),
/This is the about page/
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} catch (err) {
await next.patchFile(aboutPage, aboutContent)
@ -880,7 +881,7 @@ describe.each([[''], ['/docs']])(
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch('Failed to compile')
if (process.env.TURBOPACK) {
@ -913,7 +914,7 @@ describe.each([[''], ['/docs']])(
() => getBrowserBodyText(browser),
/This is the about page/
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} catch (err) {
await next.patchFile(aboutPage, aboutContent)
@ -952,7 +953,7 @@ describe.each([[''], ['/docs']])(
)
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch('Failed to compile')
let redboxSource = await getRedboxSource(browser)
@ -999,7 +1000,7 @@ describe.each([[''], ['/docs']])(
() => getBrowserBodyText(browser),
/This is the about page/
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} catch (err) {
await next.patchFile(aboutPage, aboutContent)
@ -1024,7 +1025,7 @@ describe.each([[''], ['/docs']])(
browser = await webdriver(next.url, basePath + '/hmr')
await browser.elementByCss('#error-in-gip-link').click()
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(
`"Error: an-expected-error-in-gip"`
)
@ -1065,7 +1066,7 @@ describe.each([[''], ['/docs']])(
try {
browser = await webdriver(next.url, basePath + '/hmr/error-in-gip')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(
`"Error: an-expected-error-in-gip"`
)
@ -1212,7 +1213,7 @@ describe.each([[''], ['/docs']])(
pageName,
`import hello from 'non-existent'\n` + originalContent
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await waitFor(3000)
await next.patchFile(pageName, originalContent)
await check(

View file

@ -2,7 +2,7 @@ import { join } from 'path'
import cheerio from 'cheerio'
import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { renderViaHTTP, check, hasRedbox } from 'next-test-utils'
import { assertNoRedbox, renderViaHTTP, check } from 'next-test-utils'
import { NextInstance } from 'e2e-utils'
const customDocumentGipContent = `\
@ -166,7 +166,7 @@ describe('next/dynamic', () => {
try {
browser = await webdriver(next.url, basePath + '/dynamic/no-ssr')
await check(() => browser.elementByCss('body').text(), /navigator/)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
if (browser) {
await browser.close()
@ -179,7 +179,7 @@ describe('next/dynamic', () => {
try {
browser = await webdriver(next.url, basePath + '/dynamic/no-ssr-esm')
await check(() => browser.elementByCss('body').text(), /esm.mjs/)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
if (browser) {
await browser.close()

View file

@ -1,6 +1,6 @@
import fs from 'fs-extra'
import webdriver from 'next-webdriver'
import { check, findPort, hasRedbox } from 'next-test-utils'
import { assertNoRedbox, check, findPort } from 'next-test-utils'
import { NextInstance } from 'e2e-utils'
import { createNext } from 'e2e-utils'
import stripAnsi from 'strip-ansi'
@ -42,7 +42,7 @@ describe.skip('Project Directory Renaming', () => {
await check(async () => {
return (await browser.eval('window.beforeNav')) === 1 ? 'pending' : 'done'
}, 'done')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
try {
// should still HMR correctly

View file

@ -1,8 +1,9 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import {
assertHasRedbox,
assertNoRedbox,
check,
hasRedbox,
renderViaHTTP,
getRedboxSource,
} from 'next-test-utils'
@ -83,7 +84,7 @@ describe('jsconfig-path-reloading', () => {
)}`
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain('"@lib/second-data"')
await next.patchFile(
@ -104,7 +105,7 @@ describe('jsconfig-path-reloading', () => {
)
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const html2 = await browser.eval('document.documentElement.innerHTML')
expect(html2).toContain('first button')
@ -159,7 +160,7 @@ describe('jsconfig-path-reloading', () => {
indexContent.replace('@mybutton', '@myotherbutton')
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
const html2 = await browser.eval('document.documentElement.innerHTML')

View file

@ -1,4 +1,9 @@
import { check, getRedboxSource, hasRedbox } from 'next-test-utils'
import {
assertHasRedbox,
assertNoRedbox,
check,
getRedboxSource,
} from 'next-test-utils'
import stripAnsi from 'strip-ansi'
import { nextTestSetup } from 'e2e-utils'
@ -48,9 +53,9 @@ describe('middleware - development errors', () => {
it('renders the error correctly and recovers', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await next.patchFile('middleware.js', `export default function () {}`)
await hasRedbox(browser)
await assertHasRedbox(browser)
})
})
@ -85,7 +90,7 @@ describe('middleware - development errors', () => {
it('does not render the error', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('#page-title')).toBeTruthy()
})
})
@ -122,10 +127,10 @@ describe('middleware - development errors', () => {
it('renders the error correctly and recovers', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain(`eval('test')`)
await next.patchFile('middleware.js', `export default function () {}`)
await hasRedbox(browser)
await assertHasRedbox(browser)
})
})
@ -160,13 +165,13 @@ describe('middleware - development errors', () => {
it('renders the error correctly and recovers', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const source = await getRedboxSource(browser)
expect(source).toContain(`throw new Error('booooom!')`)
expect(source).toContain('middleware.js')
expect(source).not.toContain('//middleware.js')
await next.patchFile('middleware.js', `export default function () {}`)
await hasRedbox(browser)
await assertHasRedbox(browser)
})
})
@ -201,7 +206,7 @@ describe('middleware - development errors', () => {
it('does not render the error', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('#page-title')).toBeTruthy()
})
})
@ -239,7 +244,7 @@ describe('middleware - development errors', () => {
it('does not render the error', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('#page-title')).toBeTruthy()
})
})
@ -265,12 +270,12 @@ describe('middleware - development errors', () => {
it('renders the error correctly and recovers', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(
await browser.elementByCss('#nextjs__container_errors_desc').text()
).toEqual('Failed to compile')
await next.patchFile('middleware.js', `export default function () {}`)
await hasRedbox(browser)
await assertHasRedbox(browser)
expect(await browser.elementByCss('#page-title')).toBeTruthy()
})
})
@ -295,11 +300,11 @@ describe('middleware - development errors', () => {
it('renders the error correctly and recovers', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await next.patchFile('middleware.js', `export default function () }`)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await next.patchFile('middleware.js', `export default function () {}`)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('#page-title')).toBeTruthy()
})
})

View file

@ -2,7 +2,11 @@ import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import { join } from 'path'
import webdriver from 'next-webdriver'
import { getRedboxSource, hasRedbox } from 'next-test-utils'
import {
assertHasRedbox,
assertNoRedbox,
getRedboxSource,
} from 'next-test-utils'
// TODO: The error overlay is not closed when restoring the working code.
describe.skip('next/font build-errors', () => {
@ -32,7 +36,7 @@ export default function Page() {
`
)
expect(await hasRedbox(browser)).toBeTrue()
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"app/page.js
\`next/font\` error:
@ -40,7 +44,7 @@ export default function Page() {
`)
await next.patchFile('app/page.js', content)
expect(await hasRedbox(browser)).toBeFalse()
await assertNoRedbox(browser)
})
it("should show a module not found error if local font file can' be resolved", async () => {
@ -60,7 +64,7 @@ export default function Page() {
`
)
expect(await hasRedbox(browser)).toBeTrue()
await assertHasRedbox(browser)
const sourceLines = (await getRedboxSource(browser)).split('\n')
// Should display the file name correctly
@ -71,6 +75,6 @@ export default function Page() {
)
await next.patchFile('app/page.js', content)
expect(await hasRedbox(browser)).toBeFalse()
await assertNoRedbox(browser)
})
})

View file

@ -1,6 +1,6 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import { getRedboxSource, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxSource } from 'next-test-utils'
import webdriver from 'next-webdriver'
import { join } from 'path'
@ -18,7 +18,7 @@ describe('font-loader-in-document-error', () => {
test('next/font inside _document', async () => {
const browser = await webdriver(next.url, '/')
expect(await hasRedbox(browser)).toBeTrue()
await assertHasRedbox(browser)
if (process.env.TURBOPACK) {
// TODO: Turbopack doesn't include pages/
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`

View file

@ -1,9 +1,10 @@
/* eslint-env jest */
import {
assertHasRedbox,
assertNoRedbox,
fetchViaHTTP,
getRedboxSource,
hasRedbox,
getRedboxHeader,
waitFor,
check,
@ -55,7 +56,7 @@ describe('Client Navigation', () => {
it('should have proper error when no children are provided', async () => {
const browser = await webdriver(next.appPort, '/link-no-child')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'No children were passed to <Link> with `href` of `/about` but one child is required'
)
@ -63,7 +64,7 @@ describe('Client Navigation', () => {
it('should not throw error when one number type child is provided', async () => {
const browser = await webdriver(next.appPort, '/link-number-child')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
if (browser) await browser.close()
})
@ -279,7 +280,7 @@ describe('Client Navigation', () => {
try {
browser = await webdriver(next.appPort, '/nav')
await browser.elementByCss('#empty-props').click()
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
/should resolve to an object\. But found "null" instead\./
)
@ -1377,7 +1378,7 @@ describe('Client Navigation', () => {
let browser
try {
browser = await webdriver(next.appPort, '/error-inside-browser-page')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxSource(browser)
expect(text).toMatch(/An Expected error occurred/)
expect(text).toMatch(/pages[\\/]error-inside-browser-page\.js \(5:13\)/)
@ -1395,7 +1396,7 @@ describe('Client Navigation', () => {
next.appPort,
'/error-in-the-browser-global-scope'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxSource(browser)
expect(text).toMatch(/An Expected error occurred/)
expect(text).toMatch(/error-in-the-browser-global-scope\.js \(2:9\)/)
@ -1478,7 +1479,7 @@ describe('Client Navigation', () => {
await browser.waitForElementByCss('.nav-about')
await browser.back()
await waitFor(1000)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
if (browser) {
await browser.close()
@ -1498,7 +1499,7 @@ describe('Client Navigation', () => {
await browser.waitForElementByCss('.nav-about')
await browser.back()
await waitFor(1000)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
if (browser) {
await browser.close()
@ -1516,7 +1517,7 @@ describe('Client Navigation', () => {
await browser.waitForElementByCss('.nav-about')
await browser.back()
await waitFor(1000)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
} finally {
if (browser) {
await browser.close()

View file

@ -3,9 +3,9 @@
import cheerio from 'cheerio'
import { nextTestSetup } from 'e2e-utils'
import {
assertHasRedbox,
fetchViaHTTP,
getRedboxHeader,
hasRedbox,
renderViaHTTP,
} from 'next-test-utils'
import webdriver from 'next-webdriver'
@ -133,7 +133,7 @@ describe('Client Navigation rendering', () => {
const expectedErrorMessage =
'Circular structure in "getInitialProps" result of page "/circular-json-error".'
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toContain(expectedErrorMessage)
})
@ -147,7 +147,7 @@ describe('Client Navigation rendering', () => {
const expectedErrorMessage =
'"InstanceInitialPropsPage.getInitialProps()" is defined as an instance method - visit https://nextjs.org/docs/messages/get-initial-props-as-an-instance-method for more information.'
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toContain(expectedErrorMessage)
})
@ -157,7 +157,7 @@ describe('Client Navigation rendering', () => {
const expectedErrorMessage =
'"EmptyInitialPropsPage.getInitialProps()" should resolve to an object. But found "null" instead.'
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toContain(expectedErrorMessage)
})
@ -193,14 +193,14 @@ describe('Client Navigation rendering', () => {
test('default export is not a React Component', async () => {
const browser = await webdriver(next.appPort, '/no-default-export')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toMatch(/The default export is not a React Component/)
})
test('error-inside-page', async () => {
const browser = await webdriver(next.appPort, '/error-inside-page')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toMatch(/This is an expected error/)
// Sourcemaps are applied by react-error-overlay, so we can't check them on SSR.
@ -211,7 +211,7 @@ describe('Client Navigation rendering', () => {
next.appPort,
'/error-in-the-global-scope'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toMatch(/aa is not defined/)
// Sourcemaps are applied by react-error-overlay, so we can't check them on SSR.
@ -311,7 +311,7 @@ describe('Client Navigation rendering', () => {
it('should show a valid error when undefined is thrown', async () => {
const browser = await webdriver(next.appPort, '/throw-undefined')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const text = await getRedboxHeader(browser)
expect(text).toContain(

View file

@ -1,6 +1,6 @@
import { nextTestSetup } from 'e2e-utils'
import fs from 'fs-extra'
import { hasRedbox } from 'next-test-utils'
import { assertNoRedbox } from 'next-test-utils'
import path from 'path'
describe('repeated-dev-edits', () => {
@ -25,7 +25,7 @@ describe('repeated-dev-edits', () => {
expect(await browser.elementByCss('p').text()).toBe('version-2')
// Verify no hydration mismatch:
expect(await hasRedbox(browser)).toBeFalse()
await assertNoRedbox(browser)
await next.patchFile(
pagePath,
@ -35,11 +35,11 @@ describe('repeated-dev-edits', () => {
expect(await browser.elementByCss('p').text()).toBe('version-3')
// Verify no hydration mismatch:
expect(await hasRedbox(browser)).toBeFalse()
await assertNoRedbox(browser)
await browser.refresh()
// Verify no hydration mismatch:
expect(await hasRedbox(browser)).toBeFalse()
await assertNoRedbox(browser)
})
})

View file

@ -1,8 +1,9 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import {
assertHasRedbox,
assertNoRedbox,
check,
hasRedbox,
renderViaHTTP,
getRedboxSource,
} from 'next-test-utils'
@ -83,7 +84,7 @@ describe('tsconfig-path-reloading', () => {
)}`
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain("'@lib/second-data'")
await next.patchFile(
@ -104,7 +105,7 @@ describe('tsconfig-path-reloading', () => {
)
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const html2 = await browser.eval('document.documentElement.innerHTML')
expect(html2).toContain('first button')
@ -159,7 +160,7 @@ describe('tsconfig-path-reloading', () => {
indexContent.replace('@mybutton', '@myotherbutton')
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
const html2 = await browser.eval('document.documentElement.innerHTML')

View file

@ -1,11 +1,11 @@
/* eslint-disable jest/no-standalone-expect */
import { nextTestSetup } from 'e2e-utils'
import {
assertHasRedbox,
check,
retry,
waitFor,
getRedboxSource,
hasRedbox,
} from 'next-test-utils'
import type { Request, Response, Route } from 'playwright'
import fs from 'fs-extra'
@ -705,7 +705,7 @@ describe('app-dir action handling', () => {
origContent + '\n\nexport const foo = 1'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain(
'Only async functions are allowed to be exported in a "use server" file.'
)

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { check, hasRedbox, waitFor } from 'next-test-utils'
import { assertNoRedbox, check, waitFor } from 'next-test-utils'
describe('app dir', () => {
const { next, isNextDev, isNextStart, skipped } = nextTestSetup({
@ -36,7 +36,7 @@ describe('app dir', () => {
await waitFor(1000)
// It should not have an error
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
// HMR should still work
const code = await next.readFile('app/page-with-loading/page.js')

View file

@ -1,5 +1,10 @@
import { nextTestSetup } from 'e2e-utils'
import { check, hasRedbox, retry, shouldRunTurboDevTest } from 'next-test-utils'
import {
assertNoRedbox,
check,
retry,
shouldRunTurboDevTest,
} from 'next-test-utils'
async function resolveStreamResponse(response: any, onData?: any) {
let result = ''
@ -250,7 +255,7 @@ describe('app dir - external dependency', () => {
expect($('#transpile-cjs-lib').text()).toBe('transpile-cjs-lib')
const browser = await next.browser('/cjs/client')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
it('should export client module references in esm', async () => {

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { getRedboxHeader, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxHeader } from 'next-test-utils'
process.env.__TEST_SENTINEL = 'build'
@ -198,7 +198,7 @@ describe('dynamic-data with dynamic = "error"', () => {
it('displays redbox when `dynamic = "error"` and dynamic data is read in dev', async () => {
let browser = await next.browser('/cookies?foo=foosearch')
try {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
'Error: Route /cookies with `dynamic = "error"` couldn\'t be rendered statically because it used `cookies`'
)
@ -208,7 +208,7 @@ describe('dynamic-data with dynamic = "error"', () => {
browser = await next.browser('/headers?foo=foosearch')
try {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
'Error: Route /headers with `dynamic = "error"` couldn\'t be rendered statically because it used `headers`'
)
@ -218,7 +218,7 @@ describe('dynamic-data with dynamic = "error"', () => {
browser = await next.browser('/search?foo=foosearch')
try {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
'Error: Route /search with `dynamic = "error"` couldn\'t be rendered statically because it used `searchParams`'
)
@ -276,7 +276,7 @@ describe('dynamic-data inside cache scope', () => {
it('displays redbox when accessing dynamic data inside a cache scope', async () => {
let browser = await next.browser('/cookies')
try {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
'Error: Route /cookies used "cookies" inside a function cached with "unstable_cache(...)".'
)
@ -286,7 +286,7 @@ describe('dynamic-data inside cache scope', () => {
browser = await next.browser('/headers')
try {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
'Error: Route /headers used "headers" inside a function cached with "unstable_cache(...)".'
)

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { getRedboxDescription, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxDescription } from 'next-test-utils'
describe('dynamic-href', () => {
const {
@ -20,7 +20,7 @@ describe('dynamic-href', () => {
const browser = await next.browser('/object')
// Error should show up
expect(await hasRedbox(browser)).toBeTrue()
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(
`"Error: Dynamic href \`/object/[slug]\` found in <Link> while using the \`/app\` router, this is not supported. Read more: https://nextjs.org/docs/messages/app-dir-dynamic-href"`
)
@ -48,7 +48,7 @@ describe('dynamic-href', () => {
const browser = await next.browser('/string')
// Error should show up
expect(await hasRedbox(browser)).toBeTrue()
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatchInlineSnapshot(
`"Error: Dynamic href \`/object/[slug]\` found in <Link> while using the \`/app\` router, this is not supported. Read more: https://nextjs.org/docs/messages/app-dir-dynamic-href"`
)

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { getRedboxHeader, hasRedbox, retry } from 'next-test-utils'
import { assertHasRedbox, getRedboxHeader, retry } from 'next-test-utils'
describe('app-dir - errors', () => {
const { next, isNextDev, isNextStart, skipped } = nextTestSetup({
@ -19,7 +19,7 @@ describe('app-dir - errors', () => {
if (isNextDev) {
// TODO: investigate desired behavior here as it is currently
// minimized by default
// expect(await hasRedbox(browser)).toBe(true)
// await assertHasRedbox(browser)
// expect(await getRedboxHeader(browser)).toMatch(/this is a test/)
} else {
await browser
@ -47,7 +47,7 @@ describe('app-dir - errors', () => {
// Digest of the error message should be stable.
).not.toBe('')
// TODO-APP: ensure error overlay is shown for errors that happened before/during hydration
// expect(await hasRedbox(browser)).toBe(true)
// await assertHasRedbox(browser)
// expect(await getRedboxHeader(browser)).toMatch(/this is a test/)
} else {
await browser
@ -68,7 +68,7 @@ describe('app-dir - errors', () => {
await browser.elementByCss('#error-trigger-button').click()
if (isNextDev) {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(/this is a test/)
} else {
expect(
@ -83,7 +83,7 @@ describe('app-dir - errors', () => {
const browser = await next.browser('/global-error-boundary/server')
if (isNextDev) {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(/custom server error/)
} else {
expect(

View file

@ -1,8 +1,8 @@
import { getRedboxHeader, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxHeader } from 'next-test-utils'
import { nextTestSetup } from 'e2e-utils'
async function testDev(browser, errorRegex) {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(errorRegex)
}

View file

@ -1,8 +1,8 @@
import { getRedboxHeader, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxHeader } from 'next-test-utils'
import { nextTestSetup } from 'e2e-utils'
async function testDev(browser, errorRegex) {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(errorRegex)
}

View file

@ -1,11 +1,11 @@
import { nextTestSetup } from 'e2e-utils'
import { getRedboxHeader, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxHeader } from 'next-test-utils'
const errorMessage =
'images.loaderFile detected but the file is missing default export.\nRead more: https://nextjs.org/docs/messages/invalid-images-config'
async function testDev(browser, errorRegex) {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(errorRegex)
}

View file

@ -339,7 +339,7 @@ describe.each(runtimes)('unstable_after() in %s runtime', (runtimeValue) => {
)
try {
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxDescription()).toContain(
`Route /static with \`dynamic = "${dynamicValue}"\` couldn't be rendered statically because it used \`unstable_after\``
)
@ -365,7 +365,7 @@ describe.each(runtimes)('unstable_after() in %s runtime', (runtimeValue) => {
'/invalid-in-client'
)
try {
expect(await session.hasRedbox()).toBe(true)
await session.assertHasRedbox()
expect(await session.getRedboxSource(true)).toMatch(
/You're importing a component that needs "?unstable_after"?\. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component\./
)

View file

@ -1,6 +1,6 @@
/* eslint-env jest */
import { nextTestSetup, isNextDev } from 'e2e-utils'
import { getRedboxSource, hasRedbox, retry } from 'next-test-utils'
import { assertHasRedbox, getRedboxSource, retry } from 'next-test-utils'
import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'
@ -69,7 +69,7 @@ _describe('unstable_after() - pages', () => {
])('$title', async ({ path }) => {
const browser = await next.browser(path)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatch(
/You're importing a component that needs "?unstable_after"?\. That only works in a Server Component which is not supported in the pages\/ directory\./
)

View file

@ -1,5 +1,5 @@
import { nextTestSetup, FileRef } from 'e2e-utils'
import { getRedboxSource, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxSource } from 'next-test-utils'
import { join } from 'path'
import cheerio from 'cheerio'
@ -456,7 +456,7 @@ describe('app dir - next/font', () => {
'./does-not-exist.woff2'
)
)
expect(await hasRedbox(browser)).toBeTrue()
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toInclude(
"Can't resolve './does-not-exist.woff2'"
)

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { check, getRedboxDescription, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, check, getRedboxDescription } from 'next-test-utils'
describe('app dir - not found with default 404 page', () => {
const { next, isNextDev, skipped } = nextTestSetup({
@ -18,7 +18,7 @@ describe('app dir - not found with default 404 page', () => {
if (isNextDev) {
await check(async () => {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toMatch(
/notFound\(\) is not allowed to use in root layout/
)
@ -45,7 +45,7 @@ describe('app dir - not found with default 404 page', () => {
const browser = await next.browser('/?root-not-found=1')
if (isNextDev) {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toBe(
'Error: notFound() is not allowed to use in root layout'
)

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { check, getRedboxSource, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, check, getRedboxSource } from 'next-test-utils'
describe('app-dir root layout', () => {
const {
@ -23,7 +23,7 @@ describe('app-dir root layout', () => {
waitHydration: false,
})
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"Please make sure to include the following tags in your root layout: <html>, <body>.
@ -37,7 +37,7 @@ describe('app-dir root layout', () => {
})
await browser.elementByCss('a').click()
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"Please make sure to include the following tags in your root layout: <html>, <body>.
@ -50,7 +50,7 @@ describe('app-dir root layout', () => {
waitHydration: false,
})
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"Please make sure to include the following tags in your root layout: <html>, <body>.

View file

@ -2,7 +2,7 @@ import { join } from 'path'
import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import { hasRedbox } from 'next-test-utils'
import { assertNoRedbox } from 'next-test-utils'
describe('basePath + trailingSlash', () => {
let next: NextInstance
@ -47,7 +47,7 @@ describe('basePath + trailingSlash', () => {
expect(await browser.eval('window.location.search')).toBe('?query=true')
if (dev) {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
}
} finally {
await browser.close()
@ -73,7 +73,7 @@ describe('basePath + trailingSlash', () => {
expect(await browser.eval('window.location.search')).toBe('?query=true')
if (dev) {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
}
} finally {
await browser.close()

View file

@ -6,9 +6,9 @@ import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import {
assertNoRedbox,
check,
fetchViaHTTP,
hasRedbox,
renderViaHTTP,
waitFor,
} from 'next-test-utils'
@ -946,7 +946,7 @@ describe('basePath', () => {
expect(await browser.eval('window.location.search')).toBe('?query=true')
if (isDev) {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
}
} finally {
await browser.close()
@ -970,7 +970,7 @@ describe('basePath', () => {
expect(await browser.eval('window.location.search')).toBe('?query=true')
if (isDev) {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
}
} finally {
await browser.close()

View file

@ -1,6 +1,7 @@
import {
assertHasRedbox,
assertNoRedbox,
getRedboxHeader,
hasRedbox,
getRedboxSource,
retry,
getRedboxDescription,
@ -48,7 +49,7 @@ describe('Conflict between app file and pages file', () => {
async function containConflictsError(browser, conflicts) {
await retry(async () => {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
if (process.env.TURBOPACK) {
expect(await getRedboxDescription(browser)).toContain(
'App Router and Pages Router both match path:'
@ -69,7 +70,7 @@ describe('Conflict between app file and pages file', () => {
it('should show error overlay for /another', async () => {
await next.start()
const browser = await next.browser('/another')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await containConflictsError(browser, [
['pages/index.js', 'app/page.js'],
['pages/another.js', 'app/another/page.js'],
@ -78,7 +79,7 @@ describe('Conflict between app file and pages file', () => {
it('should show error overlay for /', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await containConflictsError(browser, [
['pages/index.js', 'app/page.js'],
['pages/another.js', 'app/another/page.js'],
@ -87,14 +88,14 @@ describe('Conflict between app file and pages file', () => {
it('should support hmr with conflicts', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await next.renameFile('pages/index.js', 'pages/index2.js')
await next.renameFile('pages/another.js', 'pages/another2.js')
// Wait for successful recompilation
await browser.loadPage(next.url + '/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await browser.elementByCss('p').text()).toContain('index - app')
await browser.loadPage(next.url + '/another')
@ -103,23 +104,23 @@ describe('Conflict between app file and pages file', () => {
it('should not show error overlay for non conflict pages under app or pages dir', async () => {
const browser = await next.browser('/non-conflict')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await getRedboxHeader(browser)).toBeUndefined()
expect(await browser.elementByCss('p').text()).toBe('non-conflict app')
await browser.loadPage(next.url + '/non-conflict-pages')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(await getRedboxHeader(browser)).toBeUndefined()
expect(await browser.elementByCss('h1').text()).toBe('non-conflict pages')
})
it('should error again when there is new conflict', async () => {
const browser = await next.browser('/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
// Re-trigger the conflicted errors
await next.renameFile('pages/index2.js', 'pages/index.js')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
await containConflictsError(browser, [['pages/index.js', 'app/page.js']])
})
}

View file

@ -1,7 +1,7 @@
import { nextTestSetup } from 'e2e-utils'
import webdriver from 'next-webdriver'
import {
hasRedbox,
assertHasRedbox,
getRedboxSource,
getRedboxDescription,
check,
@ -27,7 +27,7 @@ describe('fetch failures have good stack traces in edge runtime', () => {
} else if (isNextDev) {
expect(next.cliOutput).toContain('src/fetcher.js')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const source = await getRedboxSource(browser)
expect(source).toContain('async function anotherFetcher(...args)')

View file

@ -1,5 +1,5 @@
import { nextTestSetup } from 'e2e-utils'
import { getRedboxSource, hasRedbox, retry } from 'next-test-utils'
import { assertHasRedbox, getRedboxSource, retry } from 'next-test-utils'
describe('module layer', () => {
const { next, isNextStart, isNextDev } = nextTestSetup({
@ -115,7 +115,7 @@ describe('module layer', () => {
)
await retry(async () => {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const source = await getRedboxSource(browser)
expect(source).toContain(
`You're importing a component that imports client-only. It only works in a Client Component but none of its parents are marked with "use client"`

View file

@ -1,5 +1,5 @@
import { createNext, FileRef, isNextDev } from 'e2e-utils'
import { getRedboxDescription, hasRedbox } from 'next-test-utils'
import { assertHasRedbox, getRedboxDescription } from 'next-test-utils'
import { NextInstance } from 'e2e-utils'
import webdriver from 'next-webdriver'
import path from 'path'
@ -30,7 +30,7 @@ describe('New Link Behavior with <a> child', () => {
if (isNextDev) {
expect(next.cliOutput).toContain(msg)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxDescription(browser)).toContain(msg)
expect(link.length).toBe(0)
} else {

View file

@ -6,11 +6,11 @@ import escapeRegex from 'escape-string-regexp'
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import {
assertHasRedbox,
check,
fetchViaHTTP,
getBrowserBodyText,
getRedboxHeader,
hasRedbox,
normalizeRegEx,
renderViaHTTP,
retry,
@ -1099,7 +1099,7 @@ describe('Prerender', () => {
// we need to reload the page to trigger getStaticProps
await browser.refresh()
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const errOverlayContent = await getRedboxHeader(browser)
const errorMsg = /oops from getStaticProps/
expect(next.cliOutput).toMatch(errorMsg)
@ -1239,7 +1239,7 @@ describe('Prerender', () => {
// )
// FIXME: disable this
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
/Failed to load static props/
)
@ -1255,7 +1255,7 @@ describe('Prerender', () => {
// )
// FIXME: disable this
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
/Failed to load static props/
)

View file

@ -1,6 +1,6 @@
import { createNext } from 'e2e-utils'
import { NextInstance } from 'e2e-utils'
import { hasRedbox, renderViaHTTP } from 'next-test-utils'
import { assertNoRedbox, renderViaHTTP } from 'next-test-utils'
import webdriver from 'next-webdriver'
import cheerio from 'cheerio'
@ -95,7 +95,7 @@ describe('Type module interop', () => {
it('should render client-side', async () => {
const browser = await webdriver(next.url, '/')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await browser.close()
})
@ -107,7 +107,7 @@ describe('Type module interop', () => {
it('should render client-side with modules', async () => {
const browser = await webdriver(next.url, '/modules')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await browser.close()
})
})

View file

@ -1,10 +1,10 @@
/* eslint-env jest */
import { join } from 'path'
import {
assertNoRedbox,
killApp,
findPort,
launchApp,
hasRedbox,
waitFor,
} from 'next-test-utils'
import webdriver from 'next-webdriver'
@ -25,7 +25,7 @@ describe('App assetPrefix config', () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const title = await browser.elementById('title').text()
expect(title).toBe('IndexPage')
} finally {

View file

@ -6,13 +6,13 @@ import fs from 'fs-extra'
import webdriver from 'next-webdriver'
import globOrig from 'glob'
import {
assertHasRedbox,
check,
fetchViaHTTP,
File,
findPort,
getRedboxHeader,
getRedboxSource,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -154,7 +154,7 @@ export async function runTests({
if (isDev) {
const url = dynamicPage ? '/another/first' : '/api/json'
const browser = await webdriver(port, url)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const header = await getRedboxHeader(browser)
const source = await getRedboxSource(browser)
expect(`${header}\n${source}`).toContain(expectedErrMsg)

View file

@ -1,10 +1,10 @@
/* eslint-env jest */
import {
assertHasRedbox,
check,
findPort,
getRedboxSource,
hasRedbox,
killApp,
launchApp,
} from 'next-test-utils'
@ -35,7 +35,7 @@ const appDir = join(__dirname, '../')
)
const browser = await webdriver(appPort, '/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
if (process.platform === 'win32') {
// TODO: add win32 snapshot
} else {

View file

@ -1,10 +1,11 @@
/* eslint-env jest */
import {
assertHasRedbox,
assertNoRedbox,
fetchViaHTTP,
File,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
} from 'next-test-utils'
@ -220,7 +221,7 @@ describe('config-output-export', () => {
await killApp(app).catch(() => {})
fs.rmSync(blog)
}
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'ISR cannot be used with "output: export".'
)
@ -255,7 +256,7 @@ describe('config-output-export', () => {
await killApp(app).catch(() => {})
fs.rmSync(blog)
}
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
it('should work with getStaticProps and without revalidate', async () => {
@ -283,7 +284,7 @@ describe('config-output-export', () => {
await killApp(app).catch(() => {})
fs.rmSync(blog)
}
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
it('should error with getServerSideProps without fallback', async () => {
@ -311,7 +312,7 @@ describe('config-output-export', () => {
await killApp(app).catch(() => {})
fs.rmSync(blog)
}
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'getServerSideProps cannot be used with "output: export".'
)
@ -351,7 +352,7 @@ describe('config-output-export', () => {
output: 'export',
})
browser = await webdriver(result.port, '/posts/one')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'getStaticPaths with "fallback: true" cannot be used with "output: export".'
)
@ -395,7 +396,7 @@ describe('config-output-export', () => {
output: 'export',
})
browser = await webdriver(result.port, '/posts/one')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'getStaticPaths with "fallback: blocking" cannot be used with "output: export".'
)
@ -445,7 +446,7 @@ describe('config-output-export', () => {
}
const h1 = await browser.elementByCss('h1')
expect(await h1.text()).toContain('Hello from one')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(result.stderr).toBeEmpty()
})
})

View file

@ -10,6 +10,7 @@ import cheerio from 'cheerio'
import webdriver from 'next-webdriver'
import escapeRegex from 'escape-string-regexp'
import {
assertNoRedbox,
launchApp,
killApp,
findPort,
@ -21,7 +22,6 @@ import {
getBrowserBodyText,
waitFor,
normalizeRegEx,
hasRedbox,
check,
} from 'next-test-utils'
@ -296,7 +296,7 @@ const runTests = (isDev = false) => {
expect(await browser.eval('window.beforeNav')).toBe(1)
if (isDev) {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
}
})

View file

@ -5,6 +5,7 @@ import { join, dirname } from 'path'
import fs from 'fs-extra'
import url from 'url'
import {
assertHasRedbox,
renderViaHTTP,
fetchViaHTTP,
findPort,
@ -15,7 +16,6 @@ import {
nextStart,
normalizeRegEx,
check,
hasRedbox,
getRedboxHeader,
} from 'next-test-utils'
import cheerio from 'cheerio'
@ -1200,7 +1200,7 @@ function runTests({ dev }) {
await browser
.elementByCss('#view-post-1-interpolated-incorrectly')
.click()
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const header = await getRedboxHeader(browser)
expect(header).toContain(
'The provided `href` (/[name]?another=value) value is missing query values (name) to be interpolated properly.'

View file

@ -1,9 +1,9 @@
/* eslint-env jest */
import {
assertHasRedbox,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -49,7 +49,7 @@ const showsError = async (pathname, regex, click = false, isWarn = false) => {
return warnLogs.join('\n')
}, regex)
} else {
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
const errorContent = await getRedboxHeader(browser)
expect(errorContent).toMatch(regex)
}

View file

@ -1,10 +1,11 @@
/* eslint-env jest */
import {
assertHasRedbox,
assertNoRedbox,
check,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -375,7 +376,7 @@ function runTests(mode) {
it('should show missing src error', async () => {
const browser = await webdriver(appPort, '/docs/missing-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -385,7 +386,7 @@ function runTests(mode) {
it('should show invalid src error', async () => {
const browser = await webdriver(appPort, '/docs/invalid-src')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Invalid src prop (https://google.com/test.png) on `next/image`, hostname "google.com" is not configured under images in your `next.config.js`'
)
@ -397,7 +398,7 @@ function runTests(mode) {
'/docs/invalid-src-proto-relative'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Failed to parse src "//assets.example.com/img.jpg" on `next/image`, protocol-relative URL (//) must be changed to an absolute URL (http:// or https://)'
)

View file

@ -3,11 +3,12 @@
import cheerio from 'cheerio'
import validateHTML from 'html-validator'
import {
assertHasRedbox,
assertNoRedbox,
check,
fetchViaHTTP,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -813,7 +814,7 @@ function runTests(mode) {
it('should show missing src error', async () => {
const browser = await webdriver(appPort, '/missing-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -823,7 +824,7 @@ function runTests(mode) {
it('should show invalid src error', async () => {
const browser = await webdriver(appPort, '/invalid-src')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Invalid src prop (https://google.com/test.png) on `next/image`, hostname "google.com" is not configured under images in your `next.config.js`'
)
@ -832,7 +833,7 @@ function runTests(mode) {
it('should show invalid src error when protocol-relative', async () => {
const browser = await webdriver(appPort, '/invalid-src-proto-relative')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Failed to parse src "//assets.example.com/img.jpg" on `next/image`, protocol-relative URL (//) must be changed to an absolute URL (http:// or https://)'
)
@ -841,7 +842,7 @@ function runTests(mode) {
it('should show error when string src and placeholder=blur and blurDataURL is missing', async () => {
const browser = await webdriver(appPort, '/invalid-placeholder-blur')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.png" has "placeholder='blur'" property but is missing the "blurDataURL" property.`
)
@ -850,7 +851,7 @@ function runTests(mode) {
it('should show error when not numeric string width or height', async () => {
const browser = await webdriver(appPort, '/invalid-width-or-height')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "width" or "height" property. These should be numeric values.`
)
@ -862,7 +863,7 @@ function runTests(mode) {
'/invalid-placeholder-blur-static'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
/Image with src "(.*)bmp" has "placeholder='blur'" property but is missing the "blurDataURL" property/
)
@ -874,7 +875,7 @@ function runTests(mode) {
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
}, /Image with src (.*)jpg(.*) may not render properly as a child of a flex container. Consider wrapping the image with a div to configure the width/gm)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
it('should warn when img with layout=fill is inside a container without position relative', async () => {
@ -899,7 +900,7 @@ function runTests(mode) {
expect(warnings).not.toMatch(
/Image with src (.*)webp(.*) may not render properly/gm
)
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
})
it('should warn when using a very small image with placeholder=blur', async () => {
@ -908,7 +909,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)jpg(.*) is smaller than 40x40. Consider removing(.*)/gm
)
@ -920,7 +921,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Expected server HTML to contain a matching/gm
)
@ -944,7 +945,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)test(.*) was detected as the Largest Contentful Paint/gm
)
@ -959,7 +960,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)png(.*) has a "loader" property that does not implement width/gm
)
@ -983,7 +984,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)png(.*) has "sizes" property but it will be ignored/gm
)
@ -1004,7 +1005,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Image with src (.*) has a "loader" property that does not implement width/gm
)

View file

@ -3,11 +3,12 @@
import cheerio from 'cheerio'
import validateHTML from 'html-validator'
import {
assertHasRedbox,
assertNoRedbox,
check,
fetchViaHTTP,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -798,7 +799,7 @@ function runTests(mode) {
'position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:cover;object-position:10% 10%;color:transparent'
)
if (mode === 'dev') {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
@ -830,7 +831,7 @@ function runTests(mode) {
'color:transparent;width:100%;height:auto'
)
if (mode === 'dev') {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
@ -880,7 +881,7 @@ function runTests(mode) {
it('should show missing src error', async () => {
const browser = await webdriver(appPort, '/missing-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -890,7 +891,7 @@ function runTests(mode) {
it('should show empty string src error', async () => {
const browser = await webdriver(appPort, '/empty-string-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -900,7 +901,7 @@ function runTests(mode) {
it('should show invalid src error', async () => {
const browser = await webdriver(appPort, '/invalid-src')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Invalid src prop (https://google.com/test.png) on `next/image`, hostname "google.com" is not configured under images in your `next.config.js`'
)
@ -909,7 +910,7 @@ function runTests(mode) {
it('should show invalid src error when protocol-relative', async () => {
const browser = await webdriver(appPort, '/invalid-src-proto-relative')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Failed to parse src "//assets.example.com/img.jpg" on `next/image`, protocol-relative URL (//) must be changed to an absolute URL (http:// or https://)'
)
@ -917,7 +918,7 @@ function runTests(mode) {
it('should show invalid src with leading space', async () => {
const browser = await webdriver(appPort, '/invalid-src-leading-space')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Image with src " /test.jpg" cannot start with a space or control character.'
)
@ -925,7 +926,7 @@ function runTests(mode) {
it('should show invalid src with trailing space', async () => {
const browser = await webdriver(appPort, '/invalid-src-trailing-space')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Image with src "/test.png " cannot end with a space or control character.'
)
@ -934,7 +935,7 @@ function runTests(mode) {
it('should show error when string src and placeholder=blur and blurDataURL is missing', async () => {
const browser = await webdriver(appPort, '/invalid-placeholder-blur')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.png" has "placeholder='blur'" property but is missing the "blurDataURL" property.`
)
@ -943,7 +944,7 @@ function runTests(mode) {
it('should show error when invalid width prop', async () => {
const browser = await webdriver(appPort, '/invalid-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "width" property. Expected a numeric value in pixels but received "100%".`
)
@ -952,7 +953,7 @@ function runTests(mode) {
it('should show error when invalid Infinity width prop', async () => {
const browser = await webdriver(appPort, '/invalid-Infinity-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "width" property. Expected a numeric value in pixels but received "Infinity".`
)
@ -961,7 +962,7 @@ function runTests(mode) {
it('should show error when invalid height prop', async () => {
const browser = await webdriver(appPort, '/invalid-height')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "height" property. Expected a numeric value in pixels but received "50vh".`
)
@ -970,7 +971,7 @@ function runTests(mode) {
it('should show missing alt error', async () => {
const browser = await webdriver(appPort, '/missing-alt')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -980,7 +981,7 @@ function runTests(mode) {
it('should show error when missing width prop', async () => {
const browser = await webdriver(appPort, '/missing-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" is missing required "width" property.`
)
@ -989,7 +990,7 @@ function runTests(mode) {
it('should show error when missing height prop', async () => {
const browser = await webdriver(appPort, '/missing-height')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" is missing required "height" property.`
)
@ -998,7 +999,7 @@ function runTests(mode) {
it('should show error when width prop on fill image', async () => {
const browser = await webdriver(appPort, '/invalid-fill-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/wide.png" has both "width" and "fill" properties.`
)
@ -1007,7 +1008,7 @@ function runTests(mode) {
it('should show error when CSS position changed on fill image', async () => {
const browser = await webdriver(appPort, '/invalid-fill-position')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/wide.png" has both "fill" and "style.position" properties. Images with "fill" always use position absolute - it cannot be modified.`
)
@ -1019,7 +1020,7 @@ function runTests(mode) {
'/invalid-placeholder-blur-static'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
/Image with src "(.*)bmp" has "placeholder='blur'" property but is missing the "blurDataURL" property/
)
@ -1031,7 +1032,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)jpg(.*) is smaller than 40x40. Consider removing(.*)/gm
)
@ -1043,7 +1044,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Expected server HTML to contain a matching/gm
)
@ -1067,7 +1068,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)test(.*) was detected as the Largest Contentful Paint/gm
)
@ -1082,7 +1083,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)png(.*) has a "loader" property that does not implement width/gm
)
@ -1105,7 +1106,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Image with src (.*) has "fill" but is missing "sizes" prop. Please add it to improve page performance/gm
)
@ -1117,7 +1118,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Image with src (.*) has a "loader" property that does not implement width/gm
)

View file

@ -1,10 +1,11 @@
/* eslint-env jest */
import {
assertHasRedbox,
assertNoRedbox,
check,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -130,7 +131,7 @@ function runTests(mode) {
it('should show missing src error', async () => {
const browser = await webdriver(appPort, '/docs/missing-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -140,7 +141,7 @@ function runTests(mode) {
it('should show invalid src error', async () => {
const browser = await webdriver(appPort, '/docs/invalid-src')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Invalid src prop (https://google.com/test.png) on `next/image`, hostname "google.com" is not configured under images in your `next.config.js`'
)
@ -152,7 +153,7 @@ function runTests(mode) {
'/docs/invalid-src-proto-relative'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Failed to parse src "//assets.example.com/img.jpg" on `next/image`, protocol-relative URL (//) must be changed to an absolute URL (http:// or https://)'
)

View file

@ -3,11 +3,12 @@
import cheerio from 'cheerio'
import validateHTML from 'html-validator'
import {
assertHasRedbox,
assertNoRedbox,
check,
fetchViaHTTP,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -799,7 +800,7 @@ function runTests(mode) {
'position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:cover;object-position:10% 10%;color:transparent'
)
if (mode === 'dev') {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
@ -831,7 +832,7 @@ function runTests(mode) {
'color:transparent;width:100%;height:auto'
)
if (mode === 'dev') {
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
@ -881,7 +882,7 @@ function runTests(mode) {
it('should show missing src error', async () => {
const browser = await webdriver(appPort, '/missing-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -891,7 +892,7 @@ function runTests(mode) {
it('should show empty string src error', async () => {
const browser = await webdriver(appPort, '/empty-string-src')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -901,7 +902,7 @@ function runTests(mode) {
it('should show invalid src error', async () => {
const browser = await webdriver(appPort, '/invalid-src')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Invalid src prop (https://google.com/test.png) on `next/image`, hostname "google.com" is not configured under images in your `next.config.js`'
)
@ -910,7 +911,7 @@ function runTests(mode) {
it('should show invalid src error when protocol-relative', async () => {
const browser = await webdriver(appPort, '/invalid-src-proto-relative')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Failed to parse src "//assets.example.com/img.jpg" on `next/image`, protocol-relative URL (//) must be changed to an absolute URL (http:// or https://)'
)
@ -918,7 +919,7 @@ function runTests(mode) {
it('should show invalid src with leading space', async () => {
const browser = await webdriver(appPort, '/invalid-src-leading-space')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Image with src " /test.jpg" cannot start with a space or control character.'
)
@ -926,7 +927,7 @@ function runTests(mode) {
it('should show invalid src with trailing space', async () => {
const browser = await webdriver(appPort, '/invalid-src-trailing-space')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
'Image with src "/test.png " cannot end with a space or control character.'
)
@ -935,7 +936,7 @@ function runTests(mode) {
it('should show error when string src and placeholder=blur and blurDataURL is missing', async () => {
const browser = await webdriver(appPort, '/invalid-placeholder-blur')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.png" has "placeholder='blur'" property but is missing the "blurDataURL" property.`
)
@ -944,7 +945,7 @@ function runTests(mode) {
it('should show error when invalid width prop', async () => {
const browser = await webdriver(appPort, '/invalid-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "width" property. Expected a numeric value in pixels but received "100%".`
)
@ -953,7 +954,7 @@ function runTests(mode) {
it('should show error when invalid Infinity width prop', async () => {
const browser = await webdriver(appPort, '/invalid-Infinity-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "width" property. Expected a numeric value in pixels but received "Infinity".`
)
@ -962,7 +963,7 @@ function runTests(mode) {
it('should show error when invalid height prop', async () => {
const browser = await webdriver(appPort, '/invalid-height')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" has invalid "height" property. Expected a numeric value in pixels but received "50vh".`
)
@ -971,7 +972,7 @@ function runTests(mode) {
it('should show missing alt error', async () => {
const browser = await webdriver(appPort, '/missing-alt')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
await check(async () => {
return (await browser.log()).map((log) => log.message).join('\n')
@ -981,7 +982,7 @@ function runTests(mode) {
it('should show error when missing width prop', async () => {
const browser = await webdriver(appPort, '/missing-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" is missing required "width" property.`
)
@ -990,7 +991,7 @@ function runTests(mode) {
it('should show error when missing height prop', async () => {
const browser = await webdriver(appPort, '/missing-height')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/test.jpg" is missing required "height" property.`
)
@ -999,7 +1000,7 @@ function runTests(mode) {
it('should show error when width prop on fill image', async () => {
const browser = await webdriver(appPort, '/invalid-fill-width')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/wide.png" has both "width" and "fill" properties.`
)
@ -1008,7 +1009,7 @@ function runTests(mode) {
it('should show error when CSS position changed on fill image', async () => {
const browser = await webdriver(appPort, '/invalid-fill-position')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(
`Image with src "/wide.png" has both "fill" and "style.position" properties. Images with "fill" always use position absolute - it cannot be modified.`
)
@ -1020,7 +1021,7 @@ function runTests(mode) {
'/invalid-placeholder-blur-static'
)
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
/Image with src "(.*)bmp" has "placeholder='blur'" property but is missing the "blurDataURL" property/
)
@ -1032,7 +1033,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)jpg(.*) is smaller than 40x40. Consider removing(.*)/gm
)
@ -1044,7 +1045,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Expected server HTML to contain a matching/gm
)
@ -1068,7 +1069,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)test(.*) was detected as the Largest Contentful Paint/gm
)
@ -1083,7 +1084,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).toMatch(
/Image with src (.*)png(.*) has a "loader" property that does not implement width/gm
)
@ -1106,7 +1107,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Image with src (.*) has "fill" but is missing "sizes" prop. Please add it to improve page performance/gm
)
@ -1118,7 +1119,7 @@ function runTests(mode) {
const warnings = (await browser.log())
.map((log) => log.message)
.join('\n')
expect(await hasRedbox(browser)).toBe(false)
await assertNoRedbox(browser)
expect(warnings).not.toMatch(
/Image with src (.*) has a "loader" property that does not implement width/gm
)

View file

@ -2,9 +2,9 @@
import { join } from 'path'
import {
assertHasRedbox,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
} from 'next-test-utils'
@ -35,7 +35,7 @@ describe('next/image with output export config', () => {
const browser = await webdriver(appPort, '/')
const msg =
"Image Optimization using the default loader is not compatible with `{ output: 'export' }`."
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toContain(msg)
expect(stderr).toContain(msg)
})

View file

@ -2,10 +2,10 @@
import { join } from 'path'
import {
assertHasRedbox,
findPort,
getRedboxHeader,
getRedboxSource,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -22,7 +22,7 @@ function runTests({ isDev }) {
it('should show error', async () => {
if (isDev) {
const browser = await webdriver(appPort, '/')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch('Failed to compile')
const source = await getRedboxSource(browser)
if (process.env.TURBOPACK) {

View file

@ -4,11 +4,11 @@ import fs from 'fs-extra'
import { join } from 'path'
import webdriver from 'next-webdriver'
import {
assertHasRedbox,
killApp,
findPort,
launchApp,
check,
hasRedbox,
getRedboxSource,
} from 'next-test-utils'
import stripAnsi from 'strip-ansi'
@ -60,11 +60,11 @@ describe('server-side dev errors', () => {
: err
}, 'success')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain('missingVar')
await fs.writeFile(gspPage, content)
await hasRedbox(browser)
await assertHasRedbox(browser)
} finally {
await fs.writeFile(gspPage, content)
}
@ -92,11 +92,11 @@ describe('server-side dev errors', () => {
: err
}, 'success')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain('missingVar')
await fs.writeFile(gsspPage, content)
await hasRedbox(browser)
await assertHasRedbox(browser)
} finally {
await fs.writeFile(gsspPage, content)
}
@ -124,11 +124,11 @@ describe('server-side dev errors', () => {
: err
}, 'success')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain('missingVar')
await fs.writeFile(dynamicGsspPage, content)
await hasRedbox(browser)
await assertHasRedbox(browser)
} finally {
await fs.writeFile(dynamicGsspPage, content)
}
@ -156,11 +156,11 @@ describe('server-side dev errors', () => {
: err
}, 'success')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain('missingVar')
await fs.writeFile(apiPage, content)
await hasRedbox(browser)
await assertHasRedbox(browser)
} finally {
await fs.writeFile(apiPage, content)
}
@ -188,11 +188,11 @@ describe('server-side dev errors', () => {
: err
}, 'success')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxSource(browser)).toContain('missingVar')
await fs.writeFile(dynamicApiPage, content)
await hasRedbox(browser)
await assertHasRedbox(browser)
} finally {
await fs.writeFile(dynamicApiPage, content)
}

View file

@ -1,9 +1,9 @@
/* eslint-env jest */
import {
assertHasRedbox,
findPort,
getRedboxHeader,
hasRedbox,
killApp,
launchApp,
nextBuild,
@ -103,7 +103,7 @@ describe('withRouter SSR', () => {
it('should show an error when trying to use router methods during SSR', async () => {
const browser = await webdriver(port, '/router-method-ssr')
expect(await hasRedbox(browser)).toBe(true)
await assertHasRedbox(browser)
expect(await getRedboxHeader(browser)).toMatch(
`No router instance found. you should only use "next/router" inside the client side of your app. https://`
)

View file

@ -5,7 +5,8 @@ import {
getRedboxHeader,
getRedboxSource,
getVersionCheckerText,
hasRedbox,
assertHasRedbox,
assertNoRedbox,
waitFor,
waitForAndOpenRuntimeError,
getRedboxDescriptionWarning,
@ -112,8 +113,11 @@ export async function sandbox(
)
}
},
async hasRedbox() {
return hasRedbox(browser)
async assertHasRedbox() {
return assertHasRedbox(browser)
},
async assertNoRedbox() {
return assertNoRedbox(browser)
},
async waitForAndOpenRuntimeError() {
return waitForAndOpenRuntimeError(browser)

View file

@ -802,9 +802,36 @@ export async function retry<T>(
}
}
export async function hasRedbox(browser: BrowserInterface): Promise<boolean> {
export async function assertHasRedbox(browser: BrowserInterface) {
try {
await retry(
async () => {
const hasRedbox = await evaluate(browser, () => {
return Boolean(
[].slice
.call(document.querySelectorAll('nextjs-portal'))
.find((p) =>
p.shadowRoot.querySelector(
'#nextjs__container_errors_label, #nextjs__container_errors_label'
)
)
)
})
expect(hasRedbox).toBe(true)
},
5000,
200
)
} catch (errorCause) {
const error = new Error('Expected Redbox but found none')
Error.captureStackTrace(error, assertHasRedbox)
throw error
}
}
export async function assertNoRedbox(browser: BrowserInterface) {
await waitFor(5000)
const result = await evaluate(browser, () => {
const hasRedbox = await evaluate(browser, () => {
return Boolean(
[].slice
.call(document.querySelectorAll('nextjs-portal'))
@ -815,7 +842,12 @@ export async function hasRedbox(browser: BrowserInterface): Promise<boolean> {
)
)
})
return result
if (hasRedbox) {
const error = new Error('Expected no Redbox but found one')
Error.captureStackTrace(error, assertHasRedbox)
throw error
}
}
export async function hasErrorToast(