Skip to content

Commit 1390402

Browse files
billyvgmydea
andauthored
test(replay): Fix flakey extendNetworkBreadcrumbs/fetch tests (#11142)
See #11140 Closes #9119 --------- Co-authored-by: Francesco Novy <[email protected]>
1 parent d651f13 commit 1390402

File tree

5 files changed

+202
-171
lines changed

5 files changed

+202
-171
lines changed

.github/workflows/flaky-test-detector.yml

+9
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,17 @@ jobs:
7979
browser_integration: dev-packages/browser-integration-tests/suites/**/test.ts
8080
8181
- name: Detect flaky tests
82+
id: test
8283
run: yarn test:detect-flaky
8384
working-directory: dev-packages/browser-integration-tests
8485
env:
8586
CHANGED_TEST_PATHS: ${{ steps.changed.outputs.browser_integration_files }}
8687
TEST_RUN_COUNT: 'AUTO'
88+
89+
- name: Artifacts upload
90+
uses: actions/upload-artifact@v4
91+
if: failure() && steps.test.outcome == 'failure'
92+
with:
93+
name: playwright-test-results
94+
path: test-results
95+
retention-days: 5

dev-packages/browser-integration-tests/suites/replay/extendNetworkBreadcrumbs/fetch/captureRequestHeaders/test.ts

+98-90
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import {
88
shouldSkipReplayTest,
99
} from '../../../../../utils/replayHelpers';
1010

11-
// Skipping because this test is flaky
12-
// https://github.com/getsentry/sentry-javascript/issues/11062
13-
sentryTest.skip('handles empty/missing request headers', async ({ getLocalTestPath, page, browserName }) => {
11+
sentryTest('handles empty/missing request headers', async ({ getLocalTestPath, page, browserName }) => {
1412
if (shouldSkipReplayTest()) {
1513
sentryTest.skip();
1614
}
@@ -37,18 +35,21 @@ sentryTest.skip('handles empty/missing request headers', async ({ getLocalTestPa
3735
const url = await getLocalTestPath({ testDir: __dirname });
3836
await page.goto(url);
3937

40-
await page.evaluate(() => {
41-
/* eslint-disable */
42-
fetch('http://localhost:7654/foo', {
43-
method: 'POST',
44-
}).then(() => {
45-
// @ts-expect-error Sentry is a global
46-
Sentry.captureException('test error');
47-
});
48-
/* eslint-enable */
49-
});
38+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
39+
page.evaluate(() => {
40+
/* eslint-disable */
41+
fetch('http://localhost:7654/foo', {
42+
method: 'POST',
43+
}).then(() => {
44+
// @ts-expect-error Sentry is a global
45+
Sentry.captureException('test error');
46+
});
47+
/* eslint-enable */
48+
}),
49+
requestPromise,
50+
replayRequestPromise,
51+
]);
5052

51-
const request = await requestPromise;
5253
const eventData = envelopeRequestParser(request);
5354

5455
expect(eventData.exception?.values).toHaveLength(1);
@@ -65,7 +66,6 @@ sentryTest.skip('handles empty/missing request headers', async ({ getLocalTestPa
6566
},
6667
});
6768

68-
const { replayRecordingSnapshots } = await replayRequestPromise;
6969
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
7070
{
7171
data: {
@@ -110,25 +110,28 @@ sentryTest('captures request headers as POJO', async ({ getLocalTestPath, page,
110110
const url = await getLocalTestPath({ testDir: __dirname });
111111
await page.goto(url);
112112

113-
await page.evaluate(() => {
114-
/* eslint-disable */
115-
fetch('http://localhost:7654/foo', {
116-
method: 'POST',
117-
headers: {
118-
Accept: 'application/json',
119-
'Content-Type': 'application/json',
120-
Cache: 'no-cache',
121-
'X-Custom-Header': 'foo',
122-
'X-Test-Header': 'test-value',
123-
},
124-
}).then(() => {
125-
// @ts-expect-error Sentry is a global
126-
Sentry.captureException('test error');
127-
});
128-
/* eslint-enable */
129-
});
113+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
114+
page.evaluate(() => {
115+
/* eslint-disable */
116+
fetch('http://localhost:7654/foo', {
117+
method: 'POST',
118+
headers: {
119+
Accept: 'application/json',
120+
'Content-Type': 'application/json',
121+
Cache: 'no-cache',
122+
'X-Custom-Header': 'foo',
123+
'X-Test-Header': 'test-value',
124+
},
125+
}).then(() => {
126+
// @ts-expect-error Sentry is a global
127+
Sentry.captureException('test error');
128+
});
129+
/* eslint-enable */
130+
}),
131+
requestPromise,
132+
replayRequestPromise,
133+
]);
130134

131-
const request = await requestPromise;
132135
const eventData = envelopeRequestParser(request);
133136

134137
expect(eventData.exception?.values).toHaveLength(1);
@@ -145,7 +148,6 @@ sentryTest('captures request headers as POJO', async ({ getLocalTestPath, page,
145148
},
146149
});
147150

148-
const { replayRecordingSnapshots } = await replayRequestPromise;
149151
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
150152
{
151153
data: {
@@ -195,25 +197,28 @@ sentryTest('captures request headers on Request', async ({ getLocalTestPath, pag
195197
const url = await getLocalTestPath({ testDir: __dirname });
196198
await page.goto(url);
197199

198-
await page.evaluate(() => {
199-
const request = new Request('http://localhost:7654/foo', {
200-
method: 'POST',
201-
headers: {
202-
Accept: 'application/json',
203-
'Content-Type': 'application/json',
204-
Cache: 'no-cache',
205-
'X-Custom-Header': 'foo',
206-
},
207-
});
208-
/* eslint-disable */
209-
fetch(request).then(() => {
210-
// @ts-expect-error Sentry is a global
211-
Sentry.captureException('test error');
212-
});
213-
/* eslint-enable */
214-
});
200+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
201+
page.evaluate(() => {
202+
const request = new Request('http://localhost:7654/foo', {
203+
method: 'POST',
204+
headers: {
205+
Accept: 'application/json',
206+
'Content-Type': 'application/json',
207+
Cache: 'no-cache',
208+
'X-Custom-Header': 'foo',
209+
},
210+
});
211+
/* eslint-disable */
212+
fetch(request).then(() => {
213+
// @ts-expect-error Sentry is a global
214+
Sentry.captureException('test error');
215+
});
216+
/* eslint-enable */
217+
}),
218+
requestPromise,
219+
replayRequestPromise,
220+
]);
215221

216-
const request = await requestPromise;
217222
const eventData = envelopeRequestParser(request);
218223

219224
expect(eventData.exception?.values).toHaveLength(1);
@@ -230,7 +235,6 @@ sentryTest('captures request headers on Request', async ({ getLocalTestPath, pag
230235
},
231236
});
232237

233-
const { replayRecordingSnapshots } = await replayRequestPromise;
234238
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
235239
{
236240
data: {
@@ -280,25 +284,28 @@ sentryTest('captures request headers as Headers instance', async ({ getLocalTest
280284

281285
await page.goto(url);
282286

283-
await page.evaluate(() => {
284-
const headers = new Headers();
285-
headers.append('Accept', 'application/json');
286-
headers.append('Content-Type', 'application/json');
287-
headers.append('Cache', 'no-cache');
288-
headers.append('X-Custom-Header', 'foo');
287+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
288+
page.evaluate(() => {
289+
const headers = new Headers();
290+
headers.append('Accept', 'application/json');
291+
headers.append('Content-Type', 'application/json');
292+
headers.append('Cache', 'no-cache');
293+
headers.append('X-Custom-Header', 'foo');
289294

290-
/* eslint-disable */
291-
fetch('http://localhost:7654/foo', {
292-
method: 'POST',
293-
headers,
294-
}).then(() => {
295-
// @ts-expect-error Sentry is a global
296-
Sentry.captureException('test error');
297-
});
298-
/* eslint-enable */
299-
});
295+
/* eslint-disable */
296+
fetch('http://localhost:7654/foo', {
297+
method: 'POST',
298+
headers,
299+
}).then(() => {
300+
// @ts-expect-error Sentry is a global
301+
Sentry.captureException('test error');
302+
});
303+
/* eslint-enable */
304+
}),
305+
requestPromise,
306+
replayRequestPromise,
307+
]);
300308

301-
const request = await requestPromise;
302309
const eventData = envelopeRequestParser(request);
303310

304311
expect(eventData.exception?.values).toHaveLength(1);
@@ -315,7 +322,6 @@ sentryTest('captures request headers as Headers instance', async ({ getLocalTest
315322
},
316323
});
317324

318-
const { replayRecordingSnapshots } = await replayRequestPromise;
319325
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
320326
{
321327
data: {
@@ -364,25 +370,28 @@ sentryTest('does not captures request headers if URL does not match', async ({ g
364370
const url = await getLocalTestPath({ testDir: __dirname });
365371
await page.goto(url);
366372

367-
await page.evaluate(() => {
368-
/* eslint-disable */
369-
fetch('http://localhost:7654/bar', {
370-
method: 'POST',
371-
headers: {
372-
Accept: 'application/json',
373-
'Content-Type': 'application/json',
374-
Cache: 'no-cache',
375-
'X-Custom-Header': 'foo',
376-
'X-Test-Header': 'test-value',
377-
},
378-
}).then(() => {
379-
// @ts-expect-error Sentry is a global
380-
Sentry.captureException('test error');
381-
});
382-
/* eslint-enable */
383-
});
373+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
374+
page.evaluate(() => {
375+
/* eslint-disable */
376+
fetch('http://localhost:7654/bar', {
377+
method: 'POST',
378+
headers: {
379+
Accept: 'application/json',
380+
'Content-Type': 'application/json',
381+
Cache: 'no-cache',
382+
'X-Custom-Header': 'foo',
383+
'X-Test-Header': 'test-value',
384+
},
385+
}).then(() => {
386+
// @ts-expect-error Sentry is a global
387+
Sentry.captureException('test error');
388+
});
389+
/* eslint-enable */
390+
}),
391+
requestPromise,
392+
replayRequestPromise,
393+
]);
384394

385-
const request = await requestPromise;
386395
const eventData = envelopeRequestParser(request);
387396

388397
expect(eventData.exception?.values).toHaveLength(1);
@@ -399,7 +408,6 @@ sentryTest('does not captures request headers if URL does not match', async ({ g
399408
},
400409
});
401410

402-
const { replayRecordingSnapshots } = await replayRequestPromise;
403411
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
404412
{
405413
data: {

dev-packages/browser-integration-tests/suites/replay/extendNetworkBreadcrumbs/fetch/captureRequestSize/test.ts

+32-30
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import {
88
shouldSkipReplayTest,
99
} from '../../../../../utils/replayHelpers';
1010

11-
// Skipping because this test is flaky
12-
// https://github.com/getsentry/sentry-javascript/issues/10395
13-
sentryTest.skip('captures request body size when body is sent', async ({ getLocalTestPath, page }) => {
11+
sentryTest('captures request body size when body is sent', async ({ getLocalTestPath, page }) => {
1412
if (shouldSkipReplayTest()) {
1513
sentryTest.skip();
1614
}
@@ -37,19 +35,22 @@ sentryTest.skip('captures request body size when body is sent', async ({ getLoca
3735
const url = await getLocalTestPath({ testDir: __dirname });
3836
await page.goto(url);
3937

40-
await page.evaluate(() => {
41-
/* eslint-disable */
42-
fetch('http://localhost:7654/foo', {
43-
method: 'POST',
44-
body: '{"foo":"bar"}',
45-
}).then(() => {
46-
// @ts-expect-error Sentry is a global
47-
Sentry.captureException('test error');
48-
});
49-
/* eslint-enable */
50-
});
38+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
39+
page.evaluate(() => {
40+
/* eslint-disable */
41+
fetch('http://localhost:7654/foo', {
42+
method: 'POST',
43+
body: '{"foo":"bar"}',
44+
}).then(() => {
45+
// @ts-expect-error Sentry is a global
46+
Sentry.captureException('test error');
47+
});
48+
/* eslint-enable */
49+
}),
50+
requestPromise,
51+
replayRequestPromise,
52+
]);
5153

52-
const request = await requestPromise;
5354
const eventData = envelopeRequestParser(request);
5455

5556
expect(eventData.exception?.values).toHaveLength(1);
@@ -67,7 +68,6 @@ sentryTest.skip('captures request body size when body is sent', async ({ getLoca
6768
},
6869
});
6970

70-
const { replayRecordingSnapshots } = await replayRequestPromise;
7171
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
7272
{
7373
data: {
@@ -122,21 +122,24 @@ sentryTest('captures request size from non-text request body', async ({ getLocal
122122
const url = await getLocalTestPath({ testDir: __dirname });
123123
await page.goto(url);
124124

125-
await page.evaluate(() => {
126-
/* eslint-disable */
127-
const blob = new Blob(['<html>Hello world!!</html>'], { type: 'text/html' });
125+
const [, request, { replayRecordingSnapshots }] = await Promise.all([
126+
page.evaluate(() => {
127+
/* eslint-disable */
128+
const blob = new Blob(['<html>Hello world!!</html>'], { type: 'text/html' });
128129

129-
fetch('http://localhost:7654/foo', {
130-
method: 'POST',
131-
body: blob,
132-
}).then(() => {
133-
// @ts-expect-error Sentry is a global
134-
Sentry.captureException('test error');
135-
});
136-
/* eslint-enable */
137-
});
130+
fetch('http://localhost:7654/foo', {
131+
method: 'POST',
132+
body: blob,
133+
}).then(() => {
134+
// @ts-expect-error Sentry is a global
135+
Sentry.captureException('test error');
136+
});
137+
/* eslint-enable */
138+
}),
139+
requestPromise,
140+
replayRequestPromise,
141+
]);
138142

139-
const request = await requestPromise;
140143
const eventData = envelopeRequestParser(request);
141144

142145
expect(eventData.exception?.values).toHaveLength(1);
@@ -154,7 +157,6 @@ sentryTest('captures request size from non-text request body', async ({ getLocal
154157
},
155158
});
156159

157-
const { replayRecordingSnapshots } = await replayRequestPromise;
158160
expect(getReplayPerformanceSpans(replayRecordingSnapshots).filter(span => span.op === 'resource.fetch')).toEqual([
159161
{
160162
data: {

0 commit comments

Comments
 (0)