Skip to content

Commit e9d846b

Browse files
authored
test(browser-integration-tests): Check trace envelope headers in trace lifetime tests (#11660)
Adds checks for the contents of the `trace` envelope headers in our new `trace-lifetime` test suite. The purpose of these checks is to ensure that we not only propagate and send correct trace data in request headers and Sentry events (trace context) but also in the `trace` envelope header.
1 parent eb2f454 commit e9d846b

File tree

5 files changed

+509
-64
lines changed

5 files changed

+509
-64
lines changed

dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts

+148-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { expect } from '@playwright/test';
22
import type { Event } from '@sentry/types';
33
import { sentryTest } from '../../../../utils/fixtures';
4+
import type { EventAndTraceHeader } from '../../../../utils/helpers';
45
import {
6+
eventAndTraceHeaderRequestParser,
57
getFirstSentryEnvelopeRequest,
68
getMultipleSentryEnvelopeRequests,
79
shouldSkipTracingTest,
@@ -14,12 +16,21 @@ sentryTest('creates a new trace on each navigation', async ({ getLocalTestPath,
1416

1517
const url = await getLocalTestPath({ testDir: __dirname });
1618

17-
await getFirstSentryEnvelopeRequest<Event>(page, url);
18-
const navigationEvent1 = await getFirstSentryEnvelopeRequest<Event>(page, `${url}#foo`);
19-
const navigationEvent2 = await getFirstSentryEnvelopeRequest<Event>(page, `${url}#bar`);
19+
await getFirstSentryEnvelopeRequest(page, url);
20+
21+
const [navigation1Event, navigation1TraceHeader] = await getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
22+
page,
23+
`${url}#foo`,
24+
eventAndTraceHeaderRequestParser,
25+
);
26+
const [navigation2Event, navigation2TraceHeader] = await getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
27+
page,
28+
`${url}#bar`,
29+
eventAndTraceHeaderRequestParser,
30+
);
2031

21-
const navigation1TraceContext = navigationEvent1.contexts?.trace;
22-
const navigation2TraceContext = navigationEvent2.contexts?.trace;
32+
const navigation1TraceContext = navigation1Event.contexts?.trace;
33+
const navigation2TraceContext = navigation2Event.contexts?.trace;
2334

2435
expect(navigation1TraceContext).toMatchObject({
2536
op: 'navigation',
@@ -28,13 +39,29 @@ sentryTest('creates a new trace on each navigation', async ({ getLocalTestPath,
2839
});
2940
expect(navigation1TraceContext).not.toHaveProperty('parent_span_id');
3041

42+
expect(navigation1TraceHeader).toEqual({
43+
environment: 'production',
44+
public_key: 'public',
45+
sample_rate: '1',
46+
sampled: 'true',
47+
trace_id: navigation1TraceContext?.trace_id,
48+
});
49+
3150
expect(navigation2TraceContext).toMatchObject({
3251
op: 'navigation',
3352
trace_id: expect.stringMatching(/^[0-9a-f]{32}$/),
3453
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
3554
});
3655
expect(navigation2TraceContext).not.toHaveProperty('parent_span_id');
3756

57+
expect(navigation2TraceHeader).toEqual({
58+
environment: 'production',
59+
public_key: 'public',
60+
sample_rate: '1',
61+
sampled: 'true',
62+
trace_id: navigation2TraceContext?.trace_id,
63+
});
64+
3865
expect(navigation1TraceContext?.trace_id).not.toEqual(navigation2TraceContext?.trace_id);
3966
});
4067

@@ -48,7 +75,11 @@ sentryTest('error after navigation has navigation traceId', async ({ getLocalTes
4875
// ensure pageload transaction is finished
4976
await getFirstSentryEnvelopeRequest<Event>(page, url);
5077

51-
const navigationEvent = await getFirstSentryEnvelopeRequest<Event>(page, `${url}#foo`);
78+
const [navigationEvent, navigationTraceHeader] = await getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
79+
page,
80+
`${url}#foo`,
81+
eventAndTraceHeaderRequestParser,
82+
);
5283
const navigationTraceContext = navigationEvent.contexts?.trace;
5384

5485
expect(navigationTraceContext).toMatchObject({
@@ -58,15 +89,34 @@ sentryTest('error after navigation has navigation traceId', async ({ getLocalTes
5889
});
5990
expect(navigationTraceContext).not.toHaveProperty('parent_span_id');
6091

61-
const errorEventPromise = getFirstSentryEnvelopeRequest<Event>(page);
92+
expect(navigationTraceHeader).toEqual({
93+
environment: 'production',
94+
public_key: 'public',
95+
sample_rate: '1',
96+
sampled: 'true',
97+
trace_id: navigationTraceContext?.trace_id,
98+
});
99+
100+
const errorEventPromise = getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
101+
page,
102+
undefined,
103+
eventAndTraceHeaderRequestParser,
104+
);
62105
await page.locator('#errorBtn').click();
63-
const errorEvent = await errorEventPromise;
106+
const [errorEvent, errorTraceHeader] = await errorEventPromise;
64107

65108
const errorTraceContext = errorEvent.contexts?.trace;
66109
expect(errorTraceContext).toEqual({
67110
trace_id: navigationTraceContext?.trace_id,
68111
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
69112
});
113+
expect(errorTraceHeader).toEqual({
114+
environment: 'production',
115+
public_key: 'public',
116+
sample_rate: '1',
117+
sampled: 'true',
118+
trace_id: navigationTraceContext?.trace_id,
119+
});
70120
});
71121

72122
sentryTest('error during navigation has new navigation traceId', async ({ getLocalTestPath, page }) => {
@@ -79,13 +129,19 @@ sentryTest('error during navigation has new navigation traceId', async ({ getLoc
79129
// ensure navigation transaction is finished
80130
await getFirstSentryEnvelopeRequest<Event>(page, url);
81131

82-
const envelopeRequestsPromise = getMultipleSentryEnvelopeRequests<Event>(page, 2);
132+
const envelopeRequestsPromise = getMultipleSentryEnvelopeRequests<EventAndTraceHeader>(
133+
page,
134+
2,
135+
undefined,
136+
eventAndTraceHeaderRequestParser,
137+
);
138+
83139
await page.goto(`${url}#foo`);
84140
await page.locator('#errorBtn').click();
85-
const events = await envelopeRequestsPromise;
141+
const envelopes = await envelopeRequestsPromise;
86142

87-
const navigationEvent = events.find(event => event.type === 'transaction');
88-
const errorEvent = events.find(event => !event.type);
143+
const [navigationEvent, navigationTraceHeader] = envelopes.find(envelope => envelope[0].type === 'transaction')!;
144+
const [errorEvent, errorTraceHeader] = envelopes.find(envelope => !envelope[0].type)!;
89145

90146
const navigationTraceContext = navigationEvent?.contexts?.trace;
91147
expect(navigationTraceContext).toMatchObject({
@@ -95,12 +151,28 @@ sentryTest('error during navigation has new navigation traceId', async ({ getLoc
95151
});
96152
expect(navigationTraceContext).not.toHaveProperty('parent_span_id');
97153

154+
expect(navigationTraceHeader).toEqual({
155+
environment: 'production',
156+
public_key: 'public',
157+
sample_rate: '1',
158+
sampled: 'true',
159+
trace_id: navigationTraceContext?.trace_id,
160+
});
161+
98162
const errorTraceContext = errorEvent?.contexts?.trace;
99163
expect(errorTraceContext).toMatchObject({
100164
op: 'navigation',
101-
trace_id: errorTraceContext?.trace_id,
165+
trace_id: navigationTraceContext?.trace_id,
102166
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
103167
});
168+
169+
expect(errorTraceHeader).toEqual({
170+
environment: 'production',
171+
public_key: 'public',
172+
sample_rate: '1',
173+
sampled: 'true',
174+
trace_id: navigationTraceContext?.trace_id,
175+
});
104176
});
105177

106178
sentryTest(
@@ -115,7 +187,11 @@ sentryTest(
115187
// ensure navigation transaction is finished
116188
await getFirstSentryEnvelopeRequest<Event>(page, url);
117189

118-
const navigationEvent = await getFirstSentryEnvelopeRequest<Event>(page, `${url}#foo`);
190+
const [navigationEvent, navigationTraceHeader] = await getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
191+
page,
192+
`${url}#foo`,
193+
eventAndTraceHeaderRequestParser,
194+
);
119195

120196
const navigationTraceContext = navigationEvent.contexts?.trace;
121197
expect(navigationTraceContext).toMatchObject({
@@ -125,6 +201,14 @@ sentryTest(
125201
});
126202
expect(navigationTraceContext).not.toHaveProperty('parent_span_id');
127203

204+
expect(navigationTraceHeader).toEqual({
205+
environment: 'production',
206+
public_key: 'public',
207+
sample_rate: '1',
208+
sampled: 'true',
209+
trace_id: navigationTraceContext?.trace_id,
210+
});
211+
128212
const requestPromise = page.waitForRequest('http://example.com/*');
129213
await page.locator('#fetchBtn').click();
130214
const request = await requestPromise;
@@ -151,11 +235,18 @@ sentryTest(
151235
// ensure navigation transaction is finished
152236
await getFirstSentryEnvelopeRequest<Event>(page, url);
153237

154-
const navigationEventPromise = getFirstSentryEnvelopeRequest<Event>(page);
238+
const navigationEventPromise = getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
239+
page,
240+
undefined,
241+
eventAndTraceHeaderRequestParser,
242+
);
155243
const requestPromise = page.waitForRequest('http://example.com/*');
156244
await page.goto(`${url}#foo`);
157245
await page.locator('#fetchBtn').click();
158-
const [navigationEvent, request] = await Promise.all([navigationEventPromise, requestPromise]);
246+
const [[navigationEvent, navigationTraceHeader], request] = await Promise.all([
247+
navigationEventPromise,
248+
requestPromise,
249+
]);
159250

160251
const navigationTraceContext = navigationEvent.contexts?.trace;
161252
expect(navigationTraceContext).toMatchObject({
@@ -165,6 +256,14 @@ sentryTest(
165256
});
166257
expect(navigationTraceContext).not.toHaveProperty('parent_span_id');
167258

259+
expect(navigationTraceHeader).toEqual({
260+
environment: 'production',
261+
public_key: 'public',
262+
sample_rate: '1',
263+
sampled: 'true',
264+
trace_id: navigationTraceContext?.trace_id,
265+
});
266+
168267
const headers = request.headers();
169268

170269
// sampling decision is propagated from active span sampling decision
@@ -186,9 +285,13 @@ sentryTest(
186285
const url = await getLocalTestPath({ testDir: __dirname });
187286

188287
// ensure navigation transaction is finished
189-
await getFirstSentryEnvelopeRequest<Event>(page, url);
288+
await getFirstSentryEnvelopeRequest(page, url);
190289

191-
const navigationEvent = await getFirstSentryEnvelopeRequest<Event>(page, `${url}#foo`);
290+
const [navigationEvent, navigationTraceHeader] = await getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
291+
page,
292+
`${url}#foo`,
293+
eventAndTraceHeaderRequestParser,
294+
);
192295

193296
const navigationTraceContext = navigationEvent.contexts?.trace;
194297
expect(navigationTraceContext).toMatchObject({
@@ -198,6 +301,14 @@ sentryTest(
198301
});
199302
expect(navigationTraceContext).not.toHaveProperty('parent_span_id');
200303

304+
expect(navigationTraceHeader).toEqual({
305+
environment: 'production',
306+
public_key: 'public',
307+
sample_rate: '1',
308+
sampled: 'true',
309+
trace_id: navigationTraceContext?.trace_id,
310+
});
311+
201312
const xhrPromise = page.waitForRequest('http://example.com/*');
202313
await page.locator('#xhrBtn').click();
203314
const request = await xhrPromise;
@@ -222,13 +333,20 @@ sentryTest(
222333
const url = await getLocalTestPath({ testDir: __dirname });
223334

224335
// ensure navigation transaction is finished
225-
await getFirstSentryEnvelopeRequest<Event>(page, url);
336+
await getFirstSentryEnvelopeRequest(page, url);
226337

227-
const navigationEventPromise = getFirstSentryEnvelopeRequest<Event>(page);
338+
const navigationEventPromise = getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
339+
page,
340+
undefined,
341+
eventAndTraceHeaderRequestParser,
342+
);
228343
const requestPromise = page.waitForRequest('http://example.com/*');
229344
await page.goto(`${url}#foo`);
230345
await page.locator('#xhrBtn').click();
231-
const [navigationEvent, request] = await Promise.all([navigationEventPromise, requestPromise]);
346+
const [[navigationEvent, navigationTraceHeader], request] = await Promise.all([
347+
navigationEventPromise,
348+
requestPromise,
349+
]);
232350

233351
const navigationTraceContext = navigationEvent.contexts?.trace;
234352
expect(navigationTraceContext).toMatchObject({
@@ -237,6 +355,15 @@ sentryTest(
237355
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
238356
});
239357
expect(navigationTraceContext).not.toHaveProperty('parent_span_id');
358+
359+
expect(navigationTraceHeader).toEqual({
360+
environment: 'production',
361+
public_key: 'public',
362+
sample_rate: '1',
363+
sampled: 'true',
364+
trace_id: navigationTraceContext?.trace_id,
365+
});
366+
240367
const headers = request.headers();
241368

242369
// sampling decision is propagated from active span sampling decision

0 commit comments

Comments
 (0)