Skip to content

Commit ec9bc7c

Browse files
test(e2e): Fix leftover / pairing and the custom-tunnel first-request leak
Co-Authored-By: Cursor Grok 4.6 <cursoragent@cursor.com>
1 parent fb54915 commit ec9bc7c

2 files changed

Lines changed: 42 additions & 14 deletions

File tree

‎dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/trace-propagation.test.ts‎

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from '@playwright/test';
2-
import { getSpanOp, waitForStreamedSpan } from '@sentry-internal/test-utils';
2+
import { collectStreamedSpans, getSpanOp } from '@sentry-internal/test-utils';
33

44
const usesManagedTunnelRoute =
55
(process.env.E2E_TEST_TUNNEL_ROUTE_MODE ?? 'off') !== 'off' || process.env.E2E_TEST_CUSTOM_TUNNEL_ROUTE === '1';
@@ -23,19 +23,30 @@ test.describe('Trace propagation', () => {
2323
});
2424

2525
test('should have trace connection between server and client', async ({ page }) => {
26-
const serverSpanPromise = waitForStreamedSpan('tanstackstart-react', span => {
27-
return span.is_segment && getSpanOp(span) === 'http.server' && span.attributes['url.path']?.value === '/';
28-
});
29-
30-
const clientSpanPromise = waitForStreamedSpan('tanstackstart-react', span => {
31-
return span.is_segment && getSpanOp(span) === 'pageload' && span.name === '/';
26+
const spansPromise = collectStreamedSpans('tanstackstart-react', spans => {
27+
return (
28+
spans.some(
29+
span => span.is_segment && getSpanOp(span) === 'http.server' && span.attributes['url.path']?.value === '/',
30+
) &&
31+
spans.some(
32+
span =>
33+
span.is_segment &&
34+
getSpanOp(span) === 'pageload' &&
35+
(span.name === '/' || span.attributes['url.path']?.value === '/'),
36+
)
37+
);
3238
});
3339

3440
await page.goto('/');
3541

36-
const serverSpan = await serverSpanPromise;
37-
const clientSpan = await clientSpanPromise;
42+
const spans = await spansPromise;
43+
const serverSpan = spans.find(
44+
span => span.is_segment && getSpanOp(span) === 'http.server' && span.attributes['url.path']?.value === '/',
45+
);
46+
const clientSpan = spans.find(span => span.is_segment && getSpanOp(span) === 'pageload');
3847

39-
expect(clientSpan.trace_id).toBe(serverSpan.trace_id);
48+
expect(serverSpan).toBeDefined();
49+
expect(clientSpan).toBeDefined();
50+
expect(clientSpan?.trace_id).toBe(serverSpan?.trace_id);
4051
});
4152
});

‎dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/tunnel.test.ts‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,30 @@ function pathnameMatchesTunnelRoute(pathname: string): boolean {
6767
: expectedTunnelPathMatcher.test(pathname);
6868
}
6969

70-
function waitForServerHttpSpan(matchesPathname: (pathname: string) => boolean): Promise<unknown> {
71-
return waitForStreamedSpan('tanstackstart-react', span => {
72-
return getSpanOp(span) === 'http.server' && matchesPathname(String(span.attributes['url.path']?.value ?? ''));
73-
});
70+
function waitForServerHttpSpan(
71+
matchesPathname: (pathname: string) => boolean,
72+
since?: number,
73+
): Promise<unknown> {
74+
return waitForStreamedSpan(
75+
'tanstackstart-react',
76+
span => {
77+
return getSpanOp(span) === 'http.server' && matchesPathname(String(span.attributes['url.path']?.value ?? ''));
78+
},
79+
since,
80+
);
7481
}
7582

7683
test('Does not create a server transaction for the tunnel route', async ({ page }) => {
84+
// Custom routes self-register `ignoreSpans` on the first POST; that first streamed
85+
// span still leaks (see `createSentryTunnelRoute`). The previous test already made
86+
// that POST — wait it out so it cannot win the race below. Managed routes register
87+
// at startup and never emit this span. The leaked span may already have arrived, so
88+
// this wait looks back over everything the proxy recorded instead of only what comes
89+
// in from here on.
90+
if (tunnelRouteMode === 'custom') {
91+
await waitForServerHttpSpan(pathnameMatchesTunnelRoute, 0);
92+
}
93+
7794
// The incoming POST to the tunnel route must not be turned into an `http.server`
7895
// transaction by the server SDK — tunnel traffic is plumbing, not application requests.
7996
const tunnelServerEventPromise = waitForServerHttpSpan(pathnameMatchesTunnelRoute);

0 commit comments

Comments
 (0)