Skip to content

Commit 6a87ebe

Browse files
committed
fix meta tag precedence, add more tests, move some files and code around
1 parent f0df692 commit 6a87ebe

File tree

42 files changed

+648
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+648
-118
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Sentry.init({
77
integrations: [
88
Sentry.browserTracingIntegration({
99
linkPreviousTrace: 'in-memory',
10-
sampleLinkedTracesConsistently: true
10+
consistentTraceSampling: true,
1111
}),
1212
],
1313
tracePropagationTargets: ['someurl.com'],
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ const btn2 = document.getElementById('btn2');
44

55
btn1.addEventListener('click', () => {
66
Sentry.startNewTrace(() => {
7-
Sentry.startSpan({name: 'custom root span 1', op: 'custom'}, () => {});
7+
Sentry.startSpan({ name: 'custom root span 1', op: 'custom' }, () => {});
88
});
99
});
1010

1111
btn2.addEventListener('click', () => {
1212
Sentry.startNewTrace(() => {
13-
Sentry.startSpan({name: 'custom root span 2', op: 'custom'}, async () => {
13+
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
1414
await fetch('https://someUrl.com');
1515
});
1616
});
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ import {
55
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
66
SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE,
77
} from '@sentry/core';
8-
9-
import { sentryTest } from '../../../../../utils/fixtures';
8+
import { sentryTest } from '../../../../../../utils/fixtures';
109
import {
1110
eventAndTraceHeaderRequestParser,
1211
shouldSkipTracingTest,
1312
waitForTransactionRequest,
14-
} from '../../../../../utils/helpers';
13+
} from '../../../../../../utils/helpers';
1514

16-
sentryTest.describe('When `sampleLinkedTracesConsistently` is `true`', () => {
15+
sentryTest.describe('When `consistentTraceSampling` is `true`', () => {
1716
sentryTest('Continues sampling decision from initial pageload', async ({ getLocalTestUrl, page }) => {
1817
if (shouldSkipTracingTest()) {
1918
sentryTest.skip();
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ Sentry.init({
77
integrations: [
88
Sentry.browserTracingIntegration({
99
linkPreviousTrace: 'in-memory',
10-
sampleLinkedTracesConsistently: true
10+
consistentTraceSampling: true,
1111
}),
1212
],
1313
tracePropagationTargets: ['someurl.com'],
1414
tracesSampleRate: 1,
1515
debug: true,
16-
sendClientReports: true
16+
sendClientReports: true,
1717
});
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ const btn2 = document.getElementById('btn2');
44

55
btn1.addEventListener('click', () => {
66
Sentry.startNewTrace(() => {
7-
Sentry.startSpan({name: 'custom root span 1', op: 'custom'}, () => {});
7+
Sentry.startSpan({ name: 'custom root span 1', op: 'custom' }, () => {});
88
});
99
});
1010

1111
btn2.addEventListener('click', () => {
1212
Sentry.startNewTrace(() => {
13-
Sentry.startSpan({name: 'custom root span 2', op: 'custom'}, async () => {
13+
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
1414
await fetch('https://someUrl.com');
1515
});
1616
});
Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { expect } from '@playwright/test';
22
import type { ClientReport } from '@sentry/core';
33
import { extractTraceparentData, parseBaggageHeader } from '@sentry/core';
4-
5-
import { sentryTest } from '../../../../../utils/fixtures';
4+
import { sentryTest } from '../../../../../../utils/fixtures';
65
import {
76
envelopeRequestParser,
87
getMultipleSentryEnvelopeRequests,
8+
hidePage,
99
shouldSkipTracingTest,
1010
waitForClientReportRequest,
11-
} from '../../../../../utils/helpers';
11+
} from '../../../../../../utils/helpers';
1212

1313
const metaTagSampleRand = 0.9;
1414
const metaTagSampleRate = 0.2;
1515
const metaTagTraceId = '12345678901234567890123456789012';
1616

17-
sentryTest.describe('When `sampleLinkedTracesConsistently` is `true` and page contains <meta> tags', () => {
17+
sentryTest.describe('When `consistentTraceSampling` is `true` and page contains <meta> tags', () => {
1818
sentryTest(
1919
'Continues negative sampling decision from meta tag across all traces and downstream propagations',
2020
async ({ getLocalTestUrl, page }) => {
@@ -81,18 +81,7 @@ sentryTest.describe('When `sampleLinkedTracesConsistently` is `true` and page co
8181
});
8282

8383
await sentryTest.step('Client report', async () => {
84-
await page.evaluate(() => {
85-
Object.defineProperty(document, 'visibilityState', {
86-
configurable: true,
87-
get: function () {
88-
return 'hidden';
89-
},
90-
});
91-
92-
// Dispatch the visibilitychange event to notify listeners
93-
document.dispatchEvent(new Event('visibilitychange'));
94-
});
95-
84+
await hidePage(page);
9685
const clientReport = envelopeRequestParser<ClientReport>(await clientReportPromise);
9786
expect(clientReport).toEqual({
9887
timestamp: expect.any(Number),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [
8+
Sentry.browserTracingIntegration({
9+
linkPreviousTrace: 'session-storage',
10+
consistentTraceSampling: true,
11+
}),
12+
],
13+
tracePropagationTargets: ['someurl.com'],
14+
tracesSampler: ({ inheritOrSampleWith }) => {
15+
return inheritOrSampleWith(0);
16+
},
17+
debug: true,
18+
sendClientReports: true,
19+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="sentry-trace" content="a2345678901234567890123456789012-1234567890123456-1" />
6+
<meta
7+
name="baggage"
8+
content="sentry-trace_id=a2345678901234567890123456789012,sentry-sample_rate=0.2,sentry-sampled=true,sentry-transaction=my-transaction,sentry-public_key=public,sentry-release=1.0.0,sentry-environment=prod,sentry-sample_rand=0.12"
9+
/>
10+
</head>
11+
<body>
12+
<h1>Another Page</h1>
13+
<a href="./page-2.html">Go To the next page</a>
14+
</body>
15+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<h1>Another Page</h1>
8+
<a href="./page-2.html">Go To the next page</a>
9+
</body>
10+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const btn1 = document.getElementById('btn1');
2+
3+
const btn2 = document.getElementById('btn2');
4+
5+
btn1?.addEventListener('click', () => {
6+
Sentry.startNewTrace(() => {
7+
Sentry.startSpan({ name: 'custom root span 1', op: 'custom' }, () => {});
8+
});
9+
});
10+
11+
btn2?.addEventListener('click', () => {
12+
Sentry.startNewTrace(() => {
13+
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
14+
await fetch('https://someUrl.com');
15+
});
16+
});
17+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="sentry-trace" content="12345678901234567890123456789012-1234567890123456-0" />
6+
<meta
7+
name="baggage"
8+
content="sentry-trace_id=12345678901234567890123456789012,sentry-sample_rate=0.2,sentry-sampled=false,sentry-transaction=my-transaction,sentry-public_key=public,sentry-release=1.0.0,sentry-environment=prod,sentry-sample_rand=0.9"
9+
/>
10+
</head>
11+
<a href="./page-1.html">Go To another page</a>
12+
<button id="btn1">Custom Trace</button>
13+
<button id="btn2">fetch request</button>
14+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { expect } from '@playwright/test';
2+
import type { ClientReport } from '@sentry/core';
3+
import { extractTraceparentData, parseBaggageHeader } from '@sentry/core';
4+
import { sentryTest } from '../../../../../../utils/fixtures';
5+
import {
6+
envelopeRequestParser,
7+
eventAndTraceHeaderRequestParser,
8+
hidePage,
9+
shouldSkipTracingTest,
10+
waitForClientReportRequest,
11+
waitForTransactionRequest,
12+
} from '../../../../../../utils/helpers';
13+
14+
const metaTagSampleRand = 0.9;
15+
const metaTagSampleRate = 0.2;
16+
const metaTagTraceIdIndex = '12345678901234567890123456789012';
17+
const metaTagTraceIdPage1 = 'a2345678901234567890123456789012';
18+
19+
sentryTest.describe('When `consistentTraceSampling` is `true` and page contains <meta> tags', () => {
20+
sentryTest(
21+
'meta tag decision has precedence over sampling decision from previous trace in session storage',
22+
async ({ getLocalTestUrl, page }) => {
23+
if (shouldSkipTracingTest()) {
24+
sentryTest.skip();
25+
}
26+
27+
const url = await getLocalTestUrl({ testDir: __dirname });
28+
29+
const clientReportPromise = waitForClientReportRequest(page);
30+
31+
await sentryTest.step('Initial pageload', async () => {
32+
await page.goto(url);
33+
});
34+
35+
await sentryTest.step('Make fetch request', async () => {
36+
let sentryTrace = undefined;
37+
let baggage = undefined;
38+
39+
await page.route('https://someUrl.com', (route, req) => {
40+
baggage = req.headers()['baggage'];
41+
sentryTrace = req.headers()['sentry-trace'];
42+
return route.fulfill({ status: 200, body: 'ok' });
43+
});
44+
45+
await page.locator('#btn2').click();
46+
47+
expect(sentryTrace).toBeDefined();
48+
expect(baggage).toBeDefined();
49+
50+
expect(extractTraceparentData(sentryTrace)).toEqual({
51+
traceId: expect.not.stringContaining(metaTagTraceIdIndex),
52+
parentSpanId: expect.stringMatching(/^[0-9a-f]{16}$/),
53+
parentSampled: false,
54+
});
55+
56+
expect(parseBaggageHeader(baggage)).toEqual({
57+
'sentry-environment': 'production',
58+
'sentry-public_key': 'public',
59+
'sentry-sample_rand': `${metaTagSampleRand}`,
60+
'sentry-sample_rate': `${metaTagSampleRate}`,
61+
'sentry-sampled': 'false',
62+
'sentry-trace_id': expect.not.stringContaining(metaTagTraceIdIndex),
63+
'sentry-transaction': 'custom root span 2',
64+
});
65+
});
66+
67+
await sentryTest.step('Client report', async () => {
68+
await hidePage(page);
69+
70+
const clientReport = envelopeRequestParser<ClientReport>(await clientReportPromise);
71+
expect(clientReport).toEqual({
72+
timestamp: expect.any(Number),
73+
discarded_events: [
74+
{
75+
category: 'transaction',
76+
quantity: 2,
77+
reason: 'sample_rate',
78+
},
79+
],
80+
});
81+
});
82+
83+
await sentryTest.step('Navigate to another page with meta tags', async () => {
84+
const page1Pageload = waitForTransactionRequest(page, evt => evt.contexts?.trace?.op === 'pageload');
85+
await page.locator('a').click();
86+
87+
const [pageloadEvent, pageloadTraceHeader] = eventAndTraceHeaderRequestParser(await page1Pageload);
88+
const pageloadTraceContext = pageloadEvent.contexts?.trace;
89+
90+
expect(Number(pageloadTraceHeader?.sample_rand)).toBe(0.12);
91+
expect(Number(pageloadTraceHeader?.sample_rate)).toBe(0.2);
92+
expect(pageloadTraceContext?.trace_id).toEqual(metaTagTraceIdPage1);
93+
});
94+
95+
await sentryTest.step('Navigate to another page without meta tags', async () => {
96+
const page2Pageload = waitForTransactionRequest(page, evt => evt.contexts?.trace?.op === 'pageload');
97+
await page.locator('a').click();
98+
99+
const [pageloadEvent, pageloadTraceHeader] = eventAndTraceHeaderRequestParser(await page2Pageload);
100+
const pageloadTraceContext = pageloadEvent.contexts?.trace;
101+
102+
expect(Number(pageloadTraceHeader?.sample_rand)).toBe(0.12);
103+
expect(Number(pageloadTraceHeader?.sample_rate)).toBe(0.2);
104+
expect(pageloadTraceContext?.trace_id).not.toEqual(metaTagTraceIdPage1);
105+
expect(pageloadTraceContext?.trace_id).not.toEqual(metaTagTraceIdIndex);
106+
});
107+
},
108+
);
109+
});
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Sentry.init({
77
integrations: [
88
Sentry.browserTracingIntegration({
99
linkPreviousTrace: 'in-memory',
10-
sampleLinkedTracesConsistently: true
10+
consistentTraceSampling: true,
1111
}),
1212
],
1313
tracePropagationTargets: ['someurl.com'],
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ const btn2 = document.getElementById('btn2');
44

55
btn1.addEventListener('click', () => {
66
Sentry.startNewTrace(() => {
7-
Sentry.startSpan({name: 'custom root span 1', op: 'custom'}, () => {});
7+
Sentry.startSpan({ name: 'custom root span 1', op: 'custom' }, () => {});
88
});
99
});
1010

1111
btn2.addEventListener('click', () => {
1212
Sentry.startNewTrace(() => {
13-
Sentry.startSpan({name: 'custom root span 2', op: 'custom'}, async () => {
13+
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
1414
await fetch('https://someUrl.com');
1515
});
1616
});
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@ import {
55
SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE,
66
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
77
} from '@sentry/core';
8-
9-
import { sentryTest } from '../../../../../utils/fixtures';
8+
import { sentryTest } from '../../../../../../utils/fixtures';
109
import {
1110
eventAndTraceHeaderRequestParser,
1211
shouldSkipTracingTest,
1312
waitForTransactionRequest,
14-
} from '../../../../../utils/helpers';
13+
} from '../../../../../../utils/helpers';
1514

1615
const metaTagSampleRand = 0.051121;
1716
const metaTagSampleRate = 0.2;
1817

19-
sentryTest.describe('When `sampleLinkedTracesConsistently` is `true` and page contains <meta> tags', () => {
18+
sentryTest.describe('When `consistentTraceSampling` is `true` and page contains <meta> tags', () => {
2019
sentryTest('Continues sampling decision across all traces from meta tag', async ({ getLocalTestUrl, page }) => {
2120
if (shouldSkipTracingTest()) {
2221
sentryTest.skip();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [
8+
Sentry.browserTracingIntegration({
9+
linkPreviousTrace: 'in-memory',
10+
consistentTraceSampling: true,
11+
enableInp: false,
12+
}),
13+
],
14+
tracePropagationTargets: ['someurl.com'],
15+
tracesSampler: ctx => {
16+
if (ctx.attributes && ctx.attributes['sentry.origin'] === 'auto.pageload.browser') {
17+
return 1;
18+
}
19+
if (ctx.name === 'custom root span 1') {
20+
return 0;
21+
}
22+
if (ctx.name === 'custom root span 2') {
23+
return 1;
24+
}
25+
return ctx.inheritOrSampleWith(0);
26+
},
27+
debug: true,
28+
});

0 commit comments

Comments
 (0)