Skip to content

test: Fix flaky replay error mode test #7307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions packages/integration-tests/suites/replay/errors/errorMode/test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../../utils/fixtures';
import { envelopeRequestParser } from '../../../../utils/helpers';
import { envelopeRequestParser, waitForErrorRequest } from '../../../../utils/helpers';
import {
expectedClickBreadcrumb,
expectedConsoleBreadcrumb,
Expand All @@ -10,6 +10,7 @@ import {
import {
getReplayEvent,
getReplayRecordingContent,
isReplayEvent,
shouldSkipReplayTest,
waitForReplayRequest,
} from '../../../../utils/replayHelpers';
Expand All @@ -26,14 +27,18 @@ sentryTest(
const reqPromise0 = waitForReplayRequest(page, 0);
const reqPromise1 = waitForReplayRequest(page, 1);
const reqPromise2 = waitForReplayRequest(page, 2);
const reqErrorPromise = waitForErrorRequest(page);

await page.route('https://dsn.ingest.sentry.io/**/*', route => {
const event = envelopeRequestParser(route.request());
// error events have no type field
if (event && !event.type && event.event_id) {
errorEventId = event.event_id;
}
callsToSentry++;
// We only want to count errors & replays here
if (event && (!event.type || isReplayEvent(event))) {
callsToSentry++;
}

return route.fulfill({
status: 200,
Expand All @@ -46,13 +51,16 @@ sentryTest(

await page.goto(url);
await page.click('#go-background');
await new Promise(resolve => setTimeout(resolve, 1000));

expect(callsToSentry).toEqual(0);

await page.click('#error');
const req0 = await reqPromise0;

await page.click('#go-background');
const req1 = await reqPromise1;
await reqErrorPromise;

expect(callsToSentry).toEqual(3); // 1 error, 2 replay events

Expand All @@ -69,11 +77,12 @@ sentryTest(
const event2 = getReplayEvent(req2);
const content2 = getReplayRecordingContent(req2);

expect(callsToSentry).toBe(4); // 1 error, 3 replay events

expect(event0).toEqual(
getExpectedReplayEvent({
contexts: { replay: { error_sample_rate: 1, session_sample_rate: 0 } },
// @ts-ignore this is fine
error_ids: [errorEventId],
error_ids: [errorEventId!],
replay_type: 'error',
}),
);
Expand All @@ -97,7 +106,6 @@ sentryTest(
expect(event1).toEqual(
getExpectedReplayEvent({
contexts: { replay: { error_sample_rate: 1, session_sample_rate: 0 } },
// @ts-ignore this is fine
replay_type: 'error', // although we're in session mode, we still send 'error' as replay_type
replay_start_timestamp: undefined,
segment_id: 1,
Expand All @@ -108,14 +116,12 @@ sentryTest(
// Also the second snapshot should have a full snapshot, as we switched from error to session
// mode which triggers another checkout
expect(content1.fullSnapshots).toHaveLength(1);
expect(content1.incrementalSnapshots).toHaveLength(0);

// The next event should just be a normal replay event as we're now in session mode and
// we continue recording everything
expect(event2).toEqual(
getExpectedReplayEvent({
contexts: { replay: { error_sample_rate: 1, session_sample_rate: 0 } },
// @ts-ignore this is fine
replay_type: 'error',
replay_start_timestamp: undefined,
segment_id: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ sentryTest(
const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);
await page.click('#go-background');
const req0 = await reqPromise0;

await page.click('#error');
Expand All @@ -57,7 +56,6 @@ sentryTest(
getExpectedReplayEvent({
replay_start_timestamp: undefined,
segment_id: 1,
// @ts-ignore this is fine
error_ids: [errorEventId],
urls: [],
}),
Expand Down
4 changes: 2 additions & 2 deletions packages/integration-tests/suites/replay/errors/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;
window.Replay = new Sentry.Replay({
flushMinDelay: 500,
flushMaxDelay: 500,
flushMinDelay: 1000,
flushMaxDelay: 1000,
});

Sentry.init({
Expand Down
17 changes: 17 additions & 0 deletions packages/integration-tests/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,23 @@ async function getSentryEvents(page: Page, url?: string): Promise<Array<Event>>
return eventsHandle.jsonValue();
}

export function waitForErrorRequest(page: Page): Promise<Request> {
return page.waitForRequest(req => {
const postData = req.postData();
if (!postData) {
return false;
}

try {
const event = envelopeRequestParser(req);

return !event.type;
} catch {
return false;
}
});
}

/**
* Waits until a number of requests matching urlRgx at the given URL arrive.
* If the timout option is configured, this function will abort waiting, even if it hasn't reveived the configured
Expand Down
2 changes: 1 addition & 1 deletion packages/integration-tests/utils/replayHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function waitForReplayRequest(page: Page, segmentId?: number): Promise<Re
});
}

function isReplayEvent(event: Event): event is ReplayEvent {
export function isReplayEvent(event: Event): event is ReplayEvent {
return event.type === 'replay_event';
}

Expand Down