|
| 1 | +import { expect, test } from '@playwright/test'; |
| 2 | +import { getSpanOp, waitForStreamedSpan } from '@sentry-internal/test-utils'; |
| 3 | + |
| 4 | +test.skip(!process.env.E2E_TEST_TUNNEL, 'Only runs in the tunnel variant'); |
| 5 | + |
| 6 | +const TUNNEL_PATH = /^\/[a-z0-9]{1,7}$/; |
| 7 | + |
| 8 | +test('answers the managed tunnel before the app auth middleware', async ({ page }) => { |
| 9 | + // The variant's auth middleware rejects every other POST. |
| 10 | + expect((await page.request.post('/api/anything', { data: 'x' })).status()).toBe(401); |
| 11 | + |
| 12 | + const tunnelServerSpanPromise = waitForStreamedSpan( |
| 13 | + 'nitro-3', |
| 14 | + span => getSpanOp(span) === 'http.server' && TUNNEL_PATH.test(String(span.attributes['url.path']?.value ?? '')), |
| 15 | + ); |
| 16 | + const tunnelResponsePromise = page.waitForResponse( |
| 17 | + response => response.request().method() === 'POST' && TUNNEL_PATH.test(new URL(response.url()).pathname), |
| 18 | + ); |
| 19 | + |
| 20 | + await page.goto('/'); |
| 21 | + const tunnelResponse = await tunnelResponsePromise; |
| 22 | + |
| 23 | + expect(tunnelResponse.status()).toBe(200); |
| 24 | + expect(new URL(tunnelResponse.url()).origin).toBe(new URL(page.url()).origin); |
| 25 | + |
| 26 | + // Anchor on a regular server span requested after the tunnel traffic: spans flush in order, so a tunnel span |
| 27 | + // would arrive first. |
| 28 | + const anchorSpanPromise = waitForStreamedSpan( |
| 29 | + 'nitro-3', |
| 30 | + span => |
| 31 | + getSpanOp(span) === 'http.server' && String(span.attributes['url.path']?.value ?? '') === '/api/test-transaction', |
| 32 | + ); |
| 33 | + await page.request.get('/api/test-transaction'); |
| 34 | + |
| 35 | + const winner = await Promise.race([ |
| 36 | + tunnelServerSpanPromise.then(() => 'tunnel' as const), |
| 37 | + anchorSpanPromise.then(() => 'anchor' as const), |
| 38 | + ]); |
| 39 | + expect(winner).toBe('anchor'); |
| 40 | +}); |
0 commit comments