Skip to content

Commit 693ca47

Browse files
authored
test(nextjs): Added nextjs CF workers test app (#18928)
This PR sets up E2E tests for Next.js 16 running on Cloudflare Workers using OpenNext. Some tests yield different transaction names and span attributes, I will review each of the skipped tests and review the differences and if we should either consolidate the edge runtime behavior with the node runtime behavior. ### Known Limitations Those are the test failures that required skipping. - Middleware `proxy` filename not being picked up by opennext, yet `middleware` works on Next 16 😕 - HTTP request headers not extracted as span attributes - Metrics not emitting on Cloudflare Workers - Middleware `transaction_info.source` is `'url'` instead of `'route'` - Server component spans have different names (e.g., `'resolve segment modules'` instead of specific component names) - Missing `http.response.status_code` / `http.status_code` attributes I plan to follow up with another PR to address these, but the higher priority is making sure the SDK doesn't crash and works to some degree on CF worker apps. Closes #18929 (added automatically)
1 parent 75f0e20 commit 693ca47

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1535
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
.yarn/*
8+
!.yarn/patches
9+
!.yarn/plugins
10+
!.yarn/releases
11+
!.yarn/versions
12+
13+
# testing
14+
/coverage
15+
16+
# next.js
17+
/.next/
18+
/out/
19+
20+
# production
21+
/build
22+
23+
# misc
24+
.DS_Store
25+
*.pem
26+
27+
# debug
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
.pnpm-debug.log*
32+
33+
# env files (can opt-in for committing if needed)
34+
.env*
35+
36+
# vercel
37+
.vercel
38+
39+
# typescript
40+
*.tsbuildinfo
41+
next-env.d.ts
42+
43+
# Sentry Config File
44+
.env.sentry-build-plugin
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { PropsWithChildren } from 'react';
2+
3+
export const dynamic = 'force-dynamic';
4+
5+
export default function Layout({ children }: PropsWithChildren<{}>) {
6+
return (
7+
<div>
8+
<p>Layout</p>
9+
{children}
10+
</div>
11+
);
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { PropsWithChildren } from 'react';
2+
3+
export const dynamic = 'force-dynamic';
4+
5+
export default function Layout({ children }: PropsWithChildren<{}>) {
6+
return (
7+
<div>
8+
<p>DynamicLayout</p>
9+
{children}
10+
</div>
11+
);
12+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const dynamic = 'force-dynamic';
2+
3+
export default async function Page() {
4+
return (
5+
<div>
6+
<p>Dynamic Page</p>
7+
</div>
8+
);
9+
}
10+
11+
export async function generateMetadata() {
12+
return {
13+
title: 'I am dynamic page generated metadata',
14+
};
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { PropsWithChildren } from 'react';
2+
3+
export const dynamic = 'force-dynamic';
4+
5+
export default function Layout({ children }: PropsWithChildren<{}>) {
6+
return (
7+
<div>
8+
<p>Layout</p>
9+
{children}
10+
</div>
11+
);
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const dynamic = 'force-dynamic';
2+
3+
export default function Page() {
4+
return <p>Hello World!</p>;
5+
}
6+
7+
export async function generateMetadata() {
8+
return {
9+
title: 'I am generated metadata',
10+
};
11+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function GET() {
2+
return Response.json({ name: 'John Doe' });
3+
}
Binary file not shown.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use client';
2+
3+
import * as Sentry from '@sentry/nextjs';
4+
import NextError from 'next/error';
5+
import { useEffect } from 'react';
6+
7+
export default function GlobalError({ error }: { error: Error & { digest?: string } }) {
8+
useEffect(() => {
9+
Sentry.captureException(error);
10+
}, [error]);
11+
12+
return (
13+
<html>
14+
<body>
15+
{/* `NextError` is the default Next.js error page component. Its type
16+
definition requires a `statusCode` prop. However, since the App Router
17+
does not expose status codes for errors, we simply pass 0 to render a
18+
generic error message. */}
19+
<NextError statusCode={0} />
20+
</body>
21+
</html>
22+
);
23+
}

0 commit comments

Comments
 (0)