-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add dynamic routes and suspense test case for onRequestError (#…
…67848) ### What Add tests cases for dynamic routes and suspense page rendering case coverage for onRequestError. Mostly for checking the `routePath` where we can display the proper original route path Closes NDX-22 Closes NDX-79
- Loading branch information
Showing
13 changed files
with
272 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export async function getOutputLogJson(next, outputLogPath) { | ||
if (!(await next.hasFile(outputLogPath))) { | ||
return {} | ||
} | ||
const content = await next.readFile(outputLogPath) | ||
return JSON.parse(content) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
test/e2e/on-request-error/dynamic-routes/app/app-page/dynamic/[id]/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default function Page() { | ||
throw new Error('server-dynamic-page-node-error') | ||
} | ||
|
||
export const dynamic = 'force-dynamic' |
18 changes: 18 additions & 0 deletions
18
test/e2e/on-request-error/dynamic-routes/app/app-page/suspense/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Suspense } from 'react' | ||
|
||
export default function Page() { | ||
return ( | ||
<Suspense> | ||
<Inner /> | ||
</Suspense> | ||
) | ||
} | ||
|
||
function Inner() { | ||
if (typeof window === 'undefined') { | ||
throw new Error('server-suspense-page-node-error') | ||
} | ||
return 'inner' | ||
} | ||
|
||
export const dynamic = 'force-dynamic' |
5 changes: 5 additions & 0 deletions
5
test/e2e/on-request-error/dynamic-routes/app/app-route/dynamic/[id]/route.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export function GET() { | ||
throw new Error('server-dynamic-route-node-error') | ||
} | ||
|
||
export const dynamic = 'force-dynamic' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export const metadata = { | ||
title: 'Next.js', | ||
description: 'Generated by Next.js', | ||
} | ||
|
||
export default function RootLayout({ children }) { | ||
return ( | ||
<html lang="en"> | ||
<body>{children}</body> | ||
</html> | ||
) | ||
} |
40 changes: 40 additions & 0 deletions
40
test/e2e/on-request-error/dynamic-routes/app/write-log/route.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import fs from 'fs' | ||
import fsp from 'fs/promises' | ||
import path from 'path' | ||
|
||
const dir = path.join(path.dirname(new URL(import.meta.url).pathname), '../..') | ||
const logPath = path.join(dir, 'output-log.json') | ||
|
||
export async function POST(req) { | ||
let payloadString = '' | ||
const decoder = new TextDecoder() | ||
const reader = req.clone().body.getReader() | ||
while (true) { | ||
const { done, value } = await reader.read() | ||
if (done) { | ||
break | ||
} | ||
|
||
payloadString += decoder.decode(value) | ||
} | ||
|
||
const payload = JSON.parse(payloadString) | ||
|
||
const json = fs.existsSync(logPath) | ||
? JSON.parse(await fsp.readFile(logPath, 'utf8')) | ||
: {} | ||
|
||
if (!json[payload.message]) { | ||
json[payload.message] = { | ||
payload, | ||
count: 1, | ||
} | ||
} else { | ||
json[payload.message].count++ | ||
} | ||
|
||
await fsp.writeFile(logPath, JSON.stringify(json, null, 2), 'utf8') | ||
|
||
console.log(`[instrumentation] write-log:${payload.message}`) | ||
return new Response(null, { status: 204 }) | ||
} |
147 changes: 147 additions & 0 deletions
147
test/e2e/on-request-error/dynamic-routes/dynamic-routes.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import { nextTestSetup } from 'e2e-utils' | ||
import { retry } from 'next-test-utils' | ||
import { getOutputLogJson } from '../_testing/utils' | ||
|
||
describe('on-request-error - dynamic-routes', () => { | ||
const { next, skipped } = nextTestSetup({ | ||
files: __dirname, | ||
skipDeployment: true, | ||
env: { | ||
__NEXT_EXPERIMENTAL_INSTRUMENTATION: '1', | ||
}, | ||
}) | ||
|
||
if (skipped) { | ||
return | ||
} | ||
|
||
const outputLogPath = 'output-log.json' | ||
|
||
async function getErrorRecord({ errorMessage }: { errorMessage: string }) { | ||
// Assert the instrumentation is called | ||
await retry(async () => { | ||
const recordLogLines = next.cliOutput | ||
.split('\n') | ||
.filter((log) => log.includes('[instrumentation] write-log')) | ||
expect(recordLogLines).toEqual( | ||
expect.arrayContaining([expect.stringContaining(errorMessage)]) | ||
) | ||
}, 5000) | ||
|
||
const json = await getOutputLogJson(next, outputLogPath) | ||
const record = json[errorMessage] | ||
|
||
return record | ||
} | ||
|
||
beforeAll(async () => { | ||
await next.patchFile(outputLogPath, '{}') | ||
}) | ||
|
||
describe('app router', () => { | ||
it('should catch app router dynamic page error with search params', async () => { | ||
await next.fetch('/app-page/dynamic/123?apple=dope') | ||
const record = await getErrorRecord({ | ||
errorMessage: 'server-dynamic-page-node-error', | ||
}) | ||
expect(record).toMatchObject({ | ||
payload: { | ||
message: 'server-dynamic-page-node-error', | ||
request: { | ||
url: '/app-page/dynamic/123?apple=dope', | ||
}, | ||
context: { | ||
routerKind: 'App Router', | ||
routeType: 'render', | ||
routePath: '/app-page/dynamic/[id]', | ||
}, | ||
}, | ||
}) | ||
}) | ||
|
||
it('should catch app router dynamic routes error with search params', async () => { | ||
await next.fetch('/app-route/dynamic/123?apple=dope') | ||
const record = await getErrorRecord({ | ||
errorMessage: 'server-dynamic-route-node-error', | ||
}) | ||
expect(record).toMatchObject({ | ||
payload: { | ||
message: 'server-dynamic-route-node-error', | ||
request: { | ||
url: '/app-route/dynamic/123?apple=dope', | ||
}, | ||
context: { | ||
routerKind: 'App Router', | ||
routeType: 'route', | ||
routePath: '/app-route/dynamic/[id]', | ||
}, | ||
}, | ||
}) | ||
}) | ||
|
||
it('should catch suspense rendering page error in node runtime', async () => { | ||
await next.fetch('/app-page/suspense') | ||
const record = await getErrorRecord({ | ||
errorMessage: 'server-suspense-page-node-error', | ||
}) | ||
|
||
expect(record).toMatchObject({ | ||
payload: { | ||
message: 'server-suspense-page-node-error', | ||
request: { | ||
url: '/app-page/suspense', | ||
}, | ||
context: { | ||
routerKind: 'App Router', | ||
routeType: 'render', | ||
routePath: '/app-page/suspense', | ||
}, | ||
}, | ||
}) | ||
}) | ||
}) | ||
|
||
describe('pages router', () => { | ||
it('should catch pages router dynamic page error with search params', async () => { | ||
await next.fetch('/pages-page/dynamic/123?apple=dope') | ||
const record = await getErrorRecord({ | ||
errorMessage: 'pages-page-node-error', | ||
}) | ||
|
||
expect(record).toMatchObject({ | ||
payload: { | ||
message: 'pages-page-node-error', | ||
request: { | ||
url: '/pages-page/dynamic/123?apple=dope', | ||
}, | ||
context: { | ||
routerKind: 'Pages Router', | ||
routeType: 'render', | ||
routePath: '/pages-page/dynamic/[id]', | ||
}, | ||
}, | ||
}) | ||
}) | ||
|
||
it('should catch pages router dynamic API route error with search params', async () => { | ||
await next.fetch('/api/dynamic/123?apple=dope') | ||
const record = await getErrorRecord({ | ||
errorMessage: 'pages-api-node-error', | ||
}) | ||
|
||
expect(record).toMatchObject({ | ||
payload: { | ||
message: 'pages-api-node-error', | ||
request: { | ||
url: '/api/dynamic/123?apple=dope', | ||
}, | ||
context: { | ||
routerKind: 'Pages Router', | ||
routeType: 'route', | ||
routePath: '/api/dynamic/[id]', | ||
}, | ||
}, | ||
}) | ||
}) | ||
}) | ||
}) |
13 changes: 13 additions & 0 deletions
13
test/e2e/on-request-error/dynamic-routes/instrumentation.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export function onRequestError(err, request, context) { | ||
fetch(`http://localhost:${process.env.PORT}/write-log`, { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
message: err.message, | ||
request, | ||
context, | ||
}), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
experimental: { | ||
instrumentationHook: true, | ||
}, | ||
} |
3 changes: 3 additions & 0 deletions
3
test/e2e/on-request-error/dynamic-routes/pages/api/dynamic/[id].js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function handler() { | ||
throw new Error('pages-api-node-error') | ||
} |
9 changes: 9 additions & 0 deletions
9
test/e2e/on-request-error/dynamic-routes/pages/pages-page/dynamic/[id].js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export default function Page() { | ||
throw new Error('pages-page-node-error') | ||
} | ||
|
||
export function getServerSideProps() { | ||
return { | ||
props: {}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters