2023-10-06 01:59:22 +02:00
import path from 'path'
import { outdent } from 'outdent'
import { FileRef , createNextDescribe } from 'e2e-utils'
import {
check ,
getRedboxDescription ,
2024-01-09 23:38:37 +01:00
getRedboxSource ,
2024-01-24 14:59:43 +01:00
getVersionCheckerText ,
2023-10-06 01:59:22 +02:00
hasRedbox ,
2024-01-24 14:59:43 +01:00
retry ,
2023-10-06 01:59:22 +02:00
} from 'next-test-utils'
createNextDescribe (
'Error overlay - RSC runtime errors' ,
{
files : new FileRef ( path . join ( __dirname , 'fixtures' , 'rsc-runtime-errors' ) ) ,
} ,
( { next } ) = > {
it ( 'should show runtime errors if invalid client API from node_modules is executed' , async ( ) = > {
await next . patchFile (
'app/server/page.js' ,
outdent `
import { callClientApi } from 'client-package'
export default function Page() {
callClientApi ( )
return 'page'
}
`
)
const browser = await next . browser ( '/server' )
await check (
2024-01-15 09:36:44 +01:00
async ( ) = > ( ( await hasRedbox ( browser ) ) ? 'success' : 'fail' ) ,
2023-10-06 01:59:22 +02:00
/success/
)
const errorDescription = await getRedboxDescription ( browser )
expect ( errorDescription ) . toContain (
` Error: useState only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component `
)
} )
it ( 'should show runtime errors if invalid server API from node_modules is executed' , async ( ) = > {
await next . patchFile (
'app/client/page.js' ,
outdent `
'use client'
import { callServerApi } from 'server-package'
export default function Page() {
callServerApi ( )
return 'page'
}
`
)
const browser = await next . browser ( '/client' )
await check (
2024-01-15 09:36:44 +01:00
async ( ) = > ( ( await hasRedbox ( browser ) ) ? 'success' : 'fail' ) ,
2023-10-06 01:59:22 +02:00
/success/
)
const errorDescription = await getRedboxDescription ( browser )
expect ( errorDescription ) . toContain (
2024-02-19 13:41:14 +01:00
'Error: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context'
2023-10-06 01:59:22 +02:00
)
} )
2024-01-09 16:30:25 +01:00
it ( 'should show source code for jsx errors from server component' , async ( ) = > {
await next . patchFile (
'app/server/page.js' ,
outdent `
export default function Page() {
return < div > { alert ( 'warn' ) } < / div >
}
`
)
const browser = await next . browser ( '/server' )
await check (
2024-01-15 09:36:44 +01:00
async ( ) = > ( ( await hasRedbox ( browser ) ) ? 'success' : 'fail' ) ,
2024-01-09 16:30:25 +01:00
/success/
)
2024-01-09 23:38:37 +01:00
2024-01-09 16:30:25 +01:00
const errorDescription = await getRedboxDescription ( browser )
expect ( errorDescription ) . toContain ( ` Error: alert is not defined ` )
} )
2024-01-09 23:38:37 +01:00
it ( 'should show the userland code error trace when fetch failed error occurred' , async ( ) = > {
await next . patchFile (
'app/server/page.js' ,
outdent `
export default async function Page() {
await fetch ( 'http://locahost:3000/xxxx' )
return 'page'
}
`
)
const browser = await next . browser ( '/server' )
await check (
2024-01-15 09:36:44 +01:00
async ( ) = > ( ( await hasRedbox ( browser ) ) ? 'success' : 'fail' ) ,
2024-01-09 23:38:37 +01:00
/success/
)
const source = await getRedboxSource ( browser )
// Can show the original source code
expect ( source ) . toContain ( 'app/server/page.js' )
expect ( source ) . toContain ( ` await fetch('http://locahost:3000/xxxx') ` )
} )
2024-01-24 14:59:43 +01:00
it ( 'should contain nextjs version check in error overlay' , async ( ) = > {
await next . patchFile (
'app/server/page.js' ,
outdent `
export default function Page() {
throw new Error ( 'test' )
}
`
)
const browser = await next . browser ( '/server' )
await retry ( async ( ) = > {
expect ( await hasRedbox ( browser ) ) . toBe ( true )
} )
2024-02-01 00:04:00 +01:00
const versionText = await getVersionCheckerText ( browser )
await expect ( versionText ) . toMatch ( /Next.js \([\w.-]+\)/ )
2024-01-24 14:59:43 +01:00
} )
2024-02-16 11:33:34 +01:00
it ( 'should not show the bundle layer info in the file trace' , async ( ) = > {
await next . patchFile (
'app/server/page.js' ,
outdent `
export default function Page() {
throw new Error ( 'test' )
}
`
)
const browser = await next . browser ( '/server' )
await retry ( async ( ) = > {
expect ( await hasRedbox ( browser ) ) . toBe ( true )
} )
const source = await getRedboxSource ( browser )
expect ( source ) . toContain ( 'app/server/page.js' )
expect ( source ) . not . toContain ( '//app/server/page.js' )
// Does not contain webpack traces in file path
expect ( source ) . not . toMatch ( /webpack(-internal:)?\/\// )
} )
2023-10-06 01:59:22 +02:00
}
)