Skip to content

Commit 1550d4c

Browse files
committed
add tests
1 parent 43baead commit 1550d4c

File tree

2 files changed

+371
-2
lines changed

2 files changed

+371
-2
lines changed

packages/tracing-internal/src/browser/browserTracingIntegration.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable max-lines, complexity */
1+
/* eslint-disable max-lines */
22
import type { IdleTransaction } from '@sentry/core';
33
import { getActiveSpan } from '@sentry/core';
44
import { getCurrentHub } from '@sentry/core';
@@ -238,7 +238,6 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
238238
latestRouteName = finalContext.name;
239239
latestRouteSource = getSource(finalContext);
240240

241-
// eslint-disable-next-line deprecation/deprecation
242241
if (finalContext.sampled === false) {
243242
DEBUG_BUILD && logger.log(`[Tracing] Will not send ${finalContext.op} transaction because of beforeNavigate.`);
244243
}
Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
import {
2+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
3+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
4+
SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE,
5+
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
6+
getActiveSpan,
7+
getCurrentScope,
8+
setCurrentClient,
9+
spanIsSampled,
10+
spanToJSON,
11+
} from '@sentry/core';
12+
import { JSDOM } from 'jsdom';
13+
import { browserTracingIntegration, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan } from '../..';
14+
import { WINDOW } from '../../src/browser/types';
15+
import { TestClient, getDefaultClientOptions } from '../utils/TestClient';
16+
17+
// We're setting up JSDom here because the Next.js routing instrumentations requires a few things to be present on pageload:
18+
// 1. Access to window.document API for `window.document.getElementById`
19+
// 2. Access to window.location API for `window.location.pathname`
20+
21+
const dom = new JSDOM(undefined, { url: 'https://example.com/' });
22+
Object.defineProperty(global, 'document', { value: dom.window.document, writable: true });
23+
Object.defineProperty(global, 'location', { value: dom.window.document.location, writable: true });
24+
Object.defineProperty(global, 'history', { value: dom.window.history, writable: true });
25+
26+
const originalGlobalDocument = WINDOW.document;
27+
const originalGlobalLocation = WINDOW.location;
28+
const originalGlobalHistory = WINDOW.history;
29+
afterAll(() => {
30+
// Clean up JSDom
31+
Object.defineProperty(WINDOW, 'document', { value: originalGlobalDocument });
32+
Object.defineProperty(WINDOW, 'location', { value: originalGlobalLocation });
33+
Object.defineProperty(WINDOW, 'history', { value: originalGlobalHistory });
34+
});
35+
36+
describe('browserTracingIntegration', () => {
37+
afterEach(() => {
38+
getCurrentScope().clear();
39+
});
40+
41+
it('works with tracing enabled', () => {
42+
const client = new TestClient(
43+
getDefaultClientOptions({
44+
tracesSampleRate: 1,
45+
integrations: [browserTracingIntegration()],
46+
}),
47+
);
48+
setCurrentClient(client);
49+
client.init();
50+
51+
const span = getActiveSpan();
52+
expect(span).toBeDefined();
53+
expect(spanIsSampled(span!)).toBe(true);
54+
expect(spanToJSON(span!)).toEqual({
55+
description: '/',
56+
op: 'pageload',
57+
origin: 'auto.pageload.browser',
58+
data: {
59+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
60+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',
61+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
62+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
63+
},
64+
span_id: expect.any(String),
65+
start_timestamp: expect.any(Number),
66+
trace_id: expect.any(String),
67+
});
68+
});
69+
70+
it('works with tracing disabled', () => {
71+
const client = new TestClient(
72+
getDefaultClientOptions({
73+
integrations: [browserTracingIntegration()],
74+
}),
75+
);
76+
setCurrentClient(client);
77+
client.init();
78+
79+
const span = getActiveSpan();
80+
expect(span).toBeDefined();
81+
expect(spanIsSampled(span!)).toBe(false);
82+
});
83+
84+
it('works with tracing enabled but unsampled', () => {
85+
const client = new TestClient(
86+
getDefaultClientOptions({
87+
tracesSampleRate: 0,
88+
integrations: [browserTracingIntegration()],
89+
}),
90+
);
91+
setCurrentClient(client);
92+
client.init();
93+
94+
const span = getActiveSpan();
95+
expect(span).toBeDefined();
96+
expect(spanIsSampled(span!)).toBe(false);
97+
});
98+
99+
it('starts navigation when URL changes', () => {
100+
const client = new TestClient(
101+
getDefaultClientOptions({
102+
tracesSampleRate: 1,
103+
integrations: [browserTracingIntegration()],
104+
}),
105+
);
106+
setCurrentClient(client);
107+
client.init();
108+
109+
const span = getActiveSpan();
110+
expect(span).toBeDefined();
111+
expect(spanIsSampled(span!)).toBe(true);
112+
expect(span!.isRecording()).toBe(true);
113+
expect(spanToJSON(span!)).toEqual({
114+
description: '/',
115+
op: 'pageload',
116+
origin: 'auto.pageload.browser',
117+
data: {
118+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
119+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',
120+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
121+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
122+
},
123+
span_id: expect.any(String),
124+
start_timestamp: expect.any(Number),
125+
trace_id: expect.any(String),
126+
});
127+
128+
// this is what is used to get the span name - JSDOM does not update this on it's own!
129+
const dom = new JSDOM(undefined, { url: 'https://example.com/test' });
130+
Object.defineProperty(global, 'location', { value: dom.window.document.location, writable: true });
131+
132+
WINDOW.history.pushState({}, '', '/test');
133+
134+
expect(span!.isRecording()).toBe(false);
135+
136+
const span2 = getActiveSpan();
137+
expect(span2).toBeDefined();
138+
expect(spanIsSampled(span2!)).toBe(true);
139+
expect(span2!.isRecording()).toBe(true);
140+
expect(spanToJSON(span2!)).toEqual({
141+
description: '/test',
142+
op: 'navigation',
143+
origin: 'auto.navigation.browser',
144+
data: {
145+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
146+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',
147+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
148+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
149+
},
150+
span_id: expect.any(String),
151+
start_timestamp: expect.any(Number),
152+
trace_id: expect.any(String),
153+
});
154+
155+
// this is what is used to get the span name - JSDOM does not update this on it's own!
156+
const dom2 = new JSDOM(undefined, { url: 'https://example.com/test2' });
157+
Object.defineProperty(global, 'location', { value: dom2.window.document.location, writable: true });
158+
159+
WINDOW.history.pushState({}, '', '/test2');
160+
161+
expect(span2!.isRecording()).toBe(false);
162+
163+
const span3 = getActiveSpan();
164+
expect(span3).toBeDefined();
165+
expect(spanIsSampled(span3!)).toBe(true);
166+
expect(span3!.isRecording()).toBe(true);
167+
expect(spanToJSON(span3!)).toEqual({
168+
description: '/test2',
169+
op: 'navigation',
170+
origin: 'auto.navigation.browser',
171+
data: {
172+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
173+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',
174+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
175+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
176+
},
177+
span_id: expect.any(String),
178+
start_timestamp: expect.any(Number),
179+
trace_id: expect.any(String),
180+
});
181+
});
182+
183+
describe('startBrowserTracingPageLoadSpan', () => {
184+
it('works without integration setup', () => {
185+
const client = new TestClient(
186+
getDefaultClientOptions({
187+
integrations: [],
188+
}),
189+
);
190+
setCurrentClient(client);
191+
client.init();
192+
193+
const span = startBrowserTracingPageLoadSpan(client, { name: 'test span' });
194+
195+
expect(span).toBeUndefined();
196+
});
197+
198+
it('works with unsampled span', () => {
199+
const client = new TestClient(
200+
getDefaultClientOptions({
201+
tracesSampleRate: 0,
202+
integrations: [browserTracingIntegration({ instrumentPageLoad: false })],
203+
}),
204+
);
205+
setCurrentClient(client);
206+
client.init();
207+
208+
const span = startBrowserTracingPageLoadSpan(client, { name: 'test span' });
209+
210+
expect(span).toBeDefined();
211+
expect(spanIsSampled(span!)).toBe(false);
212+
});
213+
214+
it('works with integration setup', () => {
215+
const client = new TestClient(
216+
getDefaultClientOptions({
217+
tracesSampleRate: 1,
218+
integrations: [browserTracingIntegration({ instrumentPageLoad: false })],
219+
}),
220+
);
221+
setCurrentClient(client);
222+
client.init();
223+
224+
const span = startBrowserTracingPageLoadSpan(client, { name: 'test span' });
225+
226+
expect(span).toBeDefined();
227+
expect(spanToJSON(span!)).toEqual({
228+
description: 'test span',
229+
op: 'pageload',
230+
origin: 'manual',
231+
data: {
232+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
233+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual',
234+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
235+
},
236+
span_id: expect.any(String),
237+
start_timestamp: expect.any(Number),
238+
trace_id: expect.any(String),
239+
});
240+
expect(spanIsSampled(span!)).toBe(true);
241+
});
242+
243+
it('allows to overwrite properties', () => {
244+
const client = new TestClient(
245+
getDefaultClientOptions({
246+
tracesSampleRate: 1,
247+
integrations: [browserTracingIntegration({ instrumentPageLoad: false })],
248+
}),
249+
);
250+
setCurrentClient(client);
251+
client.init();
252+
253+
const span = startBrowserTracingPageLoadSpan(client, {
254+
name: 'test span',
255+
origin: 'auto.test',
256+
attributes: { testy: 'yes' },
257+
});
258+
259+
expect(span).toBeDefined();
260+
expect(spanToJSON(span!)).toEqual({
261+
description: 'test span',
262+
op: 'pageload',
263+
origin: 'auto.test',
264+
data: {
265+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
266+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.test',
267+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
268+
testy: 'yes',
269+
},
270+
span_id: expect.any(String),
271+
start_timestamp: expect.any(Number),
272+
trace_id: expect.any(String),
273+
});
274+
});
275+
});
276+
277+
describe('startBrowserTracingNavigationSpan', () => {
278+
it('works without integration setup', () => {
279+
const client = new TestClient(
280+
getDefaultClientOptions({
281+
integrations: [],
282+
}),
283+
);
284+
setCurrentClient(client);
285+
client.init();
286+
287+
const span = startBrowserTracingNavigationSpan(client, { name: 'test span' });
288+
289+
expect(span).toBeUndefined();
290+
});
291+
292+
it('works with unsampled span', () => {
293+
const client = new TestClient(
294+
getDefaultClientOptions({
295+
tracesSampleRate: 0,
296+
integrations: [browserTracingIntegration({ instrumentNavigation: false })],
297+
}),
298+
);
299+
setCurrentClient(client);
300+
client.init();
301+
302+
const span = startBrowserTracingNavigationSpan(client, { name: 'test span' });
303+
304+
expect(span).toBeDefined();
305+
expect(spanIsSampled(span!)).toBe(false);
306+
});
307+
308+
it('works with integration setup', () => {
309+
const client = new TestClient(
310+
getDefaultClientOptions({
311+
tracesSampleRate: 1,
312+
integrations: [browserTracingIntegration({ instrumentNavigation: false })],
313+
}),
314+
);
315+
setCurrentClient(client);
316+
client.init();
317+
318+
const span = startBrowserTracingNavigationSpan(client, { name: 'test span' });
319+
320+
expect(span).toBeDefined();
321+
expect(spanToJSON(span!)).toEqual({
322+
description: 'test span',
323+
op: 'navigation',
324+
origin: 'manual',
325+
data: {
326+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
327+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual',
328+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
329+
},
330+
span_id: expect.any(String),
331+
start_timestamp: expect.any(Number),
332+
trace_id: expect.any(String),
333+
});
334+
expect(spanIsSampled(span!)).toBe(true);
335+
});
336+
337+
it('allows to overwrite properties', () => {
338+
const client = new TestClient(
339+
getDefaultClientOptions({
340+
tracesSampleRate: 1,
341+
integrations: [browserTracingIntegration({ instrumentNavigation: false })],
342+
}),
343+
);
344+
setCurrentClient(client);
345+
client.init();
346+
347+
const span = startBrowserTracingNavigationSpan(client, {
348+
name: 'test span',
349+
origin: 'auto.test',
350+
attributes: { testy: 'yes' },
351+
});
352+
353+
expect(span).toBeDefined();
354+
expect(spanToJSON(span!)).toEqual({
355+
description: 'test span',
356+
op: 'navigation',
357+
origin: 'auto.test',
358+
data: {
359+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
360+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.test',
361+
[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1,
362+
testy: 'yes',
363+
},
364+
span_id: expect.any(String),
365+
start_timestamp: expect.any(Number),
366+
trace_id: expect.any(String),
367+
});
368+
});
369+
});
370+
});

0 commit comments

Comments
 (0)