Skip to content

Commit a8c3c1b

Browse files
committed
Fix replay event snapshots
Allow to normalize number attributes to make it a bit less flaky
1 parent 20f3e62 commit a8c3c1b

File tree

4 files changed

+47
-19
lines changed

4 files changed

+47
-19
lines changed

packages/integration-tests/suites/replay/privacyBlock/test.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { expect } from '@playwright/test';
2-
import { EventType } from '@sentry-internal/rrweb';
3-
import type { RecordingEvent } from '@sentry/replay/build/npm/types/types';
42

53
import { sentryTest } from '../../../utils/fixtures';
6-
import { envelopeRequestParser } from '../../../utils/helpers';
7-
import { shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers';
4+
import {
5+
getFullRecordingSnapshots,
6+
normalize,
7+
shouldSkipReplayTest,
8+
waitForReplayRequest,
9+
} from '../../../utils/replayHelpers';
810

911
sentryTest('should allow to manually block elements', async ({ getLocalTestPath, page }) => {
1012
if (shouldSkipReplayTest()) {
@@ -24,8 +26,10 @@ sentryTest('should allow to manually block elements', async ({ getLocalTestPath,
2426
const url = await getLocalTestPath({ testDir: __dirname });
2527

2628
await page.goto(url);
27-
const replayPayload = envelopeRequestParser<RecordingEvent[]>(await reqPromise0, 5);
28-
const checkoutEvent = replayPayload.find(({ type }) => type === EventType.FullSnapshot);
29+
const snapshots = getFullRecordingSnapshots(await reqPromise0);
30+
expect(snapshots.length).toEqual(1);
2931

30-
expect(JSON.stringify(checkoutEvent?.data, null, 2)).toMatchSnapshot('privacy.json');
32+
const stringifiedSnapshot = normalize(snapshots[0], { normalizeNumberAttributes: ['rr_width', 'rr_height'] });
33+
34+
expect(stringifiedSnapshot).toMatchSnapshot('privacy.json');
3135
});

packages/integration-tests/suites/replay/privacyBlock/test.ts-snapshots/privacy-firefox.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@
288288
"attributes": {
289289
"class": "nested-hide",
290290
"rr_width": "1264px",
291-
"rr_height": "19.199996948242188px"
291+
"rr_height": "19px"
292292
},
293293
"childNodes": [],
294294
"id": 40

packages/integration-tests/suites/replay/privacyDefault/test.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { expect } from '@playwright/test';
2-
import { EventType } from '@sentry-internal/rrweb';
3-
import type { RecordingEvent } from '@sentry/replay/build/npm/types/types';
42

53
import { sentryTest } from '../../../utils/fixtures';
6-
import { envelopeRequestParser } from '../../../utils/helpers';
7-
import { shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers';
4+
import {
5+
getFullRecordingSnapshots,
6+
normalize,
7+
shouldSkipReplayTest,
8+
waitForReplayRequest,
9+
} from '../../../utils/replayHelpers';
810

911
sentryTest('should have the correct default privacy settings', async ({ getLocalTestPath, page }) => {
1012
if (shouldSkipReplayTest()) {
@@ -24,8 +26,11 @@ sentryTest('should have the correct default privacy settings', async ({ getLocal
2426
const url = await getLocalTestPath({ testDir: __dirname });
2527

2628
await page.goto(url);
27-
const replayPayload = envelopeRequestParser<RecordingEvent[]>(await reqPromise0, 5);
28-
const checkoutEvent = replayPayload.find(({ type }) => type === EventType.FullSnapshot);
2929

30-
expect(JSON.stringify(checkoutEvent?.data, null, 2)).toMatchSnapshot('privacy.json');
30+
const snapshots = getFullRecordingSnapshots(await reqPromise0);
31+
expect(snapshots.length).toEqual(1);
32+
33+
const stringifiedSnapshot = normalize(snapshots[0], { normalizeNumberAttributes: ['rr_width', 'rr_height'] });
34+
35+
expect(stringifiedSnapshot).toMatchSnapshot('privacy.json');
3136
});

packages/integration-tests/utils/replayHelpers.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export function getFullRecordingSnapshots(replayRequest: Request): RecordingSnap
133133
return events.filter(event => event.type === 2).map(event => event.data as RecordingSnapshot);
134134
}
135135

136-
function getincrementalRecordingSnapshots(replayRequest: Request): RecordingSnapshot[] {
136+
function getIncrementalRecordingSnapshots(replayRequest: Request): RecordingSnapshot[] {
137137
const events = getDecompressedRecordingEvents(replayRequest) as RecordingEvent[];
138138
return events.filter(event => event.type === 3).map(event => event.data as RecordingSnapshot);
139139
}
@@ -144,7 +144,7 @@ function getDecompressedRecordingEvents(replayRequest: Request): RecordingEvent[
144144

145145
export function getReplayRecordingContent(replayRequest: Request): RecordingContent {
146146
const fullSnapshots = getFullRecordingSnapshots(replayRequest);
147-
const incrementalSnapshots = getincrementalRecordingSnapshots(replayRequest);
147+
const incrementalSnapshots = getIncrementalRecordingSnapshots(replayRequest);
148148
const customEvents = getCustomRecordingEvents(replayRequest);
149149

150150
return { fullSnapshots, incrementalSnapshots, ...customEvents };
@@ -216,10 +216,29 @@ export function shouldSkipReplayTest(): boolean {
216216
* files which break the tests on different machines.
217217
* Also, we need to normalize any time offsets as they can vary and cause flakes.
218218
*/
219-
export function normalize(obj: unknown): string {
219+
export function normalize(
220+
obj: unknown,
221+
{ normalizeNumberAttributes }: { normalizeNumberAttributes?: string[] } = {},
222+
): string {
220223
const rawString = JSON.stringify(obj, null, 2);
221-
const normalizedString = rawString
224+
let normalizedString = rawString
222225
.replace(/"file:\/\/.+(\/.*\.html)"/gm, '"$1"')
223226
.replace(/"timeOffset":\s*-?\d+/gm, '"timeOffset": [timeOffset]');
227+
228+
if (normalizeNumberAttributes?.length) {
229+
// We look for: "attr": "123px", "123", "123%", "123em", "123rem"
230+
const regex = new RegExp(
231+
`"(${normalizeNumberAttributes
232+
.map(attr => `(?:${attr})`)
233+
.join('|')})":\\s*"([\\d\\.]+)((?:px)|%|(?:em)(?:rem))?"`,
234+
'gm',
235+
);
236+
237+
normalizedString = normalizedString.replace(regex, (_, attr, num, unit) => {
238+
// Remove floating points here, to ensure this is a bit less flaky
239+
return `"${attr}": "${parseInt(num, 10)}${unit || ''}"`;
240+
});
241+
}
242+
224243
return normalizedString;
225244
}

0 commit comments

Comments
 (0)