Skip to content

Commit 9b79719

Browse files
committed
test(nextjs): Assert single transaction for pages-router API routes
Guards against duplicate root transactions for pages-router API routes: Next.js's own BaseServer.handleRequest transaction and the one created by wrapApiHandlerWithSentry must never both be sent for a single request.
1 parent 550b2d8 commit 9b79719

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { expect, test } from '@playwright/test';
2+
import { waitForTransaction } from '@sentry-internal/test-utils';
3+
4+
// A pages-router API route sees both Next.js's own `BaseServer.handleRequest` OTEL transaction and the
5+
// transaction created by `wrapApiHandlerWithSentry`. Exactly one of them must be sent for a request, never
6+
// both. This guards against regressing back to duplicate root transactions for the same API route.
7+
test('Sends exactly one transaction for a pages-router API route', async ({ request }) => {
8+
const apiRouteTransactions: string[] = [];
9+
10+
// Never resolves; we accumulate every matching transaction and assert on the total after a grace period.
11+
const collectorPromise = waitForTransaction('nextjs-pages-dir', transactionEvent => {
12+
if (transactionEvent?.transaction === 'GET /api/endpoint') {
13+
apiRouteTransactions.push(transactionEvent.contexts?.trace?.trace_id ?? '<no-trace-id>');
14+
}
15+
return false;
16+
});
17+
18+
const response = await request.get('/api/endpoint');
19+
expect(await response.json()).toStrictEqual({ name: 'John Doe' });
20+
21+
await Promise.race([collectorPromise, new Promise(resolve => setTimeout(resolve, 6000))]);
22+
23+
expect(apiRouteTransactions).toHaveLength(1);
24+
});

0 commit comments

Comments
 (0)