From d8a7d454d25ed548e16166d7e7dd4d5527557b59 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 3 Feb 2023 12:59:51 +0100 Subject: [PATCH 1/8] add helpers --- packages/integration-tests/utils/helpers.ts | 4 +- .../utils/replayEventTemplates.ts | 112 ++++++++++++++++++ .../integration-tests/utils/replayHelpers.ts | 56 ++++++++- 3 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 packages/integration-tests/utils/replayEventTemplates.ts diff --git a/packages/integration-tests/utils/helpers.ts b/packages/integration-tests/utils/helpers.ts index 443e3e0e57af..5fb2aafff3e1 100644 --- a/packages/integration-tests/utils/helpers.ts +++ b/packages/integration-tests/utils/helpers.ts @@ -17,8 +17,8 @@ export const envelopeParser = (request: Request | null): unknown[] => { }); }; -export const envelopeRequestParser = (request: Request | null): Event => { - return envelopeParser(request)[2] as Event; +export const envelopeRequestParser = (request: Request | null, envelopeIndex = 2): Event => { + return envelopeParser(request)[envelopeIndex] as Event; }; export const envelopeHeaderRequestParser = (request: Request | null): EventEnvelopeHeaders => { diff --git a/packages/integration-tests/utils/replayEventTemplates.ts b/packages/integration-tests/utils/replayEventTemplates.ts new file mode 100644 index 000000000000..c3cc7f4fe819 --- /dev/null +++ b/packages/integration-tests/utils/replayEventTemplates.ts @@ -0,0 +1,112 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { expect } from '@playwright/test'; +import { SDK_VERSION } from '@sentry/browser'; +import type { ReplayEvent } from '@sentry/types'; + +const DEFAULT_REPLAY_EVENT = { + type: 'replay_event', + timestamp: expect.any(Number), + error_ids: [], + trace_ids: [], + urls: [expect.stringContaining('/dist/index.html')], + replay_id: expect.stringMatching(/\w{32}/), + replay_start_timestamp: expect.any(Number), + segment_id: 0, + replay_type: 'session', + event_id: expect.stringMatching(/\w{32}/), + environment: 'production', + sdk: { + integrations: [ + 'InboundFilters', + 'FunctionToString', + 'TryCatch', + 'Breadcrumbs', + 'GlobalHandlers', + 'LinkedErrors', + 'Dedupe', + 'HttpContext', + 'Replay', + ], + version: SDK_VERSION, + name: 'sentry.javascript.browser', + }, + sdkProcessingMetadata: {}, + request: { + url: expect.stringContaining('/dist/index.html'), + headers: { + 'User-Agent': expect.stringContaining(''), + }, + }, + platform: 'javascript', + contexts: { replay: { session_sample_rate: 1, error_sample_rate: 0 } }, +}; + +/** + * Creates a ReplayEvent object with the default values merged with the customExpectedReplayEvent. + * This is useful for testing multi-segment replays to not repeat most of the properties that don't change + * throughout the replay segments. + * + * Note: The benfit of this approach over expect.objectContaining is that, + * we'll catch if properties we expect to stay the same actually change. + * + * @param customExpectedReplayEvent overwrite the default values with custom values (e.g. segment_id) + */ +export function getExpectedReplayEvent(customExpectedReplayEvent: Partial & Record = {}) { + return { + ...DEFAULT_REPLAY_EVENT, + ...customExpectedReplayEvent, + }; +} + +/* This is how we expect different kinds of navigation performance span to look: */ + +export const expectedNavigationPerformanceSpan = { + op: 'navigation.navigate', + description: '', + startTimestamp: expect.any(Number), + endTimestamp: expect.any(Number), + data: { + duration: expect.any(Number), + size: expect.any(Number), + }, +}; + +export const expectedMemoryPerformanceSpan = { + op: 'memory', + description: 'memory', + startTimestamp: expect.any(Number), + endTimestamp: expect.any(Number), + data: { + memory: { + jsHeapSizeLimit: expect.any(Number), + totalJSHeapSize: expect.any(Number), + usedJSHeapSize: expect.any(Number), + }, + }, +}; + +export const expectedLCPPerformanceSpan = { + op: 'largest-contentful-paint', + description: 'largest-contentful-paint', + startTimestamp: expect.any(Number), + endTimestamp: expect.any(Number), + data: { + duration: expect.any(Number), + nodeId: expect.any(Number), + size: expect.any(Number), + }, +}; + +export const expectedFCPPerformanceSpan = { + op: 'paint', + description: 'first-contentful-paint', + startTimestamp: expect.any(Number), + endTimestamp: expect.any(Number), +}; + +export const expectedFPPerformanceSpan = { + op: 'paint', + description: 'first-paint', + startTimestamp: expect.any(Number), + endTimestamp: expect.any(Number), +}; diff --git a/packages/integration-tests/utils/replayHelpers.ts b/packages/integration-tests/utils/replayHelpers.ts index 601285c266b9..009e40d32047 100644 --- a/packages/integration-tests/utils/replayHelpers.ts +++ b/packages/integration-tests/utils/replayHelpers.ts @@ -1,9 +1,18 @@ -import type { ReplayContainer } from '@sentry/replay/build/npm/types/types'; -import type { Event, ReplayEvent } from '@sentry/types'; +import type { RecordingEvent, ReplayContainer } from '@sentry/replay/build/npm/types/types'; +import type { Breadcrumb, Event, ReplayEvent } from '@sentry/types'; import type { Page, Request } from 'playwright'; import { envelopeRequestParser } from './helpers'; +type CustomRecordingEvent = { tag: string; payload: Record }; +type PerformanceSpan = { + op: string; + description: string; + startTimestamp: number; + endTimestamp: number; + data: Record; +}; + /** * Waits for a replay request to be sent by the page and returns it. * @@ -56,3 +65,46 @@ export async function getReplaySnapshot(page: Page): Promise { } export const REPLAY_DEFAULT_FLUSH_MAX_DELAY = 5_000; + +export function getReplayEvent(replayRequest: Request): ReplayEvent { + const event = envelopeRequestParser(replayRequest); + if (!isReplayEvent(event)) { + throw new Error('Request is not a replay event'); + } + return event; +} + +/** + * Takes an uncompressed replay request and returns the custom recording events, + * i.e. the events we emit as type 5 rrweb events + * + * @param replayRequest + * @returns an object containing the replay breadcrumbs and performance spans + */ +export function getCustomRecordingEvents(replayRequest: Request): { + breadcrumbs: Breadcrumb[]; + performanceSpans: PerformanceSpan[]; +} { + const recordingEvents = envelopeRequestParser(replayRequest, 5) as RecordingEvent[]; + + const breadcrumbs = getReplayBreadcrumbs(recordingEvents); + const performanceSpans = getReplayPerformanceSpans(recordingEvents); + return { breadcrumbs, performanceSpans }; +} + +function getAllCustomRrwebRecordingEvents(recordingEvents: RecordingEvent[]): CustomRecordingEvent[] { + return recordingEvents.filter(event => event.type === 5).map(event => event.data as CustomRecordingEvent); +} + +function getReplayBreadcrumbs(recordingEvents: RecordingEvent[], category?: string): Breadcrumb[] { + return getAllCustomRrwebRecordingEvents(recordingEvents) + .filter(data => data.tag === 'breadcrumb') + .map(data => data.payload) + .filter(payload => !category || payload.category === category); +} + +function getReplayPerformanceSpans(recordingEvents: RecordingEvent[]): PerformanceSpan[] { + return getAllCustomRrwebRecordingEvents(recordingEvents) + .filter(data => data.tag === 'performanceSpan') + .map(data => data.payload) as PerformanceSpan[]; +} From 931ff471c15183d084c1d38d5832e0c263ce5d7a Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 3 Feb 2023 13:00:15 +0100 Subject: [PATCH 2/8] add first test --- .../suites/replay/customEvents/init.js | 18 +++++++ .../suites/replay/customEvents/template.html | 9 ++++ .../suites/replay/customEvents/test.ts | 54 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 packages/integration-tests/suites/replay/customEvents/init.js create mode 100644 packages/integration-tests/suites/replay/customEvents/template.html create mode 100644 packages/integration-tests/suites/replay/customEvents/test.ts diff --git a/packages/integration-tests/suites/replay/customEvents/init.js b/packages/integration-tests/suites/replay/customEvents/init.js new file mode 100644 index 000000000000..ccb9689a14d6 --- /dev/null +++ b/packages/integration-tests/suites/replay/customEvents/init.js @@ -0,0 +1,18 @@ +import * as Sentry from '@sentry/browser'; +import { Replay } from '@sentry/replay'; + +window.Sentry = Sentry; +window.Replay = new Replay({ + flushMinDelay: 200, + flushMaxDelay: 200, + useCompression: false, +}); + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + sampleRate: 0, + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 0.0, + + integrations: [window.Replay], +}); diff --git a/packages/integration-tests/suites/replay/customEvents/template.html b/packages/integration-tests/suites/replay/customEvents/template.html new file mode 100644 index 000000000000..2b3e2f0b27b4 --- /dev/null +++ b/packages/integration-tests/suites/replay/customEvents/template.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts new file mode 100644 index 000000000000..74bd661afe8a --- /dev/null +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -0,0 +1,54 @@ +import { expect } from '@playwright/test'; + +import { sentryTest } from '../../../utils/fixtures'; +import { + expectedFCPPerformanceSpan, + expectedFPPerformanceSpan, + expectedLCPPerformanceSpan, + expectedMemoryPerformanceSpan, + expectedNavigationPerformanceSpan, + getExpectedReplayEvent, +} from '../../../utils/replayEventTemplates'; +import { getCustomRecordingEvents, getReplayEvent, waitForReplayRequest } from '../../../utils/replayHelpers'; + +sentryTest('replay recording should contain default performance spans', async ({ getLocalTestPath, page }) => { + // Replay bundles are es6 only + if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { + sentryTest.skip(); + } + + const reqPromise0 = waitForReplayRequest(page, 0); + const reqPromise1 = waitForReplayRequest(page, 1); + + await page.route('https://dsn.ingest.sentry.io/**/*', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ id: 'test-id' }), + }); + }); + + const url = await getLocalTestPath({ testDir: __dirname }); + + await page.goto(url); + const replayEvent0 = getReplayEvent(await reqPromise0); + const { performanceSpans: performanceSpans0 } = getCustomRecordingEvents(await reqPromise0); + + expect(replayEvent0).toEqual(getExpectedReplayEvent({ segment_id: 0 })); + expect(performanceSpans0).toEqual([expectedMemoryPerformanceSpan]); + + await page.click('button'); + + const replayEvent1 = getReplayEvent(await reqPromise1); + const { performanceSpans: performanceSpans1 } = getCustomRecordingEvents(await reqPromise1); + + expect(replayEvent1).toEqual(getExpectedReplayEvent({ segment_id: 1, urls: [], replay_start_timestamp: undefined })); + + expect(performanceSpans1).toEqual([ + expectedNavigationPerformanceSpan, + expectedLCPPerformanceSpan, + expectedFPPerformanceSpan, + expectedFCPPerformanceSpan, + expectedMemoryPerformanceSpan, + ]); +}); From 9f5105c28d6c26b9da1baee8c37c81ccd8cabb4e Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 3 Feb 2023 15:25:27 +0100 Subject: [PATCH 3/8] check all spans at the end --- .../suites/replay/customEvents/test.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts index 74bd661afe8a..4513106efaee 100644 --- a/packages/integration-tests/suites/replay/customEvents/test.ts +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -35,7 +35,6 @@ sentryTest('replay recording should contain default performance spans', async ({ const { performanceSpans: performanceSpans0 } = getCustomRecordingEvents(await reqPromise0); expect(replayEvent0).toEqual(getExpectedReplayEvent({ segment_id: 0 })); - expect(performanceSpans0).toEqual([expectedMemoryPerformanceSpan]); await page.click('button'); @@ -44,11 +43,17 @@ sentryTest('replay recording should contain default performance spans', async ({ expect(replayEvent1).toEqual(getExpectedReplayEvent({ segment_id: 1, urls: [], replay_start_timestamp: undefined })); - expect(performanceSpans1).toEqual([ - expectedNavigationPerformanceSpan, - expectedLCPPerformanceSpan, - expectedFPPerformanceSpan, - expectedFCPPerformanceSpan, - expectedMemoryPerformanceSpan, - ]); + const collectedPerformanceSpans = [...performanceSpans0, ...performanceSpans1]; + + expect(collectedPerformanceSpans.length).toBe(6); + expect(collectedPerformanceSpans).toEqual( + expect.arrayContaining([ + expectedNavigationPerformanceSpan, + expectedLCPPerformanceSpan, + expectedFPPerformanceSpan, + expectedFCPPerformanceSpan, + expectedMemoryPerformanceSpan, // two memory spans - once per flush + expectedMemoryPerformanceSpan, + ]), + ); }); From d21b23f7115103bd9860ddec8c214c878ee9dc57 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 3 Feb 2023 15:44:37 +0100 Subject: [PATCH 4/8] go to background instead of click --- .../integration-tests/suites/replay/customEvents/init.js | 4 ++-- .../integration-tests/suites/replay/customEvents/subject.js | 6 ++++++ .../suites/replay/customEvents/template.html | 3 ++- .../integration-tests/suites/replay/customEvents/test.ts | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 packages/integration-tests/suites/replay/customEvents/subject.js diff --git a/packages/integration-tests/suites/replay/customEvents/init.js b/packages/integration-tests/suites/replay/customEvents/init.js index ccb9689a14d6..f02e43c7235c 100644 --- a/packages/integration-tests/suites/replay/customEvents/init.js +++ b/packages/integration-tests/suites/replay/customEvents/init.js @@ -3,8 +3,8 @@ import { Replay } from '@sentry/replay'; window.Sentry = Sentry; window.Replay = new Replay({ - flushMinDelay: 200, - flushMaxDelay: 200, + flushMinDelay: 500, + flushMaxDelay: 500, useCompression: false, }); diff --git a/packages/integration-tests/suites/replay/customEvents/subject.js b/packages/integration-tests/suites/replay/customEvents/subject.js new file mode 100644 index 000000000000..7aa69584f070 --- /dev/null +++ b/packages/integration-tests/suites/replay/customEvents/subject.js @@ -0,0 +1,6 @@ +document.getElementById('go-background').addEventListener('click', () => { + Object.defineProperty(document, 'hidden', { value: true, writable: true }); + const ev = document.createEvent('Event'); + ev.initEvent('visibilitychange'); + document.dispatchEvent(ev); +}); diff --git a/packages/integration-tests/suites/replay/customEvents/template.html b/packages/integration-tests/suites/replay/customEvents/template.html index 2b3e2f0b27b4..f8a9d72acf2d 100644 --- a/packages/integration-tests/suites/replay/customEvents/template.html +++ b/packages/integration-tests/suites/replay/customEvents/template.html @@ -4,6 +4,7 @@ - + + diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts index 4513106efaee..122b848a5e43 100644 --- a/packages/integration-tests/suites/replay/customEvents/test.ts +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -43,9 +43,10 @@ sentryTest('replay recording should contain default performance spans', async ({ expect(replayEvent1).toEqual(getExpectedReplayEvent({ segment_id: 1, urls: [], replay_start_timestamp: undefined })); + // We can't guarantee the order of the performance spans, or in which of the two segments they are sent + // So we collect them all and check that they are all there const collectedPerformanceSpans = [...performanceSpans0, ...performanceSpans1]; - expect(collectedPerformanceSpans.length).toBe(6); expect(collectedPerformanceSpans).toEqual( expect.arrayContaining([ expectedNavigationPerformanceSpan, From 89dea4c5add111e5d700af675ccf5ce5c4c4001b Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Fri, 3 Feb 2023 16:04:55 +0100 Subject: [PATCH 5/8] only run on chromium --- .../suites/replay/customEvents/test.ts | 81 ++++++++++--------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts index 122b848a5e43..2c5435c29cfb 100644 --- a/packages/integration-tests/suites/replay/customEvents/test.ts +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -11,50 +11,55 @@ import { } from '../../../utils/replayEventTemplates'; import { getCustomRecordingEvents, getReplayEvent, waitForReplayRequest } from '../../../utils/replayHelpers'; -sentryTest('replay recording should contain default performance spans', async ({ getLocalTestPath, page }) => { - // Replay bundles are es6 only - if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { - sentryTest.skip(); - } - - const reqPromise0 = waitForReplayRequest(page, 0); - const reqPromise1 = waitForReplayRequest(page, 1); - - await page.route('https://dsn.ingest.sentry.io/**/*', route => { - return route.fulfill({ - status: 200, - contentType: 'application/json', - body: JSON.stringify({ id: 'test-id' }), +sentryTest( + 'replay recording should contain default performance spans', + async ({ getLocalTestPath, page, browserName }) => { + // Replay bundles are es6 only and most performance entries are only available in chromium + if ((process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) || browserName !== 'chromium') { + sentryTest.skip(); + } + + const reqPromise0 = waitForReplayRequest(page, 0); + const reqPromise1 = waitForReplayRequest(page, 1); + + await page.route('https://dsn.ingest.sentry.io/**/*', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ id: 'test-id' }), + }); }); - }); - const url = await getLocalTestPath({ testDir: __dirname }); + const url = await getLocalTestPath({ testDir: __dirname }); - await page.goto(url); - const replayEvent0 = getReplayEvent(await reqPromise0); - const { performanceSpans: performanceSpans0 } = getCustomRecordingEvents(await reqPromise0); + await page.goto(url); + const replayEvent0 = getReplayEvent(await reqPromise0); + const { performanceSpans: performanceSpans0 } = getCustomRecordingEvents(await reqPromise0); - expect(replayEvent0).toEqual(getExpectedReplayEvent({ segment_id: 0 })); + expect(replayEvent0).toEqual(getExpectedReplayEvent({ segment_id: 0 })); - await page.click('button'); + await page.click('button'); - const replayEvent1 = getReplayEvent(await reqPromise1); - const { performanceSpans: performanceSpans1 } = getCustomRecordingEvents(await reqPromise1); + const replayEvent1 = getReplayEvent(await reqPromise1); + const { performanceSpans: performanceSpans1 } = getCustomRecordingEvents(await reqPromise1); - expect(replayEvent1).toEqual(getExpectedReplayEvent({ segment_id: 1, urls: [], replay_start_timestamp: undefined })); + expect(replayEvent1).toEqual( + getExpectedReplayEvent({ segment_id: 1, urls: [], replay_start_timestamp: undefined }), + ); - // We can't guarantee the order of the performance spans, or in which of the two segments they are sent - // So we collect them all and check that they are all there - const collectedPerformanceSpans = [...performanceSpans0, ...performanceSpans1]; + // We can't guarantee the order of the performance spans, or in which of the two segments they are sent + // So to avoid flakes, we collect them all and check that they are all there + const collectedPerformanceSpans = [...performanceSpans0, ...performanceSpans1]; - expect(collectedPerformanceSpans).toEqual( - expect.arrayContaining([ - expectedNavigationPerformanceSpan, - expectedLCPPerformanceSpan, - expectedFPPerformanceSpan, - expectedFCPPerformanceSpan, - expectedMemoryPerformanceSpan, // two memory spans - once per flush - expectedMemoryPerformanceSpan, - ]), - ); -}); + expect(collectedPerformanceSpans).toEqual( + expect.arrayContaining([ + expectedNavigationPerformanceSpan, + expectedLCPPerformanceSpan, + expectedFPPerformanceSpan, + expectedFCPPerformanceSpan, + expectedMemoryPerformanceSpan, // two memory spans - once per flush + expectedMemoryPerformanceSpan, + ]), + ); + }, +); From c1cc55b4b973abbcb0fbf16a1d418dafe67b9b19 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 7 Feb 2023 13:44:51 +0100 Subject: [PATCH 6/8] add breadcrumb test --- .../suites/replay/customEvents/test.ts | 42 +++++++++++++++++++ .../utils/replayEventTemplates.ts | 12 ++++++ 2 files changed, 54 insertions(+) diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts index 2c5435c29cfb..bb03bbc68d8c 100644 --- a/packages/integration-tests/suites/replay/customEvents/test.ts +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -2,6 +2,7 @@ import { expect } from '@playwright/test'; import { sentryTest } from '../../../utils/fixtures'; import { + expectedClickBreadcrumb, expectedFCPPerformanceSpan, expectedFPPerformanceSpan, expectedLCPPerformanceSpan, @@ -63,3 +64,44 @@ sentryTest( ); }, ); + +sentryTest( + 'replay recording should contain a click breadcrumb when a button is clicked', + async ({ getLocalTestPath, page, browserName }) => { + // Replay bundles are es6 only and most performance entries are only available in chromium + if ((process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) || browserName !== 'chromium') { + sentryTest.skip(); + } + + const reqPromise0 = waitForReplayRequest(page, 0); + const reqPromise1 = waitForReplayRequest(page, 1); + + await page.route('https://dsn.ingest.sentry.io/**/*', route => { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ id: 'test-id' }), + }); + }); + + const url = await getLocalTestPath({ testDir: __dirname }); + + await page.goto(url); + const replayEvent0 = getReplayEvent(await reqPromise0); + const { breadcrumbs: breadcrumbs0 } = getCustomRecordingEvents(await reqPromise0); + + expect(replayEvent0).toEqual(getExpectedReplayEvent({ segment_id: 0 })); + expect(breadcrumbs0.length).toEqual(0); + + await page.click('button'); + + const replayEvent1 = getReplayEvent(await reqPromise1); + const { breadcrumbs: breadcrumbs1 } = getCustomRecordingEvents(await reqPromise1); + + expect(replayEvent1).toEqual( + getExpectedReplayEvent({ segment_id: 1, urls: [], replay_start_timestamp: undefined }), + ); + + expect(breadcrumbs1).toEqual([expectedClickBreadcrumb]); + }, +); diff --git a/packages/integration-tests/utils/replayEventTemplates.ts b/packages/integration-tests/utils/replayEventTemplates.ts index c3cc7f4fe819..6a86ef8f45c7 100644 --- a/packages/integration-tests/utils/replayEventTemplates.ts +++ b/packages/integration-tests/utils/replayEventTemplates.ts @@ -110,3 +110,15 @@ export const expectedFPPerformanceSpan = { startTimestamp: expect.any(Number), endTimestamp: expect.any(Number), }; + +/* Breadcrumbs */ + +export const expectedClickBreadcrumb = { + timestamp: expect.any(Number), + type: 'default', + category: 'ui.click', + message: expect.any(String), + data: { + nodeId: expect.any(Number), + }, +}; From 4c7ffb3aff0e2f44eb9a8b8f7ee002e13a1b4f71 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 7 Feb 2023 13:52:49 +0100 Subject: [PATCH 7/8] run breadcrumbs test on all browsers --- .../integration-tests/suites/replay/customEvents/test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts index bb03bbc68d8c..ac900cfe0961 100644 --- a/packages/integration-tests/suites/replay/customEvents/test.ts +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -67,9 +67,9 @@ sentryTest( sentryTest( 'replay recording should contain a click breadcrumb when a button is clicked', - async ({ getLocalTestPath, page, browserName }) => { - // Replay bundles are es6 only and most performance entries are only available in chromium - if ((process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) || browserName !== 'chromium') { + async ({ getLocalTestPath, page }) => { + // Replay bundles are es6 only + if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { sentryTest.skip(); } From 17c28a004f576973ecda958139e9327052d18df8 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 7 Feb 2023 17:37:40 +0100 Subject: [PATCH 8/8] remove commented line --- .../integration-tests/suites/replay/customEvents/template.html | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/integration-tests/suites/replay/customEvents/template.html b/packages/integration-tests/suites/replay/customEvents/template.html index f8a9d72acf2d..31cfc73ec3c3 100644 --- a/packages/integration-tests/suites/replay/customEvents/template.html +++ b/packages/integration-tests/suites/replay/customEvents/template.html @@ -4,7 +4,6 @@ -