diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 76d2ade83d15..9afeaec5947a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -595,56 +595,6 @@ jobs: - name: Unit Test run: yarn lerna run test --scope @sentry/profiling-node - job_nextjs_integration_test: - name: Nextjs (Node ${{ matrix.node }}) Tests - needs: [job_get_metadata, job_build] - if: needs.job_get_metadata.outputs.changed_nextjs == 'true' || github.event_name != 'pull_request' - timeout-minutes: 25 - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - node: [14, 16, 18, 20, 22] - steps: - - name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }}) - uses: actions/checkout@v4 - with: - ref: ${{ env.HEAD_COMMIT }} - - name: Set up Node - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - - name: Restore caches - uses: ./.github/actions/restore-cache - env: - DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }} - - name: Get npm cache directory - id: npm-cache-dir - run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT - - name: Get Playwright version - id: playwright-version - run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT - - uses: actions/cache@v4 - name: Check if Playwright browser is cached - id: playwright-cache - with: - path: ${{ steps.npm-cache-dir.outputs.dir }} - key: ${{ runner.os }}-Playwright-${{steps.playwright-version.outputs.version}} - - name: Install Playwright browser if not cached - if: steps.playwright-cache.outputs.cache-hit != 'true' - run: npx playwright install --with-deps - env: - PLAYWRIGHT_BROWSERS_PATH: ${{steps.npm-cache-dir.outputs.dir}} - - name: Install OS dependencies of Playwright if cache hit - if: steps.playwright-cache.outputs.cache-hit == 'true' - run: npx playwright install-deps - - name: Run tests - env: - NODE_VERSION: ${{ matrix.node }} - run: | - cd packages/nextjs - yarn test:integration - job_browser_playwright_tests: name: Playwright (${{ matrix.bundle }}${{ matrix.shard && format(' {0}/{1}', matrix.shard, matrix.shards) || ''}}) Tests needs: [job_get_metadata, job_build] @@ -1328,7 +1278,6 @@ jobs: job_deno_unit_tests, job_node_unit_tests, job_profiling_node_unit_tests, - job_nextjs_integration_test, job_node_integration_tests, job_browser_playwright_tests, job_browser_loader_tests, diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/package.json b/dev-packages/e2e-tests/test-applications/nextjs-13/package.json index 3f1219f210a2..5be9ecbfc32c 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/package.json @@ -24,17 +24,17 @@ }, "devDependencies": { "@playwright/test": "^1.44.1", - "@sentry-internal/test-utils": "link:../../../test-utils", + "@sentry-internal/browser-utils": "latest || *", "@sentry-internal/feedback": "latest || *", + "@sentry-internal/replay": "latest || *", "@sentry-internal/replay-canvas": "latest || *", - "@sentry-internal/browser-utils": "latest || *", + "@sentry-internal/test-utils": "link:../../../test-utils", "@sentry/browser": "latest || *", "@sentry/core": "latest || *", "@sentry/nextjs": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", "@sentry/react": "latest || *", - "@sentry-internal/replay": "latest || *", "@sentry/types": "latest || *", "@sentry/utils": "latest || *", "@sentry/vercel-edge": "latest || *" diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-regex.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-regex.ts index 6ae521fa5cb4..5bb9ddca1270 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-regex.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-regex.ts @@ -1,7 +1,5 @@ import { NextApiRequest, NextApiResponse } from 'next'; -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { +export default async (_req: NextApiRequest, res: NextApiResponse): Promise => { res.status(200).json({ success: true }); }; - -module.exports = handler; diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-string.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-string.ts index 6ae521fa5cb4..5bb9ddca1270 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-string.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/pages/api/endpoint-excluded-with-string.ts @@ -1,7 +1,5 @@ import { NextApiRequest, NextApiResponse } from 'next'; -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { +export default async (_req: NextApiRequest, res: NextApiResponse): Promise => { res.status(200).json({ success: true }); }; - -module.exports = handler; diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts index 8a0ed1176142..8ef79f8cf146 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts @@ -1,7 +1,13 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; +const packageJson = require('../../package.json'); +const nextjsVersion = packageJson.dependencies.next; +const nextjsMajor = Number(nextjsVersion.split('.')[0]); + test('should create a transaction for a CJS pages router API endpoint', async ({ request }) => { + test.skip(nextjsMajor > 13, 'Next.js does not like CJS routes after a certain point.'); + const transactionPromise = waitForTransaction('nextjs-13', async transactionEvent => { return ( transactionEvent.transaction === 'GET /api/cjs-api-endpoint' && @@ -62,6 +68,8 @@ test('should create a transaction for a CJS pages router API endpoint', async ({ }); test('should not mess up require statements in CJS API endpoints', async ({ request }) => { + test.skip(nextjsMajor > 13, 'Next.js does not like CJS routes after a certain point.'); + const transactionPromise = waitForTransaction('nextjs-13', async transactionEvent => { return ( transactionEvent.transaction === 'GET /api/cjs-api-endpoint-with-require' && diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/excluded-api-endpoints.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/excluded-api-endpoints.test.ts index b148accf1450..63082fee6e07 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/excluded-api-endpoints.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/excluded-api-endpoints.test.ts @@ -11,7 +11,7 @@ test('should not automatically create transactions for routes that were excluded ); }); - await (await request.get(`/api/endpoint-excluded-with-string`)).json(); + expect(await (await request.get(`/api/endpoint-excluded-with-string`)).text()).toBe('{"success":true}'); let transactionPromiseReceived = false; transactionPromise.then(() => { @@ -33,7 +33,7 @@ test('should not automatically create transactions for routes that were excluded ); }); - await (await request.get(`/api/endpoint-excluded-with-regex`)).json(); + expect(await (await request.get(`/api/endpoint-excluded-with-regex`)).text()).toBe('{"success":true}'); let transactionPromiseReceived = false; transactionPromise.then(() => { diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts index 600e2b6eda53..0303fe6e583f 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts @@ -12,7 +12,6 @@ test('Should capture an error thrown in a server component', async ({ page }) => contexts: { runtime: { name: 'node', version: expect.any(String) }, trace: { - parent_span_id: expect.any(String), span_id: expect.any(String), trace_id: expect.any(String), }, @@ -27,7 +26,6 @@ test('Should capture an error thrown in a server component', async ({ page }) => }, ], }, - modules: { next: '13.2.0' }, platform: 'node', request: { cookies: expect.any(Object), diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts index 27bf728b42a5..6b25cb6f74f7 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts @@ -22,7 +22,6 @@ const cases = [ cases.forEach(({ name, url, transactionName }) => { test(`Should capture transactions for routes with various shapes (${name})`, async ({ request }) => { const transactionEventPromise = waitForTransaction('nextjs-13', transactionEvent => { - console.log({ t: transactionEvent.transaction }); return transactionEvent.transaction === transactionName && transactionEvent.contexts?.trace?.op === 'http.server'; }); diff --git a/packages/nextjs/.eslintrc.js b/packages/nextjs/.eslintrc.js index 885839f52e18..95ce15bc668f 100644 --- a/packages/nextjs/.eslintrc.js +++ b/packages/nextjs/.eslintrc.js @@ -6,7 +6,6 @@ module.exports = { parserOptions: { jsx: true, }, - ignorePatterns: ['test/integration/**', 'playwright.config.ts'], extends: ['../../.eslintrc.js'], rules: { '@sentry-internal/sdk/no-optional-chaining': 'off', diff --git a/packages/nextjs/jest.config.js b/packages/nextjs/jest.config.js index edaa219fa7be..fd23311e1656 100644 --- a/packages/nextjs/jest.config.js +++ b/packages/nextjs/jest.config.js @@ -2,5 +2,4 @@ const baseConfig = require('../../jest/jest.config.js'); module.exports = { ...baseConfig, - testPathIgnorePatterns: ['/test/integration/'], }; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index d44d5872ff08..1a651c7c6e43 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -115,12 +115,8 @@ "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", "test": "yarn test:unit", - "test:all": "run-s test:unit test:integration", + "test:all": "run-s test:unit", "test:unit": "jest", - "test:integration": "./test/run-integration-tests.sh && yarn test:types", - "test:integration:clean": "(cd test/integration && rimraf .cache node_modules build)", - "test:integration:client": "yarn playwright test test/integration/test/client/", - "test:integration:server": "(cd test/integration && yarn test:server)", "test:types": "cd test/types && yarn test", "test:watch": "jest --watch", "vercel:branch": "source vercel/set-up-branch-for-test-app-use.sh", diff --git a/packages/nextjs/playwright.config.ts b/packages/nextjs/playwright.config.ts deleted file mode 100644 index 97dfdd760da1..000000000000 --- a/packages/nextjs/playwright.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as path from 'path'; -import type { PlaywrightTestConfig } from '@playwright/test'; - -const config: PlaywrightTestConfig = { - retries: 0, // We do not accept flakes. - use: { - baseURL: 'http://localhost:3000', - }, - // Run tests inside of a single file in parallel - fullyParallel: true, - // Use 3 workers on CI, else use defaults (based on available CPU cores) - // Note that 3 is a random number selected to work well with our CI setup - workers: process.env.CI ? 3 : undefined, - webServer: { - cwd: path.join(__dirname, 'test', 'integration'), - command: 'yarn start', - port: 3000, - stdout: 'pipe', - stderr: 'pipe', - }, -}; - -export default config; diff --git a/packages/nextjs/test/integration/.gitignore b/packages/nextjs/test/integration/.gitignore deleted file mode 100644 index b302c94ed40c..000000000000 --- a/packages/nextjs/test/integration/.gitignore +++ /dev/null @@ -1,39 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -yarn.lock -package-lock.json - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel - -# Generated by Next.js 13 -.vscode diff --git a/packages/nextjs/test/integration/app/clientcomponent/layout.tsx b/packages/nextjs/test/integration/app/clientcomponent/layout.tsx deleted file mode 100644 index 71beffba2865..000000000000 --- a/packages/nextjs/test/integration/app/clientcomponent/layout.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function ({ children }: { children: React.ReactNode }) { - return <>{children}; -} diff --git a/packages/nextjs/test/integration/app/clientcomponent/page.tsx b/packages/nextjs/test/integration/app/clientcomponent/page.tsx deleted file mode 100644 index a1d45b38a939..000000000000 --- a/packages/nextjs/test/integration/app/clientcomponent/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -'use client'; - -export default function () { - return

I am a client component!

; -} diff --git a/packages/nextjs/test/integration/app/layout.tsx b/packages/nextjs/test/integration/app/layout.tsx deleted file mode 100644 index c8f9cee0b787..000000000000 --- a/packages/nextjs/test/integration/app/layout.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Layout({ children }: { children: React.ReactNode }) { - return ( - - {children} - - ); -} diff --git a/packages/nextjs/test/integration/app/servercomponent/layout.tsx b/packages/nextjs/test/integration/app/servercomponent/layout.tsx deleted file mode 100644 index 71beffba2865..000000000000 --- a/packages/nextjs/test/integration/app/servercomponent/layout.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function ({ children }: { children: React.ReactNode }) { - return <>{children}; -} diff --git a/packages/nextjs/test/integration/app/servercomponent/page.tsx b/packages/nextjs/test/integration/app/servercomponent/page.tsx deleted file mode 100644 index e3c4e8d06f61..000000000000 --- a/packages/nextjs/test/integration/app/servercomponent/page.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import * as Sentry from '@sentry/nextjs'; - -export default async function () { - // do some request so that next will render this component serverside for each new pageload - await fetch('http://example.com', { cache: 'no-store' }); - Sentry.captureException(new Error('I am an Error captured inside a server component')); - return

I am a server component!

; -} diff --git a/packages/nextjs/test/integration/components/Layout.tsx b/packages/nextjs/test/integration/components/Layout.tsx deleted file mode 100644 index 36b99f04720f..000000000000 --- a/packages/nextjs/test/integration/components/Layout.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import Head from 'next/head'; -import Link from 'next/link'; -import { ReactNode } from 'react'; - -type Props = { - children?: ReactNode; - title?: string; -}; - -const Layout = ({ children, title = 'This is the default title' }: Props) => ( -
- - {title} - - - -
- -
- {children} -
-
- Im here to stay (Footer) -
-
-); - -export default Layout; diff --git a/packages/nextjs/test/integration/components/List.tsx b/packages/nextjs/test/integration/components/List.tsx deleted file mode 100644 index fbcdfeb504c9..000000000000 --- a/packages/nextjs/test/integration/components/List.tsx +++ /dev/null @@ -1,20 +0,0 @@ -// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX -import * as React from 'react'; -import { User } from '../interfaces'; -import ListItem from './ListItem'; - -type Props = { - items: User[]; -}; - -const List = ({ items }: Props) => ( -
    - {items.map(item => ( -
  • - -
  • - ))} -
