Skip to content

Commit 7f4c4ec

Browse files
authored
test(replay): Add test for fetch and XHR performance spans (#7224)
1 parent 00d2360 commit 7f4c4ec

File tree

5 files changed

+145
-0
lines changed

5 files changed

+145
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
window.Replay = new Sentry.Replay({
5+
flushMinDelay: 500,
6+
flushMaxDelay: 500,
7+
useCompression: true,
8+
});
9+
10+
Sentry.init({
11+
dsn: 'https://[email protected]/1337',
12+
sampleRate: 0,
13+
replaysSessionSampleRate: 1.0,
14+
replaysOnErrorSampleRate: 0.0,
15+
16+
integrations: [window.Replay],
17+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
document.getElementById('go-background').addEventListener('click', () => {
2+
Object.defineProperty(document, 'hidden', { value: true, writable: true });
3+
const ev = document.createEvent('Event');
4+
ev.initEvent('visibilitychange');
5+
document.dispatchEvent(ev);
6+
});
7+
8+
document.getElementById('fetch').addEventListener('click', () => {
9+
fetch('https://example.com');
10+
});
11+
12+
document.getElementById('xhr').addEventListener('click', () => {
13+
const xhr = new XMLHttpRequest();
14+
xhr.open('GET', 'https://example.com');
15+
xhr.send();
16+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button id="go-background">Go to background</button>
8+
<button id="fetch">New Fetch Request</button>
9+
<button id="xhr">New Fetch Request</button>
10+
</body>
11+
</html>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../utils/fixtures';
4+
import { expectedFetchPerformanceSpan, expectedXHRPerformanceSpan } from '../../../utils/replayEventTemplates';
5+
import { getReplayRecordingContent, shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers';
6+
7+
sentryTest('replay recording should contain fetch request span', async ({ getLocalTestPath, page }) => {
8+
if (shouldSkipReplayTest()) {
9+
sentryTest.skip();
10+
}
11+
12+
const reqPromise0 = waitForReplayRequest(page, 0);
13+
const reqPromise1 = waitForReplayRequest(page, 1);
14+
15+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
16+
return route.fulfill({
17+
status: 200,
18+
contentType: 'application/json',
19+
body: JSON.stringify({ id: 'test-id' }),
20+
});
21+
});
22+
23+
await page.route('https://example.com', route => {
24+
return route.fulfill({
25+
status: 200,
26+
contentType: 'application/json',
27+
body: 'hello world',
28+
});
29+
});
30+
31+
const url = await getLocalTestPath({ testDir: __dirname });
32+
33+
await page.goto(url);
34+
await page.click('#fetch');
35+
await page.click('#go-background');
36+
37+
const { performanceSpans: spans0 } = getReplayRecordingContent(await reqPromise0);
38+
const { performanceSpans: spans1 } = getReplayRecordingContent(await reqPromise1);
39+
const performanceSpans = [...spans0, ...spans1];
40+
41+
expect(performanceSpans).toContainEqual(expectedFetchPerformanceSpan);
42+
});
43+
44+
sentryTest('replay recording should contain XHR request span', async ({ getLocalTestPath, page }) => {
45+
if (shouldSkipReplayTest()) {
46+
sentryTest.skip();
47+
}
48+
49+
const reqPromise0 = waitForReplayRequest(page, 0);
50+
const reqPromise1 = waitForReplayRequest(page, 1);
51+
52+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
53+
return route.fulfill({
54+
status: 200,
55+
contentType: 'application/json',
56+
body: JSON.stringify({ id: 'test-id' }),
57+
});
58+
});
59+
60+
await page.route('https://example.com', route => {
61+
return route.fulfill({
62+
status: 200,
63+
contentType: 'application/json',
64+
body: 'hello world',
65+
});
66+
});
67+
68+
const url = await getLocalTestPath({ testDir: __dirname });
69+
70+
await page.goto(url);
71+
await page.click('#xhr');
72+
await page.click('#go-background');
73+
74+
const { performanceSpans: spans0 } = getReplayRecordingContent(await reqPromise0);
75+
const { performanceSpans: spans1 } = getReplayRecordingContent(await reqPromise1);
76+
const performanceSpans = [...spans0, ...spans1];
77+
78+
expect(performanceSpans).toContainEqual(expectedXHRPerformanceSpan);
79+
});

packages/integration-tests/utils/replayEventTemplates.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,28 @@ export const expectedFPPerformanceSpan = {
130130
endTimestamp: expect.any(Number),
131131
};
132132

133+
export const expectedFetchPerformanceSpan = {
134+
op: 'resource.fetch',
135+
description: expect.any(String),
136+
startTimestamp: expect.any(Number),
137+
endTimestamp: expect.any(Number),
138+
data: {
139+
method: expect.any(String),
140+
statusCode: expect.any(Number),
141+
},
142+
};
143+
144+
export const expectedXHRPerformanceSpan = {
145+
op: 'resource.xhr',
146+
description: expect.any(String),
147+
startTimestamp: expect.any(Number),
148+
endTimestamp: expect.any(Number),
149+
data: {
150+
method: expect.any(String),
151+
statusCode: expect.any(Number),
152+
},
153+
};
154+
133155
/* Breadcrumbs */
134156

135157
export const expectedClickBreadcrumb = {

0 commit comments

Comments
 (0)