Skip to content

Commit 4ebf47d

Browse files
authored
test(nextjs): Skip flaky tests affected by Turbopack 404s in dev mode (#20993)
Turbopack intermittently returns 404 for dynamic routes in dev mode (e.g. `/route-handler/[xoxo]/...`, `/parameterized/[one]/beep/[two]`). We drop 404 transactions so when this happens, route handlers never execute, no Sentry events are sent, and the tests time out waiting for events that never arrive. This PR skips the affected tests in dev mode across `nextjs-16` and `nextjs-16-streaming` test apps. The tests still run in production mode where routes work reliably. Closes: #20992, #20986, #20987, #20985, #20977, #20976, #20975, #20984
1 parent 0db41f9 commit 4ebf47d

5 files changed

Lines changed: 26 additions & 22 deletions

File tree

dev-packages/e2e-tests/test-applications/nextjs-16-streaming/tests/route-handler.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import test, { expect } from '@playwright/test';
22
import { waitForError, waitForStreamedSpan, getSpanOp } from '@sentry-internal/test-utils';
3+
import { isDevMode } from './isDevMode';
34

45
test('Should create a streamed span for node route handlers', async ({ request }) => {
6+
test.skip(isDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
7+
58
const rootSpanPromise = waitForStreamedSpan('nextjs-16-streaming', span => {
69
return span.name === 'GET /route-handler/[xoxo]/node' && getSpanOp(span) === 'http.server' && span.is_segment;
710
});
@@ -16,6 +19,8 @@ test('Should create a streamed span for node route handlers', async ({ request }
1619
});
1720

1821
test('Should report an error linked to the correct trace for a throwing route handler', async ({ request }) => {
22+
test.skip(isDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
23+
1924
const errorEventPromise = waitForError('nextjs-16-streaming', errorEvent => {
2025
return errorEvent?.exception?.values?.some(value => value.value === 'route-handler-error') ?? false;
2126
});
@@ -37,6 +42,8 @@ test('Should report an error linked to the correct trace for a throwing route ha
3742
test('Should set a parameterized transaction name on a captureMessage event in a route handler', async ({
3843
request,
3944
}) => {
45+
test.skip(isDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
46+
4047
const messageEventPromise = waitForError('nextjs-16-streaming', event => {
4148
return event?.message === 'route-handler-message';
4249
});

dev-packages/e2e-tests/test-applications/nextjs-16-streaming/tests/server-components.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { expect, test } from '@playwright/test';
22
import { waitForStreamedSpan, waitForStreamedSpans, getSpanOp } from '@sentry-internal/test-utils';
3+
import { isDevMode } from './isDevMode';
34

45
test('Sends a streamed span for a request to app router with URL', async ({ page }) => {
6+
test.skip(isDevMode, 'Turbopack intermittently returns 404 for nested dynamic routes in dev mode');
7+
58
const rootSpanPromise = waitForStreamedSpan('nextjs-16-streaming', span => {
69
return span.name === 'GET /parameterized/[one]/beep/[two]' && span.is_segment;
710
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const isDevMode = !!process.env.TEST_ENV && process.env.TEST_ENV.includes('development');
2+
export const isTurbopackDevMode = process.env.TEST_ENV === 'development';

dev-packages/e2e-tests/test-applications/nextjs-16/tests/route-handler.test.ts

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import test, { expect } from '@playwright/test';
22
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';
3+
import { isTurbopackDevMode } from './isDevMode';
34

45
test('Should create a transaction for node route handlers', async ({ request }) => {
6+
test.skip(isTurbopackDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
7+
58
const routehandlerTransactionPromise = waitForTransaction('nextjs-16', async transactionEvent => {
69
return transactionEvent?.transaction === 'GET /route-handler/[xoxo]/node';
710
});
@@ -13,11 +16,7 @@ test('Should create a transaction for node route handlers', async ({ request })
1316

1417
expect(routehandlerTransaction.contexts?.trace?.status).toBe('ok');
1518
expect(routehandlerTransaction.contexts?.trace?.op).toBe('http.server');
16-
17-
// This is flaking on dev mode
18-
if (process.env.TEST_ENV !== 'development' && process.env.TEST_ENV !== 'dev-turbopack') {
19-
expect(routehandlerTransaction.contexts?.trace?.data?.['http.request.header.x_charly']).toBe('gomez');
20-
}
19+
expect(routehandlerTransaction.contexts?.trace?.data?.['http.request.header.x_charly']).toBe('gomez');
2120
});
2221

2322
test('Should create a transaction for edge route handlers', async ({ request }) => {
@@ -41,6 +40,8 @@ test('Should create a transaction for edge route handlers', async ({ request })
4140
test('Should report an error with a parameterized transaction name for a throwing route handler', async ({
4241
request,
4342
}) => {
43+
test.skip(isTurbopackDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
44+
4445
const errorEventPromise = waitForError('nextjs-16', errorEvent => {
4546
return errorEvent?.exception?.values?.some(value => value.value === 'route-handler-error') ?? false;
4647
});
@@ -63,23 +64,6 @@ test('Should report an error with a parameterized transaction name for a throwin
6364
// Error should carry the parameterized transaction name
6465
expect(errorEvent.transaction).toBe('GET /route-handler/[xoxo]/error');
6566

66-
// On turbopack (no wrapping loader), the error goes through onRequestError which sets nextjs context.
67-
// On webpack, the wrapping loader's error handler fires first and captures without nextjs context.
68-
// The SDK deduplicates by error identity, so only the first capture survives.
69-
if (process.env.TEST_ENV === 'development') {
70-
expect(errorEvent.contexts?.nextjs).toEqual({
71-
route_type: 'route',
72-
router_kind: 'App Router',
73-
router_path: '/route-handler/[xoxo]/error',
74-
request_path: '/route-handler/456/error',
75-
});
76-
77-
expect(errorEvent.exception?.values?.[0]?.mechanism).toEqual({
78-
handled: false,
79-
type: 'auto.function.nextjs.on_request_error',
80-
});
81-
}
82-
8367
// Transaction should have parameterized name and internal_error status
8468
expect(transactionEvent.transaction).toBe('GET /route-handler/[xoxo]/error');
8569
expect(transactionEvent.contexts?.trace?.status).toBe('internal_error');
@@ -88,6 +72,8 @@ test('Should report an error with a parameterized transaction name for a throwin
8872
test('Should set a parameterized transaction name on a captureMessage event in a route handler', async ({
8973
request,
9074
}) => {
75+
test.skip(isTurbopackDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
76+
9177
const messageEventPromise = waitForError('nextjs-16', event => {
9278
return event?.message === 'route-handler-message';
9379
});
@@ -119,6 +105,8 @@ test('Should set a parameterized transaction name on a captureMessage event in a
119105
test('Should set a parameterized transaction name on a captureException event in a route handler', async ({
120106
request,
121107
}) => {
108+
test.skip(isTurbopackDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
109+
122110
const errorEventPromise = waitForError('nextjs-16', errorEvent => {
123111
return errorEvent?.exception?.values?.some(value => value.value === 'route-handler-capture-exception') ?? false;
124112
});

dev-packages/e2e-tests/test-applications/nextjs-16/tests/server-components.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { expect, test } from '@playwright/test';
22
import { waitForTransaction } from '@sentry-internal/test-utils';
3+
import { isTurbopackDevMode } from './isDevMode';
34

45
test('Sends a transaction for a request to app router with URL', async ({ page }) => {
6+
test.skip(isTurbopackDevMode, 'Turbopack intermittently returns 404 for nested dynamic routes in dev mode');
7+
58
const serverComponentTransactionPromise = waitForTransaction('nextjs-16', transactionEvent => {
69
return (
710
transactionEvent?.transaction === 'GET /parameterized/[one]/beep/[two]' &&
@@ -74,6 +77,8 @@ test('Will create a transaction with spans for every server component and metada
7477
test('Will create a transaction with spans for every server component and metadata generation functions when visiting a dynamic page', async ({
7578
page,
7679
}) => {
80+
test.skip(isTurbopackDevMode, 'Turbopack intermittently returns 404 for dynamic routes in dev mode');
81+
7782
const serverTransactionEventPromise = waitForTransaction('nextjs-16', async transactionEvent => {
7883
return transactionEvent?.transaction === 'GET /nested-layout/[dynamic]';
7984
});

0 commit comments

Comments
 (0)