-); - -export default List; diff --git a/packages/nextjs/test/integration/components/ListDetail.tsx b/packages/nextjs/test/integration/components/ListDetail.tsx deleted file mode 100644 index 9b1417333c9f..000000000000 --- a/packages/nextjs/test/integration/components/ListDetail.tsx +++ /dev/null @@ -1,17 +0,0 @@ -// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX -import * as React from 'react'; - -import { User } from '../interfaces'; - -type ListDetailProps = { - item: User; -}; - -const ListDetail = ({ item: user }: ListDetailProps) => ( -
-

Detail for {user.name}

-

ID: {user.id}

-
-); - -export default ListDetail; diff --git a/packages/nextjs/test/integration/components/ListItem.tsx b/packages/nextjs/test/integration/components/ListItem.tsx deleted file mode 100644 index 9de97d32c7fb..000000000000 --- a/packages/nextjs/test/integration/components/ListItem.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Link from 'next/link'; -// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX -import React from 'react'; - -import { User } from '../interfaces'; - -type Props = { - data: User; -}; - -const ListItem = ({ data }: Props) => ( - - - {data.id}: {data.name} - - -); - -export default ListItem; diff --git a/packages/nextjs/test/integration/instrumentation.ts b/packages/nextjs/test/integration/instrumentation.ts deleted file mode 100644 index d3bf16c5b957..000000000000 --- a/packages/nextjs/test/integration/instrumentation.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as Sentry from '@sentry/nextjs'; - -export function register() { - if (process.env.NEXT_RUNTIME === 'nodejs') { - Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - tracesSampleRate: 1.0, - debug: !!process.env.SDK_DEBUG, - integrations: defaults => [ - ...defaults.filter( - integration => - // filter out `Console` since the tests are happening in the console and we don't need to record what's printed - // there, because we can see it (this makes debug logging much less noisy, since intercepted events which are - // printed to the console no longer create console breadcrumbs, which then get printed, creating even longer - // console breadcrumbs, which get printed, etc, etc) - integration.name !== 'Console', - ), - ], - }); - } -} diff --git a/packages/nextjs/test/integration/interfaces/index.ts b/packages/nextjs/test/integration/interfaces/index.ts deleted file mode 100644 index 0a4f06952a9c..000000000000 --- a/packages/nextjs/test/integration/interfaces/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -// You can include shared interfaces/types in a separate file -// and then use them in any component by importing them. For -// example, to import the interface below do: -// -// import { User } from 'path/to/interfaces'; - -export type User = { - id: number; - name: string; -}; diff --git a/packages/nextjs/test/integration/jest.config.js b/packages/nextjs/test/integration/jest.config.js deleted file mode 100644 index e9df7b66dc9f..000000000000 --- a/packages/nextjs/test/integration/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -const baseConfig = require('../../jest.config.js'); - -module.exports = { - ...baseConfig, - testMatch: [`${__dirname}/test/server/**/*.test.ts`], - testPathIgnorePatterns: [`${__dirname}/test/client`], - forceExit: true, - testTimeout: 30000, - setupFilesAfterEnv: [`${__dirname}/jest.setup.js`], - collectCoverage: false, -}; diff --git a/packages/nextjs/test/integration/jest.setup.js b/packages/nextjs/test/integration/jest.setup.js deleted file mode 100644 index 6360e753c4a5..000000000000 --- a/packages/nextjs/test/integration/jest.setup.js +++ /dev/null @@ -1,8 +0,0 @@ -global.console = { - ...console, - log: jest.fn(), - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), - // console.debug is available -}; diff --git a/packages/nextjs/test/integration/next-env.d.ts b/packages/nextjs/test/integration/next-env.d.ts deleted file mode 100644 index 4f11a03dc6cc..000000000000 --- a/packages/nextjs/test/integration/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/packages/nextjs/test/integration/next.config.js b/packages/nextjs/test/integration/next.config.js deleted file mode 100644 index e9e4e4e04b2e..000000000000 --- a/packages/nextjs/test/integration/next.config.js +++ /dev/null @@ -1,16 +0,0 @@ -const { withSentryConfig } = require('@sentry/nextjs'); - -const moduleExports = { - eslint: { - ignoreDuringBuilds: true, - }, - experimental: { - appDir: Number(process.env.NODE_MAJOR) >= 16, // experimental.appDir requires Node v16.8.0 or later. - }, - pageExtensions: ['jsx', 'js', 'tsx', 'ts', 'page.tsx'], -}; - -module.exports = withSentryConfig(moduleExports, { - debug: true, - excludeServerRoutes: ['/api/excludedEndpoints/excludedWithString', /\/api\/excludedEndpoints\/excludedWithRegExp/], -}); diff --git a/packages/nextjs/test/integration/next13.appdir.config.template b/packages/nextjs/test/integration/next13.appdir.config.template deleted file mode 100644 index e9e4e4e04b2e..000000000000 --- a/packages/nextjs/test/integration/next13.appdir.config.template +++ /dev/null @@ -1,16 +0,0 @@ -const { withSentryConfig } = require('@sentry/nextjs'); - -const moduleExports = { - eslint: { - ignoreDuringBuilds: true, - }, - experimental: { - appDir: Number(process.env.NODE_MAJOR) >= 16, // experimental.appDir requires Node v16.8.0 or later. - }, - pageExtensions: ['jsx', 'js', 'tsx', 'ts', 'page.tsx'], -}; - -module.exports = withSentryConfig(moduleExports, { - debug: true, - excludeServerRoutes: ['/api/excludedEndpoints/excludedWithString', /\/api\/excludedEndpoints\/excludedWithRegExp/], -}); diff --git a/packages/nextjs/test/integration/next13.config.template b/packages/nextjs/test/integration/next13.config.template deleted file mode 100644 index 815eba98e889..000000000000 --- a/packages/nextjs/test/integration/next13.config.template +++ /dev/null @@ -1,13 +0,0 @@ -const { withSentryConfig } = require('@sentry/nextjs'); - -const moduleExports = { - eslint: { - ignoreDuringBuilds: true, - }, - pageExtensions: ['jsx', 'js', 'tsx', 'ts', 'page.tsx'], -}; - -module.exports = withSentryConfig(moduleExports, { - debug: true, - excludeServerRoutes: ['/api/excludedEndpoints/excludedWithString', /\/api\/excludedEndpoints\/excludedWithRegExp/], -}); diff --git a/packages/nextjs/test/integration/package.json b/packages/nextjs/test/integration/package.json deleted file mode 100644 index f4c547b5b687..000000000000 --- a/packages/nextjs/test/integration/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "with-typescript", - "license": "MIT", - "scripts": { - "dev": "next", - "build": "next build", - "predebug": "source ../integration_test_utils.sh && link_monorepo_packages '../../..' && yarn build", - "start": "next start", - "pretest": "yarn build", - "test:client": "playwright test", - "test:server": "jest --forceExit --runInBand" - }, - "dependencies": { - "@sentry/nextjs": "file:../../", - "next": "latest", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@types/node": "^15.3.1", - "@types/react": "17.0.47", - "@types/react-dom": "17.0.17", - "nock": "^13.1.0", - "typescript": "4.9.5", - "yargs": "^16.2.0" - }, - "resolutions": { - "@sentry/browser": "file:../../../browser", - "@sentry/core": "file:../../../core", - "@sentry/node": "file:../../../node", - "@sentry/opentelemetry": "file:../../../opentelemetry", - "@sentry/react": "file:../../../react", - "@sentry-internal/browser-utils": "file:../../../browser-utils", - "@sentry-internal/replay": "file:../../../replay-internal", - "@sentry-internal/replay-canvas": "file:../../../replay-canvas", - "@sentry-internal/feedback": "file:../../../feedback", - "@sentry/types": "file:../../../types", - "@sentry/utils": "file:../../../utils", - "@sentry/vercel-edge": "file:../../../vercel-edge" - } -} diff --git a/packages/nextjs/test/integration/pages/[id]/errorClick.tsx b/packages/nextjs/test/integration/pages/[id]/errorClick.tsx deleted file mode 100644 index df55a4b32967..000000000000 --- a/packages/nextjs/test/integration/pages/[id]/errorClick.tsx +++ /dev/null @@ -1,11 +0,0 @@ -const ButtonPage = (): JSX.Element => ( - -); - -export default ButtonPage; diff --git a/packages/nextjs/test/integration/pages/[id]/withInitialProps.tsx b/packages/nextjs/test/integration/pages/[id]/withInitialProps.tsx deleted file mode 100644 index 8fa2f228e90d..000000000000 --- a/packages/nextjs/test/integration/pages/[id]/withInitialProps.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import Link from 'next/link'; - -const WithInitialPropsPage = ({ data }: { data: string }) => ( - <> -

WithInitialPropsPage {data}

