diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/.gitignore b/dev-packages/e2e-tests/test-applications/create-next-app/.gitignore
deleted file mode 100644
index d9f766878259..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/.gitignore
+++ /dev/null
@@ -1,41 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# next.js
-/.next/
-/out/
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-.pnpm-debug.log*
-
-# local env files
-.env*.local
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
-next-env.d.ts
-
-!*.d.ts
-
-# Sentry
-.sentryclirc
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/.npmrc b/dev-packages/e2e-tests/test-applications/create-next-app/.npmrc
deleted file mode 100644
index 070f80f05092..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/.npmrc
+++ /dev/null
@@ -1,2 +0,0 @@
-@sentry:registry=http://127.0.0.1:4873
-@sentry-internal:registry=http://127.0.0.1:4873
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/globals.d.ts b/dev-packages/e2e-tests/test-applications/create-next-app/globals.d.ts
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/instrumentation.ts b/dev-packages/e2e-tests/test-applications/create-next-app/instrumentation.ts
deleted file mode 100644
index dd214cc7a7bc..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/instrumentation.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as Sentry from '@sentry/nextjs';
-
-export function register() {
- if (process.env.NEXT_RUNTIME === 'nodejs') {
- Sentry.init({
- environment: 'qa', // dynamic sampling bias to keep transactions
- dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
- // Adjust this value in production, or use tracesSampler for greater control
- tracesSampleRate: 1.0,
- tunnel: 'http://localhost:3031',
- });
- }
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/next-env.d.ts b/dev-packages/e2e-tests/test-applications/create-next-app/next-env.d.ts
deleted file mode 100644
index 4f11a03dc6cc..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/next-env.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-///
-///
-
-// NOTE: This file should not be edited
-// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/next.config.js b/dev-packages/e2e-tests/test-applications/create-next-app/next.config.js
deleted file mode 100644
index 5de673a830d7..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/next.config.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const { withSentryConfig } = require('@sentry/nextjs');
-
-module.exports = withSentryConfig();
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/package.json b/dev-packages/e2e-tests/test-applications/create-next-app/package.json
deleted file mode 100644
index b484016785b9..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "create-next-app",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "build": "next build",
- "clean": "npx rimraf node_modules pnpm-lock.yaml .next",
- "test:prod": "TEST_ENV=prod playwright test",
- "test:dev": "TEST_ENV=dev playwright test",
- "test:build": "pnpm install && pnpm build",
- "test:build-13": "pnpm install && pnpm add next@13.5.11 && pnpm build",
- "test:assert": "pnpm test:prod && pnpm test:dev"
- },
- "dependencies": {
- "@sentry/nextjs": "latest || *",
- "@types/node": "^18.19.1",
- "@types/react": "18.0.26",
- "@types/react-dom": "18.0.9",
- "next": "14.2.35",
- "react": "18.2.0",
- "react-dom": "18.2.0",
- "typescript": "~5.0.0"
- },
- "devDependencies": {
- "@playwright/test": "~1.56.0",
- "@sentry-internal/test-utils": "link:../../../test-utils"
- },
- "volta": {
- "extends": "../../package.json"
- },
- "sentryTest": {
- "variants": [
- {
- "build-command": "pnpm test:build-13",
- "label": "create-next-app (next@13)"
- }
- ]
- }
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/_app.tsx b/dev-packages/e2e-tests/test-applications/create-next-app/pages/_app.tsx
deleted file mode 100644
index da826ed16c72..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/_app.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import type { AppProps } from 'next/app';
-
-export default function App({ Component, pageProps }: AppProps) {
- return ;
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/_document.tsx b/dev-packages/e2e-tests/test-applications/create-next-app/pages/_document.tsx
deleted file mode 100644
index af2f1aba391f..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/_document.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Head, Html, Main, NextScript } from 'next/document';
-
-export default function Document() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/_error.tsx b/dev-packages/e2e-tests/test-applications/create-next-app/pages/_error.tsx
deleted file mode 100644
index fb1fca2a0ad7..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/_error.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * NOTE: This requires `@sentry/nextjs` version 7.3.0 or higher.
- *
- * NOTE: If using this with `next` version 12.2.0 or lower, uncomment the
- * penultimate line in `CustomErrorComponent`.
- *
- * This page is loaded by Nextjs:
- * - on the server, when data-fetching methods throw or reject
- * - on the client, when `getInitialProps` throws or rejects
- * - on the client, when a React lifecycle method throws or rejects, and it's
- * caught by the built-in Nextjs error boundary
- *
- * See:
- * - https://nextjs.org/docs/basic-features/data-fetching/overview
- * - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
- * - https://reactjs.org/docs/error-boundaries.html
- */
-
-import * as Sentry from '@sentry/nextjs';
-import { NextPageContext } from 'next';
-import NextErrorComponent from 'next/error';
-
-const CustomErrorComponent = (props: { statusCode: any }) => {
- // If you're using a Nextjs version prior to 12.2.1, uncomment this to
- // compensate for https://github.com/vercel/next.js/issues/8592
- // Sentry.captureUnderscoreErrorException(props);
-
- return ;
-};
-
-CustomErrorComponent.getInitialProps = async (contextData: NextPageContext) => {
- // In case this is running in a serverless function, await this in order to give Sentry
- // time to send the error before the lambda exits
- await Sentry.captureUnderscoreErrorException(contextData);
-
- // This will contain the status code of the response
- return NextErrorComponent.getInitialProps(contextData);
-};
-
-export default CustomErrorComponent;
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/api/error.ts b/dev-packages/e2e-tests/test-applications/create-next-app/pages/api/error.ts
deleted file mode 100644
index 6debfd151870..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/api/error.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
-import type { NextApiRequest, NextApiResponse } from 'next';
-
-export default async function handler(req: NextApiRequest, res: NextApiResponse) {
- throw new Error('I am a server error!');
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts b/dev-packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts
deleted file mode 100644
index d3504dc73d98..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/api/success.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import * as Sentry from '@sentry/nextjs';
-// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
-import type { NextApiRequest, NextApiResponse } from 'next';
-
-export default function handler(req: NextApiRequest, res: NextApiResponse) {
- Sentry.startSpan({ name: 'test-span' }, () => undefined);
-
- Sentry.flush().then(() => {
- res.status(200).json({});
- });
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/index.tsx b/dev-packages/e2e-tests/test-applications/create-next-app/pages/index.tsx
deleted file mode 100644
index 6bb62f18deb4..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/index.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import Head from 'next/head';
-import Link from 'next/link';
-
-export default function Home() {
- return (
- <>
-
- Create Next App
-
-
-
-
-
- {
- throw new Error('I am an error!');
- }}
- />
-
- navigate
-
-
- >
- );
-}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/create-next-app/playwright.config.mjs
deleted file mode 100644
index f97facbf0cc5..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/playwright.config.mjs
+++ /dev/null
@@ -1,13 +0,0 @@
-import { getPlaywrightConfig } from '@sentry-internal/test-utils';
-
-const testEnv = process.env.TEST_ENV;
-
-if (!testEnv) {
- throw new Error('No test env defined');
-}
-
-const config = getPlaywrightConfig({
- startCommand: testEnv === 'development' ? `pnpm next dev -p 3030` : `pnpm next start -p 3030`,
-});
-
-export default config;
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/sentry.client.config.ts b/dev-packages/e2e-tests/test-applications/create-next-app/sentry.client.config.ts
deleted file mode 100644
index e24170711a83..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/sentry.client.config.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// This file configures the initialization of Sentry on the browser.
-// The config you add here will be used whenever a page is visited.
-// https://docs.sentry.io/platforms/javascript/guides/nextjs/
-
-import * as Sentry from '@sentry/nextjs';
-
-Sentry.init({
- environment: 'qa', // dynamic sampling bias to keep transactions
- dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
- tracesSampleRate: 1.0,
- tunnel: 'http://localhost:3031',
-});
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/create-next-app/start-event-proxy.mjs
deleted file mode 100644
index db6c74e4afe3..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/start-event-proxy.mjs
+++ /dev/null
@@ -1,6 +0,0 @@
-import { startEventProxyServer } from '@sentry-internal/test-utils';
-
-startEventProxyServer({
- port: 3031,
- proxyServerName: 'create-next-app',
-});
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts
deleted file mode 100644
index e0effa285b9f..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { expect, test } from '@playwright/test';
-import { waitForError } from '@sentry-internal/test-utils';
-
-test('Sends a client-side exception to Sentry', async ({ page }) => {
- const errorEventPromise = waitForError('create-next-app', event => {
- return event.exception?.values?.[0]?.value === 'I am an error!';
- });
-
- await page.goto('/');
-
- const exceptionButton = page.locator('id=exception-button');
- await exceptionButton.click();
-
- const errorEvent = await errorEventPromise;
-
- expect(errorEvent.exception?.values).toHaveLength(1);
- expect(errorEvent.exception?.values?.[0]?.value).toBe('I am an error!');
-
- expect(errorEvent.request).toEqual({
- headers: expect.any(Object),
- url: 'http://localhost:3030/',
- });
-
- expect(errorEvent.transaction).toEqual('/');
-
- expect(errorEvent.contexts?.trace).toEqual({
- trace_id: expect.stringMatching(/[a-f0-9]{32}/),
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- });
-});
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts
deleted file mode 100644
index a539216efee7..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { expect, test } from '@playwright/test';
-import { waitForTransaction } from '@sentry-internal/test-utils';
-
-test('Sends a pageload transaction to Sentry', async ({ page }) => {
- const pageloadTransactionEventPromise = waitForTransaction('create-next-app', transactionEvent => {
- return transactionEvent.contexts?.trace?.op === 'pageload' && transactionEvent.transaction === '/';
- });
-
- await page.goto('/');
-
- const transactionEvent = await pageloadTransactionEventPromise;
-
- expect(transactionEvent).toEqual(
- expect.objectContaining({
- transaction: '/',
- transaction_info: { source: 'route' },
- type: 'transaction',
- contexts: {
- react: {
- version: '18.2.0',
- },
- trace: {
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- trace_id: expect.stringMatching(/[a-f0-9]{32}/),
- op: 'pageload',
- origin: 'auto.pageload.nextjs.pages_router_instrumentation',
- status: 'ok',
- data: expect.objectContaining({
- 'sentry.idle_span_finish_reason': 'idleTimeout',
- 'sentry.op': 'pageload',
- 'sentry.origin': 'auto.pageload.nextjs.pages_router_instrumentation',
- 'sentry.sample_rate': 1,
- 'sentry.source': 'route',
- }),
- },
- },
- request: {
- headers: {
- 'User-Agent': expect.any(String),
- },
- url: 'http://localhost:3030/',
- },
- }),
- );
-});
-
-test('captures a navigation transaction to Sentry', async ({ page }) => {
- const clientNavigationTxnEventPromise = waitForTransaction('create-next-app', txnEvent => {
- return txnEvent?.transaction === '/user/[id]';
- });
-
- await page.goto('/');
-
- // navigation to page
- const clickPromise = page.getByText('navigate').click();
-
- const [clientTxnEvent, serverTxnEvent] = await Promise.all([clientNavigationTxnEventPromise, clickPromise]);
-
- expect(clientTxnEvent).toEqual(
- expect.objectContaining({
- transaction: '/user/[id]',
- transaction_info: { source: 'route' },
- type: 'transaction',
- contexts: {
- react: {
- version: '18.2.0',
- },
- trace: {
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- trace_id: expect.stringMatching(/[a-f0-9]{32}/),
- op: 'navigation',
- origin: 'auto.navigation.nextjs.pages_router_instrumentation',
- status: 'ok',
- data: expect.objectContaining({
- 'sentry.idle_span_finish_reason': 'idleTimeout',
- 'sentry.op': 'navigation',
- 'sentry.origin': 'auto.navigation.nextjs.pages_router_instrumentation',
- 'sentry.sample_rate': 1,
- 'sentry.source': 'route',
- }),
- links: [
- {
- attributes: {
- 'sentry.link.type': 'previous_trace',
- },
- sampled: true,
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- trace_id: expect.stringMatching(/[a-f0-9]{32}/),
- },
- ],
- },
- },
- request: {
- headers: {
- 'User-Agent': expect.any(String),
- },
- url: 'http://localhost:3030/user/5',
- },
- }),
- );
-});
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts
deleted file mode 100644
index 08a47ace671f..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { expect, test } from '@playwright/test';
-import { waitForError } from '@sentry-internal/test-utils';
-
-test('Sends a server-side exception to Sentry', async ({ baseURL }) => {
- const errorEventPromise = waitForError('create-next-app', event => {
- return event.exception?.values?.[0]?.value === 'I am a server error!';
- });
-
- const response = await fetch(`${baseURL}/api/error`);
-
- expect(response.status).toBe(500);
-
- const errorEvent = await errorEventPromise;
-
- expect(errorEvent.exception?.values).toHaveLength(1);
- expect(errorEvent.exception?.values?.[0]?.value).toBe('I am a server error!');
-
- expect(errorEvent.request).toEqual({
- headers: expect.any(Object),
- cookies: {},
- method: 'GET',
- url: expect.stringContaining('/api/error'),
- });
-
- expect(errorEvent.transaction).toEqual('GET /api/error');
-
- expect(errorEvent.contexts?.trace).toEqual({
- trace_id: expect.stringMatching(/[a-f0-9]{32}/),
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- });
-});
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts
deleted file mode 100644
index 731d1820ee61..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { expect, test } from '@playwright/test';
-import { waitForTransaction } from '@sentry-internal/test-utils';
-
-test('Sends server-side transactions to Sentry', async ({ baseURL }) => {
- const transactionEventPromise = waitForTransaction('create-next-app', transactionEvent => {
- return (
- transactionEvent.contexts?.trace?.op === 'http.server' && transactionEvent.transaction === 'GET /api/success'
- );
- });
-
- await fetch(`${baseURL}/api/success`);
-
- const transactionEvent = await transactionEventPromise;
-
- expect(transactionEvent).toEqual(
- expect.objectContaining({
- transaction: 'GET /api/success',
- transaction_info: { source: 'route' },
- type: 'transaction',
- contexts: expect.objectContaining({
- trace: {
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- trace_id: expect.stringMatching(/[a-f0-9]{32}/),
- op: 'http.server',
- origin: 'auto.http.nextjs',
- data: expect.objectContaining({
- 'http.response.status_code': 200,
- 'sentry.op': 'http.server',
- 'sentry.origin': 'auto.http.nextjs',
- 'sentry.sample_rate': 1,
- 'sentry.source': 'route',
- }),
- status: 'ok',
- },
- }),
- spans: [
- {
- data: {
- 'sentry.origin': 'manual',
- },
- description: 'test-span',
- origin: 'manual',
- parent_span_id: transactionEvent.contexts?.trace?.span_id,
- span_id: expect.stringMatching(/[a-f0-9]{16}/),
- start_timestamp: expect.any(Number),
- status: 'ok',
- timestamp: expect.any(Number),
- trace_id: transactionEvent.contexts?.trace?.trace_id,
- },
- ],
- request: {
- headers: expect.any(Object),
- method: 'GET',
- cookies: {},
- url: expect.stringContaining('/api/success'),
- },
- }),
- );
-});
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tsconfig.json b/dev-packages/e2e-tests/test-applications/create-next-app/tsconfig.json
deleted file mode 100644
index 73c09112c46a..000000000000
--- a/dev-packages/e2e-tests/test-applications/create-next-app/tsconfig.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "incremental": true
- },
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next.config.js"],
- "exclude": ["node_modules"]
-}
diff --git a/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/index.tsx b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/index.tsx
index 109542e2fba5..9dd0cc0aaa96 100644
--- a/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/index.tsx
+++ b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/index.tsx
@@ -1,3 +1,4 @@
+import Link from 'next/link';
import { ClientErrorDebugTools } from '../components/client-error-debug-tools';
export default function Page() {
@@ -5,6 +6,9 @@ export default function Page() {
Page (/)
+
+ navigate
+
);
}
diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/pages/user/[id].tsx b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/user/[id].tsx
similarity index 54%
rename from dev-packages/e2e-tests/test-applications/create-next-app/pages/user/[id].tsx
rename to dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/user/[id].tsx
index 08f65a85273d..7c7aff559fd1 100644
--- a/dev-packages/e2e-tests/test-applications/create-next-app/pages/user/[id].tsx
+++ b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/pages/user/[id].tsx
@@ -1,5 +1,5 @@
const User = () => {
- return I am a blank page :)
;
+ return I am a user page
;
};
export default User;
diff --git a/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/transactions.test.ts
index 5b648065e45a..9d9dd6e90168 100644
--- a/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/transactions.test.ts
+++ b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/transactions.test.ts
@@ -50,3 +50,61 @@ test('Sends a pageload transaction', async ({ page }) => {
}),
);
});
+
+test('Sends a navigation transaction', async ({ page }) => {
+ // Skip in dev mode - flaky due to slow compilation affecting transaction timing
+ test.skip(isDevMode, 'Skipped in dev mode due to flakiness from slow compilation');
+
+ await page.goto('/');
+
+ const clientNavigationTxnEventPromise = waitForTransaction('nextjs-pages-dir', txnEvent => {
+ return txnEvent?.contexts?.trace?.op === 'navigation' && txnEvent?.transaction === '/user/[id]';
+ });
+
+ await page.getByText('navigate').click();
+
+ const clientTxnEvent = await clientNavigationTxnEventPromise;
+
+ expect(clientTxnEvent).toEqual(
+ expect.objectContaining({
+ transaction: '/user/[id]',
+ transaction_info: { source: 'route' },
+ type: 'transaction',
+ contexts: {
+ react: {
+ version: expect.any(String),
+ },
+ trace: {
+ span_id: expect.stringMatching(/[a-f0-9]{16}/),
+ trace_id: expect.stringMatching(/[a-f0-9]{32}/),
+ op: 'navigation',
+ origin: 'auto.navigation.nextjs.pages_router_instrumentation',
+ status: 'ok',
+ data: expect.objectContaining({
+ 'sentry.idle_span_finish_reason': 'idleTimeout',
+ 'sentry.op': 'navigation',
+ 'sentry.origin': 'auto.navigation.nextjs.pages_router_instrumentation',
+ 'sentry.sample_rate': 1,
+ 'sentry.source': 'route',
+ }),
+ links: [
+ {
+ attributes: {
+ 'sentry.link.type': 'previous_trace',
+ },
+ sampled: true,
+ span_id: expect.stringMatching(/[a-f0-9]{16}/),
+ trace_id: expect.stringMatching(/[a-f0-9]{32}/),
+ },
+ ],
+ },
+ },
+ request: {
+ headers: {
+ 'User-Agent': expect.any(String),
+ },
+ url: 'http://localhost:3030/user/5',
+ },
+ }),
+ );
+});