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', + }, + }), + ); +});