- {/* @ts-ignore https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-custom-component-that-wraps-an-a-tag */} - - Go to withServerSideProps - - -); - -WithInitialPropsPage.getInitialProps = () => { - return { data: '[some getInitialProps data]' }; -}; - -export default WithInitialPropsPage; diff --git a/packages/nextjs/test/integration/pages/[id]/withServerSideProps.tsx b/packages/nextjs/test/integration/pages/[id]/withServerSideProps.tsx deleted file mode 100644 index 420f88856656..000000000000 --- a/packages/nextjs/test/integration/pages/[id]/withServerSideProps.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import Link from 'next/link'; - -const WithServerSidePropsPage = ({ data }: { data: string }) => ( - <> -

WithServerSidePropsPage {data}

- {/* @ts-ignore https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-custom-component-that-wraps-an-a-tag */} - - Go to withInitialProps - - -); - -export async function getServerSideProps() { - return { props: { data: '[some getServerSideProps data]' } }; -} - -export default WithServerSidePropsPage; diff --git a/packages/nextjs/test/integration/pages/_app.tsx b/packages/nextjs/test/integration/pages/_app.tsx deleted file mode 100644 index da1ab1154f15..000000000000 --- a/packages/nextjs/test/integration/pages/_app.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import App, { AppContext, AppProps } from 'next/app'; - -const MyApp = ({ Component, pageProps }: AppProps) => { - return ; -}; - -MyApp.getInitialProps = async (appContext: AppContext) => { - // This simulates user misconfiguration. Users should always call `App.getInitialProps(appContext)`, but they don't, - // so we have a test for this so we don't break their apps. - if (appContext.ctx.pathname === '/faultyAppGetInitialProps') { - return {}; - } - - const appProps = await App.getInitialProps(appContext); - return { ...appProps }; -}; - -export default MyApp; diff --git a/packages/nextjs/test/integration/pages/_document.tsx b/packages/nextjs/test/integration/pages/_document.tsx deleted file mode 100644 index 9479e30f712b..000000000000 --- a/packages/nextjs/test/integration/pages/_document.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import Document, { DocumentContext } from 'next/document'; - -class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - // Verify that wrapping correctly passes `this` - this.testFunction(); - - const initialProps = await Document.getInitialProps(ctx); - - return initialProps; - } - - static testFunction() { - // noop - } -} - -export default MyDocument; diff --git a/packages/nextjs/test/integration/pages/about.tsx b/packages/nextjs/test/integration/pages/about.tsx deleted file mode 100644 index 30cfcf130c54..000000000000 --- a/packages/nextjs/test/integration/pages/about.tsx +++ /dev/null @@ -1,3 +0,0 @@ -const AboutPage = () =>

About

; - -export default AboutPage; diff --git a/packages/nextjs/test/integration/pages/alsoHealthy.tsx b/packages/nextjs/test/integration/pages/alsoHealthy.tsx deleted file mode 100644 index 84eb4c60c4d6..000000000000 --- a/packages/nextjs/test/integration/pages/alsoHealthy.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import Link from 'next/link'; - -const HealthyPage = (): JSX.Element => ( - // @ts-ignore https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-custom-component-that-wraps-an-a-tag - - Healthy - -); - -export default HealthyPage; diff --git a/packages/nextjs/test/integration/pages/api/broken/index.ts b/packages/nextjs/test/integration/pages/api/broken/index.ts deleted file mode 100644 index bc1bbcd5c241..000000000000 --- a/packages/nextjs/test/integration/pages/api/broken/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(500).json({ statusCode: 500, message: 'Something went wrong' }); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/doubleEndMethodOnVercel.ts b/packages/nextjs/test/integration/pages/api/doubleEndMethodOnVercel.ts deleted file mode 100644 index b0cfca8651be..000000000000 --- a/packages/nextjs/test/integration/pages/api/doubleEndMethodOnVercel.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - // This handler calls .end twice. We test this to verify that this still doesn't throw because we're wrapping `.end`. - res.status(200).json({ success: true }); - res.end(); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/error/index.ts b/packages/nextjs/test/integration/pages/api/error/index.ts deleted file mode 100644 index ce65576656de..000000000000 --- a/packages/nextjs/test/integration/pages/api/error/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, _res: NextApiResponse): Promise => { - throw new Error('API Error'); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/excludedEndpoints/excludedWithRegExp.tsx b/packages/nextjs/test/integration/pages/api/excludedEndpoints/excludedWithRegExp.tsx deleted file mode 100644 index 49099819c843..000000000000 --- a/packages/nextjs/test/integration/pages/api/excludedEndpoints/excludedWithRegExp.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// This file will test the `excludeServerRoutes` option when a route is provided as a RegExp. -const handler = async (): Promise => { - throw new Error('API Error'); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/excludedEndpoints/excludedWithString.tsx b/packages/nextjs/test/integration/pages/api/excludedEndpoints/excludedWithString.tsx deleted file mode 100644 index 9e6bde70c490..000000000000 --- a/packages/nextjs/test/integration/pages/api/excludedEndpoints/excludedWithString.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// This file will test the `excludeServerRoutes` option when a route is provided as a string. -const handler = async (): Promise => { - throw new Error('API Error'); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/http/index.ts b/packages/nextjs/test/integration/pages/api/http/index.ts deleted file mode 100644 index e5fe7f576723..000000000000 --- a/packages/nextjs/test/integration/pages/api/http/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -export default (_req: NextApiRequest, res: NextApiResponse) => { - res.status(200).json({}); -}; diff --git a/packages/nextjs/test/integration/pages/api/requireTest.ts b/packages/nextjs/test/integration/pages/api/requireTest.ts deleted file mode 100644 index 353dd632927e..000000000000 --- a/packages/nextjs/test/integration/pages/api/requireTest.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -if (process.env.NEXT_PUBLIC_SOME_FALSE_ENV_VAR === 'enabled') { - require('../../test/server/utils/throw'); // Should not throw unless the hoisting in the wrapping loader is messed up! -} - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - require('@sentry/nextjs').captureException; // Should not throw unless the wrapping loader messes up cjs imports - // @ts-expect-error - require.context('.'); // This is a webpack utility call. Should not throw unless the wrapping loader messes it up by mangling. - res.status(200).json({ success: true }); -}; - -module.exports = handler; diff --git a/packages/nextjs/test/integration/pages/api/users/index.ts b/packages/nextjs/test/integration/pages/api/users/index.ts deleted file mode 100644 index a46c4bd12879..000000000000 --- a/packages/nextjs/test/integration/pages/api/users/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -import { sampleUserData } from '../../../utils/sample-data'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - try { - if (!Array.isArray(sampleUserData)) { - throw new Error('Cannot find user data'); - } - - res.status(200).json(sampleUserData); - } catch (err) { - res.status(500).json({ statusCode: 500, message: (err as Error).message }); - } -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/[...pathParts].ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/[...pathParts].ts deleted file mode 100644 index 3307b12037d5..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/[...pathParts].ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({}); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/[animal].ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/[animal].ts deleted file mode 100644 index 3307b12037d5..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/[animal].ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({}); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/cjsExport.ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/cjsExport.ts deleted file mode 100644 index 6ae521fa5cb4..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/cjsExport.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({ success: true }); -}; - -module.exports = handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/noParams.ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/noParams.ts deleted file mode 100644 index 3307b12037d5..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/unwrapped/noParams.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({}); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/[...pathParts].ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/[...pathParts].ts deleted file mode 100644 index 3307b12037d5..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/[...pathParts].ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({}); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/[animal].ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/[animal].ts deleted file mode 100644 index 3307b12037d5..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/[animal].ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({}); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/cjsExport.ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/cjsExport.ts deleted file mode 100644 index 6ae521fa5cb4..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/cjsExport.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({ success: true }); -}; - -module.exports = handler; diff --git a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/noParams.ts b/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/noParams.ts deleted file mode 100644 index 3307b12037d5..000000000000 --- a/packages/nextjs/test/integration/pages/api/wrapApiHandlerWithSentry/wrapped/noParams.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next'; - -const handler = async (_req: NextApiRequest, res: NextApiResponse): Promise => { - res.status(200).json({}); -}; - -export default handler; diff --git a/packages/nextjs/test/integration/pages/crashed.tsx b/packages/nextjs/test/integration/pages/crashed.tsx deleted file mode 100644 index bddf97b5cb6c..000000000000 --- a/packages/nextjs/test/integration/pages/crashed.tsx +++ /dev/null @@ -1,15 +0,0 @@ -const CrashedPage = (): JSX.Element => { - // Magic to naively trigger onerror to make session crashed and allow for SSR - try { - if (typeof window !== 'undefined' && typeof window.onerror === 'function') { - // Lovely oldschool browsers syntax with 5 arguments <3 - // @ts-expect-error - window.onerror(null, null, null, null, new Error('Crashed')); - } - } catch (_e) { - // no-empty - } - return

Crashed

; -}; - -export default CrashedPage; diff --git a/packages/nextjs/test/integration/pages/customPageExtension.page.tsx b/packages/nextjs/test/integration/pages/customPageExtension.page.tsx deleted file mode 100644 index 302326cdbc96..000000000000 --- a/packages/nextjs/test/integration/pages/customPageExtension.page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -const BasicPage = (): JSX.Element => ( -

- This page simply exists to test the compatibility of Next.js' `pageExtensions` option with our auto wrapping - process. This file should be turned into a page by Next.js and our webpack loader should process it. -

-); - -export async function getServerSideProps() { - return { props: { data: '[some getServerSideProps data]' } }; -} - -export default BasicPage; diff --git a/packages/nextjs/test/integration/pages/errorClick.tsx b/packages/nextjs/test/integration/pages/errorClick.tsx deleted file mode 100644 index df55a4b32967..000000000000 --- a/packages/nextjs/test/integration/pages/errorClick.tsx +++ /dev/null @@ -1,11 +0,0 @@ -const ButtonPage = (): JSX.Element => ( - -); - -export default ButtonPage; diff --git a/packages/nextjs/test/integration/pages/faultyAppGetInitialProps.tsx b/packages/nextjs/test/integration/pages/faultyAppGetInitialProps.tsx deleted file mode 100644 index fabe09909a44..000000000000 --- a/packages/nextjs/test/integration/pages/faultyAppGetInitialProps.tsx +++ /dev/null @@ -1,4 +0,0 @@ -// See _app.tsx for more information why this file exists. -const Page = (): JSX.Element =>

Hello World!

; - -export default Page; diff --git a/packages/nextjs/test/integration/pages/fetch.tsx b/packages/nextjs/test/integration/pages/fetch.tsx deleted file mode 100644 index 1e34e41986b9..000000000000 --- a/packages/nextjs/test/integration/pages/fetch.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useEffect } from 'react'; - -const FetchPage = (): JSX.Element => { - useEffect(() => { - // test that a span is created in the pageload transaction for this fetch request - fetch('http://example.com').catch(() => { - // no-empty - }); - }, []); - - return

Hello world!

; -}; - -export default FetchPage; diff --git a/packages/nextjs/test/integration/pages/healthy.tsx b/packages/nextjs/test/integration/pages/healthy.tsx deleted file mode 100644 index 2a254b825d4b..000000000000 --- a/packages/nextjs/test/integration/pages/healthy.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import Link from 'next/link'; - -const HealthyPage = (): JSX.Element => ( - // @ts-ignore https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-custom-component-that-wraps-an-a-tag - - AlsoHealthy - -); - -export default HealthyPage; diff --git a/packages/nextjs/test/integration/pages/index.tsx b/packages/nextjs/test/integration/pages/index.tsx deleted file mode 100644 index e9549c4f1604..000000000000 --- a/packages/nextjs/test/integration/pages/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -const IndexPage = (): JSX.Element =>

Hello Next.js

; - -export default IndexPage; diff --git a/packages/nextjs/test/integration/pages/reportDialog.tsx b/packages/nextjs/test/integration/pages/reportDialog.tsx deleted file mode 100644 index bfc9704c3aa9..000000000000 --- a/packages/nextjs/test/integration/pages/reportDialog.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { captureException, showReportDialog } from '@sentry/nextjs'; - -const ReportDialogPage = (): JSX.Element => ( - -); - -export default ReportDialogPage; diff --git a/packages/nextjs/test/integration/pages/unmatchedCustomPageExtension.someExtension b/packages/nextjs/test/integration/pages/unmatchedCustomPageExtension.someExtension deleted file mode 100644 index e8d58e47f18e..000000000000 --- a/packages/nextjs/test/integration/pages/unmatchedCustomPageExtension.someExtension +++ /dev/null @@ -1,3 +0,0 @@ -This page simply exists to test the compatibility of Next.js' `pageExtensions` option with our auto wrapping -process. This file should not be turned into a page by Next.js and our webpack loader also shouldn't process it. -This page should not contain valid JavaScript. diff --git a/packages/nextjs/test/integration/pages/users/[id].tsx b/packages/nextjs/test/integration/pages/users/[id].tsx deleted file mode 100644 index 20f79eb0ecd7..000000000000 --- a/packages/nextjs/test/integration/pages/users/[id].tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { GetStaticPaths, GetStaticProps } from 'next'; - -import Layout from '../../components/Layout'; -import ListDetail from '../../components/ListDetail'; -import { User } from '../../interfaces'; -import { sampleUserData } from '../../utils/sample-data'; - -type Props = { - item?: User; - errors?: string; -}; - -const StaticPropsDetail = ({ item, errors }: Props) => { - if (errors) { - return ( - -

- Error: {errors} -

-
- ); - } - - return ( - - {item && } - - ); -}; - -export default StaticPropsDetail; - -export const getStaticPaths: GetStaticPaths = async () => { - // Get the paths we want to pre-render based on users - const paths = sampleUserData.map(user => ({ - params: { id: user.id.toString() }, - })); - - // We'll pre-render only these paths at build time. - // { fallback: false } means other routes should 404. - return { paths, fallback: false }; -}; - -// This function gets called at build time on server-side. -// It won't be called on client-side, so you can even do -// direct database queries. -export const getStaticProps: GetStaticProps = async ({ params }) => { - try { - const id = params?.id; - const item = sampleUserData.find(data => data.id === Number(id)); - // By returning { props: item }, the StaticPropsDetail component - // will receive `item` as a prop at build time - return { props: { item } }; - } catch (err) { - return { props: { errors: (err as Error).message } }; - } -}; diff --git a/packages/nextjs/test/integration/pages/users/index.tsx b/packages/nextjs/test/integration/pages/users/index.tsx deleted file mode 100644 index 90e959ff440e..000000000000 --- a/packages/nextjs/test/integration/pages/users/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { GetStaticProps } from 'next'; -import Link from 'next/link'; - -import Layout from '../../components/Layout'; -import List from '../../components/List'; -import { User } from '../../interfaces'; -import { sampleUserData } from '../../utils/sample-data'; - -type Props = { - items: User[]; -}; - -const WithStaticProps = ({ items }: Props) => ( - -

Users List

-

- Example fetching data from inside getStaticProps(). -

-

You are currently on: /users

- -

- {/* - // @ts-ignore https://nextjs.org/docs/api-reference/next/link#if-the-child-is-a-custom-component-that-wraps-an-a-tag */} - - Go home - -

-
-); - -export const getStaticProps: GetStaticProps = async () => { - // Example for including static props in a Next.js function component page. - // Don't forget to include the respective types for any props passed into - // the component. - const items: User[] = sampleUserData; - return { props: { items } }; -}; - -export default WithStaticProps; diff --git a/packages/nextjs/test/integration/pages/withErrorServerSideProps.tsx b/packages/nextjs/test/integration/pages/withErrorServerSideProps.tsx deleted file mode 100644 index dda4f8f31dd2..000000000000 --- a/packages/nextjs/test/integration/pages/withErrorServerSideProps.tsx +++ /dev/null @@ -1,7 +0,0 @@ -const WithServerSidePropsPage = ({ data }: { data: string }) =>

WithServerSidePropsPage {data}

; - -export async function getServerSideProps() { - throw new Error('ServerSideProps Error'); -} - -export default WithServerSidePropsPage; diff --git a/packages/nextjs/test/integration/sentry.client.config.js b/packages/nextjs/test/integration/sentry.client.config.js deleted file mode 100644 index 4345033e9cdc..000000000000 --- a/packages/nextjs/test/integration/sentry.client.config.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as Sentry from '@sentry/nextjs'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - tracesSampler: () => true, - debug: process.env.SDK_DEBUG, -}); diff --git a/packages/nextjs/test/integration/src/pages/someNamedComponent.tsx b/packages/nextjs/test/integration/src/pages/someNamedComponent.tsx deleted file mode 100644 index c6b4a0859769..000000000000 --- a/packages/nextjs/test/integration/src/pages/someNamedComponent.tsx +++ /dev/null @@ -1,6 +0,0 @@ -export const MyNamedPage = () => ( -

- This page exists to test the compatibility of our auto-wrapper with the option of having the `pages` directory - inside a `src` directory (https://nextjs.org/docs/advanced-features/src-directory) -

-); diff --git a/packages/nextjs/test/integration/test/.eslintrc.json b/packages/nextjs/test/integration/test/.eslintrc.json deleted file mode 100644 index 1abfc6ab4acc..000000000000 --- a/packages/nextjs/test/integration/test/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-console": "off", - "guard-for-in": "off" - } -} diff --git a/packages/nextjs/test/integration/test/client/appDirTracingPageloadClientcomponent.test.ts b/packages/nextjs/test/integration/test/client/appDirTracingPageloadClientcomponent.test.ts deleted file mode 100644 index 019c84438c72..000000000000 --- a/packages/nextjs/test/integration/test/client/appDirTracingPageloadClientcomponent.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should create a pageload transaction when the `app` directory is used with a client component.', async ({ - page, -}) => { - if (process.env.USE_APPDIR !== 'true') { - return; - } - - const [transaction] = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/clientcomponent', - envelopeType: 'transaction', - }); - - expect(transaction).toMatchObject({ - contexts: { - trace: { - op: 'pageload', - }, - }, - transaction: '/clientcomponent', - }); - - expect(await countEnvelopes(page, { url: '/clientcomponent', envelopeType: 'transaction', timeout: 2000 })).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/appDirTracingPageloadServercomponent.test.ts b/packages/nextjs/test/integration/test/client/appDirTracingPageloadServercomponent.test.ts deleted file mode 100644 index aa77dc5c9afb..000000000000 --- a/packages/nextjs/test/integration/test/client/appDirTracingPageloadServercomponent.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should create a pageload transaction when the `app` directory is used with a server component.', async ({ - page, -}) => { - if (process.env.USE_APPDIR !== 'true') { - return; - } - - const [transaction] = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/servercomponent', - envelopeType: 'transaction', - }); - - expect(transaction).toMatchObject({ - contexts: { - trace: { - op: 'pageload', - }, - }, - transaction: '/servercomponent', - }); - - expect(await countEnvelopes(page, { url: '/servercomponent', envelopeType: 'transaction', timeout: 2000 })).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/errorClick.test.ts b/packages/nextjs/test/integration/test/client/errorClick.test.ts deleted file mode 100644 index ad1b94463ed7..000000000000 --- a/packages/nextjs/test/integration/test/client/errorClick.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; -import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should capture error triggered on click', async ({ page }) => { - await page.goto('/errorClick'); - - const [, events] = await Promise.all([ - page.click('button'), - getMultipleSentryEnvelopeRequests(page, 1, { envelopeType: 'event' }), - ]); - - expect(events[0]?.exception?.values?.[0]).toMatchObject({ - type: 'Error', - value: 'Sentry Frontend Error', - }); -}); - -test('should have a non-url-encoded top frame in route with parameter', async ({ page }) => { - await page.goto('/some-param/errorClick'); - - const [, events] = await Promise.all([ - page.click('button'), - getMultipleSentryEnvelopeRequests(page, 1, { envelopeType: 'event' }), - ]); - - const frames = events[0]?.exception?.values?.[0]?.stacktrace?.frames; - - expect(frames?.[frames.length - 1].filename).toMatch(/\/\[id\]\/errorClick-[a-f0-9]+\.js$/); -}); - -test('should mark nextjs internal frames as `in_app`: false', async ({ page }) => { - await page.goto('/some-param/errorClick'); - - const [, events] = await Promise.all([ - page.click('button'), - getMultipleSentryEnvelopeRequests(page, 1, { envelopeType: 'event' }), - ]); - - const frames = events[0]?.exception?.values?.[0]?.stacktrace?.frames; - - expect(frames).toContainEqual( - expect.objectContaining({ - filename: expect.stringMatching( - /^app:\/\/\/_next\/static\/chunks\/(main-|main-app-|polyfills-|webpack-|framework-|framework\.)[0-9a-f]+\.js$/, - ), - in_app: false, - }), - ); - - expect(frames).not.toContainEqual( - expect.objectContaining({ - filename: expect.stringMatching( - /^app:\/\/\/_next\/static\/chunks\/(main-|main-app-|polyfills-|webpack-|framework-|framework\.)[0-9a-f]+\.js$/, - ), - in_app: true, - }), - ); -}); diff --git a/packages/nextjs/test/integration/test/client/errorGlobal.test.ts b/packages/nextjs/test/integration/test/client/errorGlobal.test.ts deleted file mode 100644 index e31daac08be1..000000000000 --- a/packages/nextjs/test/integration/test/client/errorGlobal.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; -import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should capture a globally triggered event', async ({ page }) => { - const event = await getMultipleSentryEnvelopeRequests(page, 1, { url: '/crashed', envelopeType: 'event' }); - - expect(event[0]?.exception?.values?.[0]).toMatchObject({ - type: 'Error', - value: 'Crashed', - }); -}); diff --git a/packages/nextjs/test/integration/test/client/faultyAppGetInitialPropsConfiguration.test.ts b/packages/nextjs/test/integration/test/client/faultyAppGetInitialPropsConfiguration.test.ts deleted file mode 100644 index b03c1f9f705f..000000000000 --- a/packages/nextjs/test/integration/test/client/faultyAppGetInitialPropsConfiguration.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { expect, test } from '@playwright/test'; - -// This test verifies that a faulty configuration of `getInitialProps` in `_app` will not cause our -// auto - wrapping / instrumentation to throw an error. -// See `_app.tsx` for more information. - -test('should not fail auto-wrapping when `getInitialProps` configuration is faulty.', async ({ page }) => { - await page.goto('/faultyAppGetInitialProps'); - - const serverErrorText = await page.$('//*[contains(text(), "Internal Server Error")]'); - - expect(serverErrorText).toBeFalsy(); -}); diff --git a/packages/nextjs/test/integration/test/client/reportDialog.test.ts b/packages/nextjs/test/integration/test/client/reportDialog.test.ts deleted file mode 100644 index bfbb54d775ad..000000000000 --- a/packages/nextjs/test/integration/test/client/reportDialog.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { expect, test } from '@playwright/test'; - -test('should show a dialog', async ({ page }) => { - await page.goto('/reportDialog'); - - await page.click('button'); - - const dialogScriptSelector = 'head > script[src^="https://dsn.ingest.sentry.io/api/embed/error-page"]'; - - const dialogScript = await page.waitForSelector(dialogScriptSelector, { state: 'attached' }); - const dialogScriptSrc = await (await dialogScript.getProperty('src')).jsonValue(); - - expect(dialogScriptSrc).toMatch(/^https:\/\/dsn\.ingest\.sentry\.io\/api\/embed\/error-page\/\?.*/); -}); diff --git a/packages/nextjs/test/integration/test/client/sessionCrashed.test.ts b/packages/nextjs/test/integration/test/client/sessionCrashed.test.ts deleted file mode 100644 index a16615cb7afb..000000000000 --- a/packages/nextjs/test/integration/test/client/sessionCrashed.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Session } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should report crashed sessions', async ({ page }) => { - const event = await getMultipleSentryEnvelopeRequests(page, 2, { url: '/crashed', envelopeType: 'session' }); - - expect(event[0]).toMatchObject({ - init: true, - status: 'ok', - errors: 0, - }); - - expect(event[1]).toMatchObject({ - init: false, - status: 'crashed', - errors: 1, - }); - - expect(await countEnvelopes(page, { url: '/crashed', envelopeType: 'session' })).toBe(2); -}); diff --git a/packages/nextjs/test/integration/test/client/sessionHealthy.test.ts b/packages/nextjs/test/integration/test/client/sessionHealthy.test.ts deleted file mode 100644 index ffbc238fe7ae..000000000000 --- a/packages/nextjs/test/integration/test/client/sessionHealthy.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Session } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should report healthy sessions', async ({ page }) => { - const event = await getMultipleSentryEnvelopeRequests(page, 1, { url: '/healthy', envelopeType: 'session' }); - - expect(event[0]).toMatchObject({ - init: true, - status: 'ok', - errors: 0, - }); - - expect(await countEnvelopes(page, { url: '/healthy', envelopeType: 'session' })).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/sessionNavigate.test.ts b/packages/nextjs/test/integration/test/client/sessionNavigate.test.ts deleted file mode 100644 index 05b201f99609..000000000000 --- a/packages/nextjs/test/integration/test/client/sessionNavigate.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Session } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should report navigation sessions', async ({ page }) => { - const event = await getMultipleSentryEnvelopeRequests(page, 1, { url: '/healthy', envelopeType: 'session' }); - - expect(event[0]).toMatchObject({ - init: true, - status: 'ok', - errors: 0, - }); - - await page.waitForTimeout(250); - - const [, events] = await Promise.all([ - page.click('a#alsoHealthy'), - getMultipleSentryEnvelopeRequests(page, 2, { envelopeType: 'session' }), - ]); - - expect(events[0]).toMatchObject({ - init: false, - status: 'exited', - errors: 0, - }); - - await page.waitForTimeout(250); - - expect(events[1]).toMatchObject({ - init: true, - status: 'ok', - errors: 0, - }); - - await page.waitForTimeout(250); - - const [, events_2] = await Promise.all([ - page.click('a#healthy'), - getMultipleSentryEnvelopeRequests(page, 2, { envelopeType: 'session' }), - ]); - - expect(events_2[0]).toMatchObject({ - init: false, - status: 'exited', - errors: 0, - }); - - expect(events_2[1]).toMatchObject({ - init: true, - status: 'ok', - errors: 0, - }); - - expect(await countEnvelopes(page, { url: '/healthy', envelopeType: 'session' })).toBe(1); - expect(await countEnvelopes(page, { url: '/healthy#alsoHealthy', envelopeType: 'session' })).toBe(4); -}); diff --git a/packages/nextjs/test/integration/test/client/tracingClientGetInitialProps.test.ts b/packages/nextjs/test/integration/test/client/tracingClientGetInitialProps.test.ts deleted file mode 100644 index 4f44d6762f46..000000000000 --- a/packages/nextjs/test/integration/test/client/tracingClientGetInitialProps.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { TransactionEvent } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should instrument `getInitialProps` for performance tracing', async ({ page }) => { - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/42/withInitialProps', - envelopeType: 'transaction', - }); - - expect(transaction[0]).toMatchObject({ - contexts: { - trace: { - op: 'pageload', - }, - }, - }); - - const nextDataTag = await page.waitForSelector('#__NEXT_DATA__', { state: 'attached' }); - const nextDataTagValue = JSON.parse(await nextDataTag.evaluate(tag => (tag as HTMLElement).innerText)); - - const traceId = transaction[0]?.contexts?.trace?.trace_id; - - expect(traceId).toBeDefined(); - - expect(nextDataTagValue.props.pageProps.data).toBe('[some getInitialProps data]'); - expect(nextDataTagValue.props.pageProps._sentryTraceData).toBeTruthy(); - expect(nextDataTagValue.props.pageProps._sentryBaggage).toBeTruthy(); - - expect(nextDataTagValue.props.pageProps._sentryTraceData.split('-')[0]).toBe(traceId); - - expect(nextDataTagValue.props.pageProps._sentryBaggage.match(/sentry-trace_id=([a-f0-9]*),/)[1]).toBe(traceId); - - expect(await countEnvelopes(page, { url: '/42/withInitialProps', envelopeType: 'transaction', timeout: 2500 })).toBe( - 1, - ); -}); diff --git a/packages/nextjs/test/integration/test/client/tracingClientGetServerSideProps.test.ts b/packages/nextjs/test/integration/test/client/tracingClientGetServerSideProps.test.ts deleted file mode 100644 index ee8990462d47..000000000000 --- a/packages/nextjs/test/integration/test/client/tracingClientGetServerSideProps.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Transaction } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should instrument `getServerSideProps` for performance tracing', async ({ page }) => { - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/1337/withServerSideProps', - envelopeType: 'transaction', - }); - - expect(transaction[0]).toMatchObject({ - contexts: { - trace: { - op: 'pageload', - }, - }, - }); - - const nextDataTag = await page.waitForSelector('#__NEXT_DATA__', { state: 'attached' }); - const nextDataTagValue = JSON.parse(await nextDataTag.evaluate(tag => (tag as HTMLElement).innerText)); - - // @ts-expect-error - We know `contexts` is defined in the Transaction envelope - const traceId = transaction[0]?.contexts.trace.trace_id; - - expect(traceId).toBeDefined(); - - expect(nextDataTagValue.props.pageProps.data).toBe('[some getServerSideProps data]'); - expect(nextDataTagValue.props.pageProps._sentryTraceData).toBeTruthy(); - expect(nextDataTagValue.props.pageProps._sentryBaggage).toBeTruthy(); - - expect(nextDataTagValue.props.pageProps._sentryTraceData.split('-')[0]).toBe(traceId); - - expect(nextDataTagValue.props.pageProps._sentryBaggage.match(/sentry-trace_id=([a-f0-9]*),/)[1]).toBe(traceId); - - expect( - await countEnvelopes(page, { url: '/1337/withServerSideProps', envelopeType: 'transaction', timeout: 2500 }), - ).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/tracingDynamicRoute.test.ts b/packages/nextjs/test/integration/test/client/tracingDynamicRoute.test.ts deleted file mode 100644 index 015668852f40..000000000000 --- a/packages/nextjs/test/integration/test/client/tracingDynamicRoute.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Transaction } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should correctly instrument dynamic routes for tracing', async ({ page }) => { - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/users/102', - envelopeType: 'transaction', - }); - - expect(transaction[0]).toMatchObject({ - transaction: '/users/[id]', - type: 'transaction', - contexts: { - trace: { - op: 'pageload', - }, - }, - }); - - expect(await countEnvelopes(page, { url: '/users/102', envelopeType: 'transaction', timeout: 2500 })).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/tracingFetch.test.ts b/packages/nextjs/test/integration/test/client/tracingFetch.test.ts deleted file mode 100644 index 1ad8d3859518..000000000000 --- a/packages/nextjs/test/integration/test/client/tracingFetch.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should correctly instrument `fetch` for performance tracing', async ({ page }) => { - await page.route('http://example.com/**/*', route => { - return route.fulfill({ - status: 200, - body: JSON.stringify({ - foo: 'bar', - }), - }); - }); - - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/fetch', - envelopeType: 'transaction', - }); - - expect(transaction[0]).toMatchObject({ - transaction: '/fetch', - type: 'transaction', - contexts: { - trace: { - op: 'pageload', - }, - }, - }); - - expect(transaction[0]?.spans).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - data: { - 'http.method': 'GET', - url: 'http://example.com', - 'http.url': 'http://example.com/', - 'server.address': 'example.com', - type: 'fetch', - 'http.response_content_length': expect.any(Number), - 'http.response.status_code': 200, - 'sentry.op': 'http.client', - 'sentry.origin': 'auto.http.browser', - }, - description: 'GET http://example.com', - op: 'http.client', - parent_span_id: expect.any(String), - span_id: expect.any(String), - start_timestamp: expect.any(Number), - timestamp: expect.any(Number), - trace_id: expect.any(String), - status: expect.any(String), - origin: 'auto.http.browser', - }), - ]), - ); - - expect(await countEnvelopes(page, { url: '/fetch', envelopeType: 'transaction', timeout: 2500 })).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/tracingNavigate.test.ts b/packages/nextjs/test/integration/test/client/tracingNavigate.test.ts deleted file mode 100644 index 434f12ecca22..000000000000 --- a/packages/nextjs/test/integration/test/client/tracingNavigate.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Transaction } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should report navigation transactions', async ({ page }) => { - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/42/withInitialProps', - envelopeType: 'transaction', - }); - - expect(transaction[0]).toMatchObject({ - transaction: '/[id]/withInitialProps', - type: 'transaction', - contexts: { - trace: { - op: 'pageload', - }, - }, - }); - - await page.waitForTimeout(250); - - const [, transactions] = await Promise.all([ - page.click('a#server-side-props-page'), - getMultipleSentryEnvelopeRequests(page, 1, { envelopeType: 'transaction' }), - ]); - - expect(transactions[0]).toMatchObject({ - transaction: '/[id]/withServerSideProps', - type: 'transaction', - contexts: { - trace: { - op: 'navigation', - data: {}, - }, - }, - }); - - await page.waitForTimeout(250); - - const [, transactions_2] = await Promise.all([ - page.click('a#initial-props-page'), - getMultipleSentryEnvelopeRequests(page, 1, { envelopeType: 'transaction' }), - ]); - - expect(transactions_2[0]).toMatchObject({ - transaction: '/[id]/withInitialProps', - type: 'transaction', - contexts: { - trace: { - op: 'navigation', - data: {}, - }, - }, - }); - - expect(await countEnvelopes(page, { url: '/42/withInitialProps', envelopeType: 'transaction', timeout: 4000 })).toBe( - 1, - ); -}); diff --git a/packages/nextjs/test/integration/test/client/tracingPageLoad.test.ts b/packages/nextjs/test/integration/test/client/tracingPageLoad.test.ts deleted file mode 100644 index 65e1eaf93df6..000000000000 --- a/packages/nextjs/test/integration/test/client/tracingPageLoad.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { Transaction } from '@sentry/types'; -import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; - -test('should report a `pageload` transaction', async ({ page }) => { - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { - url: '/testy', - envelopeType: 'transaction', - }); - - expect(transaction[0]).toMatchObject({ - contexts: { - trace: { - op: 'pageload', - }, - }, - }); - - expect(await countEnvelopes(page, { url: '/testy', envelopeType: 'transaction', timeout: 4000 })).toBe(1); -}); diff --git a/packages/nextjs/test/integration/test/client/utils/helpers.ts b/packages/nextjs/test/integration/test/client/utils/helpers.ts deleted file mode 100644 index 37cffb1cd898..000000000000 --- a/packages/nextjs/test/integration/test/client/utils/helpers.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@sentry-internal/browser-integration-tests/utils/helpers'; diff --git a/packages/nextjs/test/integration/test/server/cjsApiEndpoints.test.ts b/packages/nextjs/test/integration/test/server/cjsApiEndpoints.test.ts deleted file mode 100644 index 25bbed240baa..000000000000 --- a/packages/nextjs/test/integration/test/server/cjsApiEndpoints.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('CommonJS API Endpoints', () => { - it('should not intercept unwrapped request', async () => { - const env = await NextTestEnv.init(); - const unwrappedRoute = '/api/wrapApiHandlerWithSentry/unwrapped/cjsExport'; - const url = `${env.url}${unwrappedRoute}`; - - const unwrappedEnvelope = await env.getEnvelopeRequest({ - url, - envelopeType: 'transaction', - endServer: false, - }); - - expect(unwrappedEnvelope[2]).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - data: { - 'http.response.status_code': 200, - }, - }, - }, - transaction: `GET ${unwrappedRoute}`, - type: 'transaction', - request: { - url, - }, - }); - - const response = await env.getAPIResponse(url); - - expect(response).toMatchObject({ - success: true, - }); - }); - - it('should intercept wrapped request', async () => { - const env = await NextTestEnv.init(); - const wrappedRoute = '/api/wrapApiHandlerWithSentry/wrapped/cjsExport'; - const url = `${env.url}${wrappedRoute}`; - - const wrappedEnvelope = await env.getEnvelopeRequest({ - url, - envelopeType: 'transaction', - endServer: false, - }); - - expect(wrappedEnvelope[2]).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - data: { - 'http.response.status_code': 200, - }, - }, - }, - transaction: `GET ${wrappedRoute}`, - type: 'transaction', - request: { - url, - }, - }); - - const response = await env.getAPIResponse(url); - - expect(response).toMatchObject({ - success: true, - }); - }); - - it('should not mess up require statements', async () => { - const env = await NextTestEnv.init(); - const route = '/api/requireTest'; - const url = `${env.url}${route}`; - - const wrappedEnvelope = await env.getEnvelopeRequest({ - url, - envelopeType: 'transaction', - endServer: false, - }); - - expect(wrappedEnvelope[2]).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - data: { - 'http.response.status_code': 200, - }, - }, - }, - transaction: `GET ${route}`, - type: 'transaction', - request: { - url, - }, - }); - - const response = await env.getAPIResponse(url); - - expect(response).toMatchObject({ - success: true, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/doubleEndMethodOnVercel.test.ts b/packages/nextjs/test/integration/test/server/doubleEndMethodOnVercel.test.ts deleted file mode 100644 index 5bc1aed6536e..000000000000 --- a/packages/nextjs/test/integration/test/server/doubleEndMethodOnVercel.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -// This test asserts that our wrapping of `res.end` doesn't break API routes on Vercel if people call `res.json` or -// `res.send` multiple times in one request handler. -// https://github.com/getsentry/sentry-javascript/issues/6670 -it.skip('should not break API routes on Vercel if people call res.json or res.send multiple times in one request handler', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/doubleEndMethodOnVercel`; - const response = await env.getAPIResponse(url); - - expect(response).toMatchObject({ - success: true, - }); -}); diff --git a/packages/nextjs/test/integration/test/server/errorApiEndpoint.test.ts b/packages/nextjs/test/integration/test/server/errorApiEndpoint.test.ts deleted file mode 100644 index b99058ecfe64..000000000000 --- a/packages/nextjs/test/integration/test/server/errorApiEndpoint.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Error API Endpoints', () => { - it('should capture an error event', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/error`; - - const envelope = await env.getEnvelopeRequest({ - url, - envelopeType: 'event', - }); - - expect(envelope[2]).toMatchObject({ - exception: { - values: [ - { - type: 'Error', - value: 'API Error', - }, - ], - }, - request: { - url, - method: 'GET', - }, - transaction: 'GET /api/error', - }); - }); - - it('should capture an erroneous transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/error`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === 'GET /api/error'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'internal_error', - data: { - 'http.response.status_code': 500, - }, - }, - }, - transaction: 'GET /api/error', - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/errorServerSideProps.test.ts b/packages/nextjs/test/integration/test/server/errorServerSideProps.test.ts deleted file mode 100644 index b777653af526..000000000000 --- a/packages/nextjs/test/integration/test/server/errorServerSideProps.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Error Server-side Props', () => { - it('should capture an error event', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/withErrorServerSideProps`; - - const envelope = await env.getEnvelopeRequest({ - url, - envelopeType: 'event', - }); - - expect(envelope[2]).toMatchObject({ - transaction: `getServerSideProps (/withErrorServerSideProps)`, - exception: { - values: [ - { - type: 'Error', - value: 'ServerSideProps Error', - }, - ], - }, - request: { - url, - method: 'GET', - }, - }); - }); - - it('should capture an erroneous transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/withErrorServerSideProps`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === '/withErrorServerSideProps'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'internal_error', - }, - }, - transaction: '/withErrorServerSideProps', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url: expect.stringMatching(/http:\/\/localhost:[0-9]+\/withErrorServerSideProps/), - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/excludedApiEndpoints.test.ts b/packages/nextjs/test/integration/test/server/excludedApiEndpoints.test.ts deleted file mode 100644 index 810fa899e926..000000000000 --- a/packages/nextjs/test/integration/test/server/excludedApiEndpoints.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Excluded API Endpoints', () => { - it('Should exclude API endpoint via RegExp', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/excludedEndpoints/excludedWithRegExp`; - - const count = await env.countEnvelopes({ - url, - envelopeType: 'event', - timeout: 3000, - }); - - expect(count).toBe(0); - }); - - it('Should exclude API endpoint via string', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/excludedEndpoints/excludedWithString`; - - const count = await env.countEnvelopes({ - url, - envelopeType: 'event', - timeout: 3000, - }); - - expect(count).toBe(0); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/serverComponent.test.ts b/packages/nextjs/test/integration/test/server/serverComponent.test.ts deleted file mode 100644 index e178def81d7b..000000000000 --- a/packages/nextjs/test/integration/test/server/serverComponent.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Loading the server component', () => { - it('should capture an error event', async () => { - if (process.env.USE_APPDIR !== 'true') { - return; - } - - const env = await NextTestEnv.init(); - const url = `${env.url}/servercomponent`; - - const envelope = await env.getEnvelopeRequest({ - url, - envelopeType: 'event', - }); - - expect(envelope[2]).toMatchObject({ - exception: { - values: [ - { - type: 'Error', - value: 'I am an Error captured inside a server component', - }, - ], - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracing200.test.ts b/packages/nextjs/test/integration/test/server/tracing200.test.ts deleted file mode 100644 index dec2af2ef086..000000000000 --- a/packages/nextjs/test/integration/test/server/tracing200.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Tracing 200', () => { - it('should capture a transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/users`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === 'GET /api/users'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - data: { - 'http.response.status_code': 200, - }, - }, - }, - transaction: 'GET /api/users', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracing500.test.ts b/packages/nextjs/test/integration/test/server/tracing500.test.ts deleted file mode 100644 index d98c36d61db3..000000000000 --- a/packages/nextjs/test/integration/test/server/tracing500.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Tracing 500', () => { - it('should capture an erroneous transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/broken`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === 'GET /api/broken'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'internal_error', - data: { - 'http.response.status_code': 500, - }, - }, - }, - transaction: 'GET /api/broken', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracingHttp.test.ts b/packages/nextjs/test/integration/test/server/tracingHttp.test.ts deleted file mode 100644 index 1d84c2309d53..000000000000 --- a/packages/nextjs/test/integration/test/server/tracingHttp.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('Tracing HTTP', () => { - it('should capture a transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/api/http`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === 'GET /api/http'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]!; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - data: { - 'http.response.status_code': 200, - }, - }, - }, - transaction: 'GET /api/http', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracingServerGetInitialProps.test.ts b/packages/nextjs/test/integration/test/server/tracingServerGetInitialProps.test.ts deleted file mode 100644 index 4e8c1a2975c4..000000000000 --- a/packages/nextjs/test/integration/test/server/tracingServerGetInitialProps.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('getInitialProps', () => { - it('should capture a transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/239/withInitialProps`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === `/[id]/withInitialProps`; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - }, - }, - transaction: '/[id]/withInitialProps', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracingServerGetServerSideProps.test.ts b/packages/nextjs/test/integration/test/server/tracingServerGetServerSideProps.test.ts deleted file mode 100644 index 88e0bcb2b550..000000000000 --- a/packages/nextjs/test/integration/test/server/tracingServerGetServerSideProps.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('getServerSideProps', () => { - it('should capture a transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/193/withServerSideProps`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === '/[id]/withServerSideProps'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - }, - }, - transaction: '/[id]/withServerSideProps', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracingServerGetServerSidePropsCustomPageExtension.test.ts b/packages/nextjs/test/integration/test/server/tracingServerGetServerSidePropsCustomPageExtension.test.ts deleted file mode 100644 index 54dec6ae5153..000000000000 --- a/packages/nextjs/test/integration/test/server/tracingServerGetServerSidePropsCustomPageExtension.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -describe('tracingServerGetServerSidePropsCustomPageExtension', () => { - it('should capture a transaction', async () => { - const env = await NextTestEnv.init(); - const url = `${env.url}/customPageExtension`; - - const envelopes = await env.getMultipleEnvelopeRequest({ - url, - envelopeType: 'transaction', - count: 1, - }); - - const sentryTransactionEnvelope = envelopes.find(envelope => { - const envelopeItem = envelope[2]!; - return envelopeItem.transaction === '/customPageExtension'; - }); - - expect(sentryTransactionEnvelope).toBeDefined(); - - const envelopeItem = sentryTransactionEnvelope![2]; - - expect(envelopeItem).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - }, - }, - transaction: '/customPageExtension', - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/tracingWithSentryAPI.test.ts b/packages/nextjs/test/integration/test/server/tracingWithSentryAPI.test.ts deleted file mode 100644 index 73302842e15e..000000000000 --- a/packages/nextjs/test/integration/test/server/tracingWithSentryAPI.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { NextTestEnv } from './utils/helpers'; - -const cases = [ - { - name: 'unwrappedNoParamURL', - url: `/api/wrapApiHandlerWithSentry/unwrapped/noParams`, - transactionName: '/api/wrapApiHandlerWithSentry/unwrapped/noParams', - }, - { - name: 'unwrappedDynamicURL', - url: `/api/wrapApiHandlerWithSentry/unwrapped/dog`, - transactionName: '/api/wrapApiHandlerWithSentry/unwrapped/[animal]', - }, - { - name: 'unwrappedCatchAllURL', - url: `/api/wrapApiHandlerWithSentry/unwrapped/dog/facts`, - transactionName: '/api/wrapApiHandlerWithSentry/unwrapped/[...pathParts]', - }, - { - name: 'wrappedNoParamURL', - url: `/api/wrapApiHandlerWithSentry/wrapped/noParams`, - transactionName: '/api/wrapApiHandlerWithSentry/wrapped/noParams', - }, - { - name: 'wrappedDynamicURL', - url: `/api/wrapApiHandlerWithSentry/wrapped/dog`, - transactionName: '/api/wrapApiHandlerWithSentry/wrapped/[animal]', - }, - { - name: 'wrappedCatchAllURL', - url: `/api/wrapApiHandlerWithSentry/wrapped/dog/facts`, - transactionName: '/api/wrapApiHandlerWithSentry/wrapped/[...pathParts]', - }, -]; - -describe('getServerSideProps', () => { - it.each(cases)(`should capture a transaction for %s`, async ({ url, transactionName }) => { - const env = await NextTestEnv.init(); - - const fullUrl = `${env.url}${url}`; - - const envelope = await env.getEnvelopeRequest({ - url: fullUrl, - envelopeType: 'transaction', - }); - - expect(envelope[2]).toMatchObject({ - contexts: { - trace: { - op: 'http.server', - status: 'ok', - }, - }, - transaction: `GET ${transactionName}`, - transaction_info: { - source: 'route', - }, - type: 'transaction', - request: { - url: fullUrl, - }, - }); - }); -}); diff --git a/packages/nextjs/test/integration/test/server/utils/helpers.ts b/packages/nextjs/test/integration/test/server/utils/helpers.ts deleted file mode 100644 index badc22c18424..000000000000 --- a/packages/nextjs/test/integration/test/server/utils/helpers.ts +++ /dev/null @@ -1,67 +0,0 @@ -import * as http from 'http'; -import { Server, createServer } from 'http'; -import { AddressInfo } from 'net'; -import * as path from 'path'; -import { parse } from 'url'; -import next from 'next'; -import { TestEnv } from '../../../../../../../dev-packages/node-integration-tests/utils'; -import { register } from '../../../instrumentation'; - -let initializedSdk = false; - -// Type not exported from NextJS -// @ts-expect-error -export const createNextServer = async config => { - const app = next({ ...config, customServer: false }); // customServer: false because: https://github.com/vercel/next.js/pull/49805#issuecomment-1557321794 - const handle = app.getRequestHandler(); - await app.prepare(); - - return createServer((req, res) => { - const { url } = req; - - if (!url) { - throw new Error('No url'); - } - - handle(req, res, parse(url, true)); - }); -}; - -export const startServer = async (server: Server) => { - return new Promise<{ server: http.Server; url: string }>(resolve => { - server.listen(0, () => { - const port = (server.address() as AddressInfo).port; - const url = `http://localhost:${port}`; - resolve({ server, url }); - }); - }); -}; - -export class NextTestEnv extends TestEnv { - private constructor(public readonly server: http.Server, public readonly url: string) { - super(server, url); - } - - public static async init(): Promise { - if (!initializedSdk) { - // Normally, Next.js calls the `register` hook by itself, but since we are using a custom server for the tests we need to do it manually. - process.env.NEXT_RUNTIME = 'nodejs'; - await register(); - initializedSdk = true; - } - - const server = await createNextServer({ - dev: false, - dir: path.resolve(__dirname, '../../..'), - - // This needs to be explicitly passed to the server - // Otherwise it causes Segmentation Fault with NextJS >= 12 - // https://github.com/vercel/next.js/issues/33008 - conf: path.resolve(__dirname, '../../next.config.js'), - }); - - const { url } = await startServer(server); - - return new NextTestEnv(server, url); - } -} diff --git a/packages/nextjs/test/integration/test/server/utils/throw.js b/packages/nextjs/test/integration/test/server/utils/throw.js deleted file mode 100644 index 0e37a4135be4..000000000000 --- a/packages/nextjs/test/integration/test/server/utils/throw.js +++ /dev/null @@ -1 +0,0 @@ -throw new Error('I am throwing'); diff --git a/packages/nextjs/test/integration/test/tsconfig.json b/packages/nextjs/test/integration/test/tsconfig.json deleted file mode 100644 index e48928457b7c..000000000000 --- a/packages/nextjs/test/integration/test/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../../tsconfig.test.json", - -} diff --git a/packages/nextjs/test/integration/tsconfig.json b/packages/nextjs/test/integration/tsconfig.json deleted file mode 100644 index ed3ebdb2baea..000000000000 --- a/packages/nextjs/test/integration/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "allowJs": true, - "allowSyntheticDefaultImports": true, - "alwaysStrict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "jsx": "preserve", - "lib": ["dom", "es2018"], - "module": "esnext", - "moduleResolution": "node", - "noEmit": true, - "noFallthroughCasesInSwitch": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "target": "esnext", - "incremental": true, // automatically set by Next.js 13 - "plugins": [ - { - "name": "next" - } - ], - }, - "exclude": ["node_modules"], - "include": ["**/*.ts", "**/*.tsx", "../../playwright.config.ts", ".next/types/**/*.ts"] -} diff --git a/packages/nextjs/test/integration/tsconfig.test.json b/packages/nextjs/test/integration/tsconfig.test.json deleted file mode 100644 index 3b04de6d5bc0..000000000000 --- a/packages/nextjs/test/integration/tsconfig.test.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.test.json", - - "include": ["test/**/*"], - - "compilerOptions": { - "types": ["node", "jest"], - "esModuleInterop": true - } -} diff --git a/packages/nextjs/test/integration/utils/sample-data.ts b/packages/nextjs/test/integration/utils/sample-data.ts deleted file mode 100644 index 504268d70797..000000000000 --- a/packages/nextjs/test/integration/utils/sample-data.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { User } from '../interfaces'; - -/** Dummy user data. */ -export const sampleUserData: User[] = [ - { id: 101, name: 'Alice' }, - { id: 102, name: 'Bob' }, - { id: 103, name: 'Caroline' }, - { id: 104, name: 'Dave' }, -]; diff --git a/packages/nextjs/test/integration_test_utils.sh b/packages/nextjs/test/integration_test_utils.sh deleted file mode 100644 index c067ab9c227d..000000000000 --- a/packages/nextjs/test/integration_test_utils.sh +++ /dev/null @@ -1,79 +0,0 @@ -function link_package() { - local package_abs_path=$1 - # strip the 'sentry-' prefix from the repo name of packages not in the monorepo (`cli`, `webpack-plugin`, and `wizard`) - local package_name=$(basename $package_abs_path | sed s/sentry-//) - - echo "Setting up @sentry/${package_name} for linking" - pushd $package_abs_path - yarn link - popd - - echo "Linking @sentry/$package_name" - yarn link "@sentry/$package_name" - -} - -# Note: LINKED_CLI_REPO and LINKED_PLUGIN_REPO in the functions below should be set to the absolute path of each local repo - -function linkcli() { - if [[ ! $LINKED_CLI_REPO ]]; then - return - fi - - # check to make sure the repo directory exists - if [[ -d $LINKED_CLI_REPO ]]; then - link_package $LINKED_CLI_REPO - else - # the $1 lets us insert a string in that spot if one is passed to `linkcli` (useful for when we're calling this from - # within another linking function) - echo "ERROR: Can't link @sentry/cli $1because directory $LINKED_CLI_REPO does not exist." - fi -} - -function linkplugin() { - if [[ ! $LINKED_PLUGIN_REPO ]]; then - return - fi - - # check to make sure the repo directory exists - if [[ -d $LINKED_PLUGIN_REPO ]]; then - link_package $LINKED_PLUGIN_REPO - - # the webpack plugin depends on `@sentry/cli`, so if we're also using a linked version of the cli package, the - # plugin needs to link to it, too - if [[ $LINKED_CLI_REPO ]]; then - pushd $LINKED_PLUGIN_REPO - link_cli "in webpack plugin repo " - popd - fi - else - echo "ERROR: Can't link @sentry/wepack-plugin because $LINKED_PLUGIN_REPO does not exist." - fi -} - -# This is only really useful for running tests in the debugger, as the normal test runner reinstalls all SDK packages -# from the local files on each test run -function link_monorepo_packages() { - local repo_packages_dir=$1 - - for abs_package_path in ${repo_packages_dir}/*; do - local package_name=$(basename $abs_package_path) - - # Skip packages under the `@sentry-internal` namespace (our function is only linking packages in the `@sentry` - # namespace, and besides, there's no reason to link such packages, as they're purely SDK dev dependencies). - # - # (The regex test ( `=~` ) is a sneaky way of testing if `package_name` is any of the three packages listed: if the - # string containing all of the packages containes a match to the regex solely consisting of the current package - # name, the current package must be in the list.) - if [[ "eslint-config-sdk eslint-plugin-sdk typescript" =~ $package_name ]]; then - continue - fi - - # `-L` tests if the given file is a symbolic link, to see if linking has already been done - if [[ ! -L node_modules/@sentry/$package_name ]]; then - echo "Linking @sentry/$package_name" - link_package $abs_package_path >/dev/null 2>&1 - fi - - done -} diff --git a/packages/nextjs/test/run-integration-tests.sh b/packages/nextjs/test/run-integration-tests.sh deleted file mode 100755 index 17e8ace8f446..000000000000 --- a/packages/nextjs/test/run-integration-tests.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env bash - -source test/integration_test_utils.sh - -set -e - -START_TIME=$(date -R) - -function cleanup { - echo "[nextjs] Cleaning up..." - mv next.config.js.bak next.config.js 2>/dev/null || true - mv -f package.json.bak package.json 2>/dev/null || true - rm -rf node_modules 2>/dev/null || true - - # Delete yarn's cached versions of sentry packages added during this test run, since every test run installs multiple - # copies of each package. Without this, the cache can balloon in size quickly if integration tests are being run - # multiple times in a row. - find "$(yarn cache dir)" -iname "npm-@sentry*" -newermt "$START_TIME" -mindepth 1 -maxdepth 1 -exec rm -rf {} \; - - echo "[nextjs] Test run complete" -} - -trap cleanup EXIT - -cd "$(dirname "$0")/integration" - -NODE_VERSION=$(node -v) -NODE_MAJOR=$(echo "$NODE_VERSION" | cut -c2- | cut -d. -f1) -echo "Running integration tests on Node $NODE_VERSION" - -# make a backup of our config file so we can restore it when we're done -mv next.config.js next.config.js.bak - -for NEXTJS_VERSION in 13; do - for USE_APPDIR in true false; do - if ([ "$NODE_MAJOR" -lt "16" ]) && [ "$USE_APPDIR" == true ]; then - # App dir doesn not work on Node.js < 16 - continue - fi - - # export this to the env so that we can behave differently depending on which version of next we're testing, without - # having to pass this value from function to function to function to the one spot, deep in some callstack, where we - # actually need it - export NEXTJS_VERSION=$NEXTJS_VERSION - export NODE_MAJOR=$NODE_MAJOR - export USE_APPDIR=$USE_APPDIR - - echo "[nextjs@$NEXTJS_VERSION] Preparing environment..." - rm -rf node_modules .next .env.local 2>/dev/null || true - - echo "[nextjs@$NEXTJS_VERSION] Installing dependencies..." - - # Pin to a specific version - if [ "$NEXTJS_VERSION" -eq "13" ]; then - NEXTJS_PACKAGE_JSON_VERSION="13.2.0" - else - NEXTJS_PACKAGE_JSON_VERSION="$NEXTJS_VERSION.x" - fi - - # set the desired version of next long enough to run yarn, and then restore the old version (doing the restoration now - # rather than during overall cleanup lets us look for "latest" in every loop) - cp package.json package.json.bak - if [[ $(uname) == "Darwin" ]]; then - sed -i "" /"next.*latest"/s/latest/"${NEXTJS_PACKAGE_JSON_VERSION}"/ package.json - else - sed -i /"next.*latest"/s/latest/"${NEXTJS_PACKAGE_JSON_VERSION}"/ package.json - fi - - # Yarn install randomly started failing because it couldn't find some cache so for now we need to run these two commands which seem to fix it. - # It was pretty much this issue: https://github.com/yarnpkg/yarn/issues/5275 - rm -rf node_modules - yarn cache clean - - # We have to use `--ignore-engines` because sucrase claims to need Node 12, even though tests pass just fine on Node 10 - yarn --no-lockfile --ignore-engines - - # if applicable, use local versions of `@sentry/cli` and/or `@sentry/webpack-plugin` (these commands no-op unless - # LINKED_CLI_REPO and/or LINKED_PLUGIN_REPO are set) - linkcli && linkplugin - mv -f package.json.bak package.json 2>/dev/null || true - - if [ "$NEXTJS_VERSION" -eq "13" ]; then - if [ "$USE_APPDIR" == true ]; then - cat next13.appdir.config.template > next.config.js - else - cat next13.config.template > next.config.js - fi - fi - - echo "[nextjs@$NEXTJS_VERSION] Building..." - yarn build - - # we keep this updated as we run the tests, so that if it's ever non-zero, we can bail - EXIT_CODE=0 - - if [ "$USE_APPDIR" == true ]; then - echo "Skipping server tests for appdir" - else - echo "[nextjs@$NEXTJS_VERSION] Running server tests with options: $args" - (cd .. && yarn test:integration:server) || EXIT_CODE=$? - fi - - if [ $EXIT_CODE -eq 0 ]; then - echo "[nextjs@$NEXTJS_VERSION] Server integration tests passed" - else - echo "[nextjs@$NEXTJS_VERSION] Server integration tests failed" - exit 1 - fi - - if [ "$NODE_MAJOR" -lt "14" ]; then - echo "[nextjs@$NEXTJS_VERSION] Skipping client tests on Node $NODE_MAJOR" - else - echo "[nextjs@$NEXTJS_VERSION] Running client tests with options: $args" - (cd .. && yarn test:integration:client) || EXIT_CODE=$? - if [ $EXIT_CODE -eq 0 ]; then - echo "[nextjs@$NEXTJS_VERSION] Client integration tests passed" - else - echo "[nextjs@$NEXTJS_VERSION] Client integration tests failed" - exit 1 - fi - fi - done -done diff --git a/packages/nextjs/vercel/install-sentry-from-branch.sh b/packages/nextjs/vercel/install-sentry-from-branch.sh deleted file mode 100644 index b36983b898dc..000000000000 --- a/packages/nextjs/vercel/install-sentry-from-branch.sh +++ /dev/null @@ -1,127 +0,0 @@ -# SCRIPT TO INCLUDE AS PART OF A VERCEL-DEPLOYED PROJECT, SO THAT IT USES A BRANCH FROM THE SDK REPO -# USE `yarn vercel:project ` TO HAVE IT AUTOMATICALLY ADDED TO YOUR PROJECT - -# CUSTOM INSTALL COMMAND FOR PROJECT ON VERCEL: `bash .sentry/install-sentry-from-branch.sh` - -PROJECT_DIR=$(pwd) -REPO_DIR="${PROJECT_DIR}/sentry-javascript" - -# Set BRANCH_NAME as an environment variable -source .sentry/set-branch-name.sh - -echo " " -echo "CLONING SDK REPO" -git clone https://github.com/getsentry/sentry-javascript.git - -echo " " -echo "MOVING INTO REPO DIRECTORY AND CHECKING OUT BRANCH" -cd $REPO_DIR -git checkout $BRANCH_NAME - -echo "LATEST COMMIT: $(git log --format="%C(auto) %h - %s" | head -n 1)" - -echo " " -echo "INSTALLING SDK DEPENDENCIES" -# We need dev dependencies so that we can build the SDK -yarn --prod false - -echo " " -echo "BUILDING SDK" -# build types, cjs, and esm -yarn build:dev - -# Set all packages in the repo to point to their siblings as file dependencies. That way, when we install the local copy -# of @sentry/nextjs, it'll pull the local copy of each of its @sentry/* dependents. This mimics what Lerna does with -# symlinks, just with file dependencies (which we have to use because linking seems to lead to module resolution -# errors). -echo " " -echo "POINTING SIBLING DEPENDENCIES IN PACKAGE.JSON AT LOCAL DIRECTORIES" -PACKAGES_DIR="$REPO_DIR/packages" -# Escape all of the slashes in the path for use in sed -ESCAPED_PACKAGES_DIR=$(echo $PACKAGES_DIR | sed s/'\/'/'\\\/'/g) - -PACKAGE_NAMES=$(ls $PACKAGES_DIR) - -# Modify each package's package.json file by searching in it for sentry dependencies from the monorepo and, for each -# sibling dependency found, replacing the version number with a file dependency pointing to the sibling itself (so -# `"@sentry/utils": "6.9.0"` becomes `"@sentry/utils": "file:/abs/path/to/sentry-javascript/packages/utils"`) -for package in ${PACKAGE_NAMES[@]}; do - # Within a given package.json file, search for each of the other packages in turn, and if found, make the replacement - for package_dep in ${PACKAGE_NAMES[@]}; do - sed -Ei /"@sentry\/${package_dep}"/s/"[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta)\.[0-9]+)?"/"file:${ESCAPED_PACKAGES_DIR}\/${package_dep}"/ ${PACKAGES_DIR}/${package}/package.json - done -done - -echo " " -echo "MOVING BACK TO PROJECT DIRECTORY" -cd $PROJECT_DIR - -# TODO move this into `yarn vercel:project` script, accounting for differences in SDK repo location between running the -# test app locally and on vercel -echo " " -echo "PATCHING SENTRY.SERVER.CONFIG.JS AND SENTRY.CLIENT.CONFIG.JS" -echo "Removing frame limit on stacktraces" -echo "Tagging events with $(vercel) tag" -echo "Tagging events with SDK repo's most recent commit message" -echo "Tagging events with test project repo's most recent commit message" - -INFINITE_STACKTRACE_CODE=" -Error.stackTraceLimit = Infinity; - " - -SDK_COMMIT_MESSAGE=$(cd sentry-javascript && git log --format="%C(auto)%s" | head -n 1) -CONFIGURE_SCOPE_CODE=" -if (process.env.VERCEL) { - Sentry.setTag('vercel', true); -} -Sentry.setTag('commitMessage', process.env.VERCEL_GIT_COMMIT_MESSAGE); -Sentry.setTag('sdkCommitMessage', \"$SDK_COMMIT_MESSAGE\"); -" - -echo "$INFINITE_STACKTRACE_CODE" "$CONFIGURE_SCOPE_CODE" >>sentry.server.config.js -echo "$INFINITE_STACKTRACE_CODE" "$CONFIGURE_SCOPE_CODE" >>sentry.client.config.js - -# Add built SDK as a file dependency. This has the side effect of forcing yarn to install all of the other dependencies, -# saving us the trouble of needing to call `yarn` separately after this -echo " " -echo "SUBSTITUTING LOCAL SDK FOR PUBLISHED ONE AND INSTALLING PROJECT DEPENDENCIES" -echo "yarn add file:sentry-javascript/packages/nextjs" -yarn add file:sentry-javascript/packages/nextjs - -# In case for any reason we ever need to link the local SDK rather than adding it as a file dependency: - -# echo " " -# echo "LINKING LOCAL SDK INTO PROJECT" - -# for abs_package_path in sentry-javascript/packages/*; do -# package=$(basename $abs_package_path) - -# # this one will error out because it's not called @sentry/typescript, it's -# # called @sentry-internal/typescript, but we don't need it, so just move on -# if [ "$package" = "typescript" ]; then -# continue -# fi - -# echo " " -# echo "Linking @sentry/${package}" - -# cd $abs_package_path -# yarn link - -# cd $PROJECT_DIR -# yarn link "@sentry/$package" -# done - -# # These aren't in the repo and therefore have to be done separately (we link these even though they're not in the repo -# # because the branch might specify a different version of either than the published SDK does) -# for package in "cli" "webpack-plugin"; do - -# echo " " -# echo "Linking @sentry/${package}" - -# cd sentry-javascript/node_modules/@sentry/$package -# yarn link - -# cd $PROJECT_DIR -# yarn link "@sentry/$package" -# done diff --git a/packages/nextjs/vercel/instructions.md b/packages/nextjs/vercel/instructions.md deleted file mode 100644 index 6a1890494ffc..000000000000 --- a/packages/nextjs/vercel/instructions.md +++ /dev/null @@ -1,53 +0,0 @@ -# Testing an SDK Branch on Vercel - -Follow the instructions below to test a branch of the SDK against a test app deployed to Vercel. This assumes you -already have such an app set up, and modifies both it and the SDK branch such that the dependency installation process -run on Vercel includes cloning the repo, building the current branch of the SDK, and setting the test app's -`@sentry/next` dependency to point to the newly-built local version. - -(The clone-build-link step is necessary because you can't point a `package.json` dependency to a sub-folder of a git -repo, only a full repo itself. Since we run a monorepo, this won't work in our case.) - -### To prepare your SDK branch for deploying on Vercel - -From `packages/nextjs`, run - -`yarn vercel:branch`. - -This will delete unneeded packages (angular, vue, etc) in order to speed up deployment. It will then commit that change. -When your branch is ready to PR, just rebase and drop that commit. - -### To prepare your test app for using current SDK branch - -First, make sure the branch you want to test is checked out in your `sentry-javascript` repo, and that all changes you -want to test are pushed to GitHub. - -From `packages/nextjs`, run - -`yarn vercel:project `. - -This will copy the `install-sentry-from-branch.sh` script into a `.sentry` folder at the root level of your test app, -and create a `set-branch-name.sh` script in the same location. (The first script is the one you'll run on Vercel. The -second is called by the first, and just sets an environment variable with the current (SDK) branch name.) It will then -commit (but not push) this change. - -Go into your project settings on Vercel and change the install command to - -`bash .sentry/install-sentry-from-branch.sh` - -and the build command to - -`yarn build && bash .sentry/post-app-build.sh`. - -If you're using bundle analyzer, the post-build script will move the visualizations it creates so that they're available -on your deployed site at `/client.html` and `/server.html`. - -NOTE: You don't need to change the `@sentry/nextjs` dependency in your project's `package.json` file. That will happen -on the fly each time your app is deployed. - -### To test the SDK - -Once you have pushed the changes made by `yarn vercel:project` to GitHub, just make changes (either to the SDK or your -test app) and push them. Vercel will always use the latest version of both the SDK and your test app each time it -deploys. Pushing changes to your test app will trigger a new build in Vercel; for changes to the SDK, you'll need to -manually redeploy, either by kicking off a new build or simply choosing 'Redeploy' on your most recent existing build. diff --git a/packages/nextjs/vercel/make-project-use-current-branch.sh b/packages/nextjs/vercel/make-project-use-current-branch.sh deleted file mode 100644 index 57d21ac968c8..000000000000 --- a/packages/nextjs/vercel/make-project-use-current-branch.sh +++ /dev/null @@ -1,63 +0,0 @@ -# SCRIPT TO MAKE TEST APP USE THIS BRANCH - -# CALL THIS BY RUNNING `yarn vercel:project ` - -NEXTJS_SDK_DIR=$(pwd) -PROJECT_DIR=$1 -SDK_BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) - -if [ ! -n "${PROJECT_DIR}" ]; then - echo " " - echo "ERROR: Missing project directory. Please supply the path to your project as an argument to the command." - exit 1 -fi - -# make sure branch is already set up -echo " " -echo "Making sure branch is set up for vercel deployment." -yarn vercel:branch - -cd $PROJECT_DIR - -# make sure we're dealing with a clean test app repo -STASHED_CHANGES=$(git status --porcelain) -if [ -n "${STASHED_CHANGES}" ]; then - echo "Found uncommitted changes in your project. Stashing them." - git stash --quiet --include-untracked -fi - -# make sure we have a clean directory into which to put our scripts -echo " " -if [ -d .sentry ]; then - echo "Clearing .sentry directory" - rm -rf .sentry -else - echo "Creating .sentry directory" -fi -mkdir .sentry - -# set up scripts for use in vercel deployment -echo " " -echo "Creating install scripts and committing the changes" -cp $NEXTJS_SDK_DIR/vercel/install-sentry-from-branch.sh .sentry -cp $NEXTJS_SDK_DIR/vercel/post-app-build.sh .sentry -echo "export BRANCH_NAME=${SDK_BRANCH_NAME}" >>.sentry/set-branch-name.sh -git add . -git commit -m "add scripts for using ${SDK_BRANCH_NAME} branch of @sentry/nextjs" - -# restore working directory, if necessary -if [ -n "${STASHED_CHANGES}" ]; then - echo " " - echo "Restoring changes from earlier stash:" - git stash pop --quiet - git status --porcelain - echo " " -fi - -cd $NEXTJS_SDK_DIR - -echo " " -echo "SUCCESS!" -echo "Your project will now use this branch of the SDK repo when deployed to Vercel. If you haven't done so already, go to your project settings in Vercel and set a custom install command:" -echo " bash .sentry/install-sentry-from-branch.sh" -echo " " diff --git a/packages/nextjs/vercel/post-app-build.sh b/packages/nextjs/vercel/post-app-build.sh deleted file mode 100644 index d4f98319f528..000000000000 --- a/packages/nextjs/vercel/post-app-build.sh +++ /dev/null @@ -1,16 +0,0 @@ -# SCRIPT TO INCLUDE AS PART OF A VERCEL-DEPLOYED PROJECT, FOR WORK TO BE DONE AFTER THE NEXTJS APP IS BUILT -# USE `yarn vercel:project ` TO HAVE IT AUTOMATICALLY ADDED TO YOUR PROJECT - -# CUSTOM BUILD COMMAND FOR PROJECT ON VERCEL: `yarn build && bash .sentry/post-app-build.sh` - -if [[ -e .next/analyze/ ]]; then - echo " " - echo "Moving bundle analysis graphs from \`.next/analyze/\` to \`/public\`" - mv .next/analyze/* public -fi -if [[ -e .next/server/analyze/ ]]; then - echo " " - echo "Moving bundle analysis graphs from \`.next/server/analyze/\` to \`/public\`" - mv .next/server/analyze/* public - echo " " -fi diff --git a/packages/nextjs/vercel/set-up-branch-for-test-app-use.sh b/packages/nextjs/vercel/set-up-branch-for-test-app-use.sh deleted file mode 100644 index 324ad21412ee..000000000000 --- a/packages/nextjs/vercel/set-up-branch-for-test-app-use.sh +++ /dev/null @@ -1,59 +0,0 @@ -# SCRIPT TO SET UP BRANCH FOR USE IN VERCEL-DEPLOYED TEST APPS - -# CALL THIS WITH `yarn vercel:branch` - -echo " " - -# This puts us in the packages directory -cd .. - -# Make sure we're dealing with a clean SDK repo -STASHED_CHANGES=$(git status --porcelain) -if [ -n "${STASHED_CHANGES}" ]; then - echo "Found uncommitted changes. Stashing them." - git stash --quiet --include-untracked -fi - -# If this hasn't already been done, get rid of irrelevant packages to speed up deploy process -PACKAGES_DELETED=false -for package in *; do - # Delete all packages which aren't either runtime or dev dependencies of the nextjs SDK - case $package in - # Runtime depependencies - "nextjs" | "core" | "hub" | "browser" | "node" | "react" | "tracing" | "utils" | "integrations") - continue - ;; - # Dev dependencies - "eslint-config-sdk" | "eslint-plugin-sdk" | "types" | "typescript") - continue - ;; - # Everything else - *) - echo "Deleting ${package}" - rm -rf ${package} - PACKAGES_DELETED=true - ;; - esac -done - -echo " " - -# If we deleted anything, commit the result -if [ "$PACKAGES_DELETED" = true ]; then - echo "Committing deletions. Don't forget to push this commit before you deploy." - git add . - git commit -m "delete unneeded packages" -else - echo "Branch already set up for vercel deployment" -fi - -# Restore working directory, if necessary -if [ -n "${STASHED_CHANGES}" ]; then - echo " " - echo "Restoring changes from earlier stash:" - git stash pop --quiet - git status --porcelain - echo " " -fi - -cd nextjs