From d691af700814ae8737db3963777a800a0ef594d7 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 1 Mar 2023 15:27:10 +0100 Subject: [PATCH] test: Fix flaky errorsInSession test --- .../suites/replay/captureReplay/test.ts | 8 ++--- .../replay/captureReplayViaBrowser/test.ts | 8 ++--- .../replay/errors/errorsInSession/test.ts | 3 +- .../integration-tests/utils/replayHelpers.ts | 32 +++++++++++++------ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/packages/integration-tests/suites/replay/captureReplay/test.ts b/packages/integration-tests/suites/replay/captureReplay/test.ts index 0801f13101c4..d06be65f1cb6 100644 --- a/packages/integration-tests/suites/replay/captureReplay/test.ts +++ b/packages/integration-tests/suites/replay/captureReplay/test.ts @@ -1,10 +1,8 @@ import { expect } from '@playwright/test'; import { SDK_VERSION } from '@sentry/browser'; -import type { ReplayEvent } from '@sentry/types'; import { sentryTest } from '../../../utils/fixtures'; -import { envelopeRequestParser } from '../../../utils/helpers'; -import { shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers'; +import { getReplayEvent, shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers'; sentryTest('should capture replays', async ({ getLocalTestPath, page }) => { if (shouldSkipReplayTest()) { @@ -25,10 +23,10 @@ sentryTest('should capture replays', async ({ getLocalTestPath, page }) => { const url = await getLocalTestPath({ testDir: __dirname }); await page.goto(url); - const replayEvent0 = envelopeRequestParser(await reqPromise0) as ReplayEvent; + const replayEvent0 = getReplayEvent(await reqPromise0); await page.click('button'); - const replayEvent1 = envelopeRequestParser(await reqPromise1) as ReplayEvent; + const replayEvent1 = getReplayEvent(await reqPromise1); expect(replayEvent0).toBeDefined(); expect(replayEvent0).toEqual({ diff --git a/packages/integration-tests/suites/replay/captureReplayViaBrowser/test.ts b/packages/integration-tests/suites/replay/captureReplayViaBrowser/test.ts index f670ac28dfef..0f50a194e01c 100644 --- a/packages/integration-tests/suites/replay/captureReplayViaBrowser/test.ts +++ b/packages/integration-tests/suites/replay/captureReplayViaBrowser/test.ts @@ -1,10 +1,8 @@ import { expect } from '@playwright/test'; import { SDK_VERSION } from '@sentry/browser'; -import type { ReplayEvent } from '@sentry/types'; import { sentryTest } from '../../../utils/fixtures'; -import { envelopeRequestParser } from '../../../utils/helpers'; -import { waitForReplayRequest } from '../../../utils/replayHelpers'; +import { getReplayEvent, waitForReplayRequest } from '../../../utils/replayHelpers'; sentryTest('should capture replays (@sentry/browser export)', async ({ getLocalTestPath, page }) => { // For this test, we skip all bundle tests, as we're only interested in Replay being correctly @@ -27,10 +25,10 @@ sentryTest('should capture replays (@sentry/browser export)', async ({ getLocalT const url = await getLocalTestPath({ testDir: __dirname }); await page.goto(url); - const replayEvent0 = envelopeRequestParser(await reqPromise0) as ReplayEvent; + const replayEvent0 = getReplayEvent(await reqPromise0); await page.click('button'); - const replayEvent1 = envelopeRequestParser(await reqPromise1) as ReplayEvent; + const replayEvent1 = getReplayEvent(await reqPromise1); expect(replayEvent0).toBeDefined(); expect(replayEvent0).toEqual({ diff --git a/packages/integration-tests/suites/replay/errors/errorsInSession/test.ts b/packages/integration-tests/suites/replay/errors/errorsInSession/test.ts index 217a19b5198a..d948875cf2d8 100644 --- a/packages/integration-tests/suites/replay/errors/errorsInSession/test.ts +++ b/packages/integration-tests/suites/replay/errors/errorsInSession/test.ts @@ -76,6 +76,7 @@ sentryTest( sentryTest.skip(); } + const reqPromise0 = waitForReplayRequest(page, 0); const reqPromise1 = waitForReplayRequest(page, 1); await page.route('https://dsn.ingest.sentry.io/**/*', route => { @@ -89,7 +90,7 @@ sentryTest( const url = await getLocalTestPath({ testDir: __dirname }); await page.goto(url); - await page.click('#go-background'); + await reqPromise0; await page.click('#drop'); await page.click('#go-background'); diff --git a/packages/integration-tests/utils/replayHelpers.ts b/packages/integration-tests/utils/replayHelpers.ts index 1eac33fd1987..d1fe2b6b07cb 100644 --- a/packages/integration-tests/utils/replayHelpers.ts +++ b/packages/integration-tests/utils/replayHelpers.ts @@ -1,7 +1,7 @@ import type { RecordingEvent, ReplayContainer } from '@sentry/replay/build/npm/types/types'; import type { Breadcrumb, Event, ReplayEvent } from '@sentry/types'; import pako from 'pako'; -import type { Page, Request } from 'playwright'; +import type { Page, Request, Response } from 'playwright'; import { envelopeRequestParser } from './helpers'; @@ -37,8 +37,10 @@ type SnapshotNode = { * @param segmentId the segment_id of the replay event * @returns */ -export function waitForReplayRequest(page: Page, segmentId?: number): Promise { - return page.waitForRequest(req => { +export function waitForReplayRequest(page: Page, segmentId?: number): Promise { + return page.waitForResponse(res => { + const req = res.request(); + const postData = req.postData(); if (!postData) { return false; @@ -78,7 +80,8 @@ export async function getReplaySnapshot(page: Page): Promise { export const REPLAY_DEFAULT_FLUSH_MAX_DELAY = 5_000; -export function getReplayEvent(replayRequest: Request): ReplayEvent { +export function getReplayEvent(resOrReq: Request | Response): ReplayEvent { + const replayRequest = getRequest(resOrReq); const event = envelopeRequestParser(replayRequest); if (!isReplayEvent(event)) { throw new Error('Request is not a replay event'); @@ -103,7 +106,8 @@ type RecordingContent = { * @param replayRequest * @returns an object containing the replay breadcrumbs and performance spans */ -export function getCustomRecordingEvents(replayRequest: Request): CustomRecordingContent { +export function getCustomRecordingEvents(resOrReq: Request | Response): CustomRecordingContent { + const replayRequest = getRequest(resOrReq); const recordingEvents = getDecompressedRecordingEvents(replayRequest); const breadcrumbs = getReplayBreadcrumbs(recordingEvents); @@ -128,21 +132,25 @@ function getReplayPerformanceSpans(recordingEvents: RecordingEvent[]): Performan .map(data => data.payload) as PerformanceSpan[]; } -export function getFullRecordingSnapshots(replayRequest: Request): RecordingSnapshot[] { +export function getFullRecordingSnapshots(resOrReq: Request | Response): RecordingSnapshot[] { + const replayRequest = getRequest(resOrReq); const events = getDecompressedRecordingEvents(replayRequest) as RecordingEvent[]; return events.filter(event => event.type === 2).map(event => event.data as RecordingSnapshot); } -function getIncrementalRecordingSnapshots(replayRequest: Request): RecordingSnapshot[] { +function getIncrementalRecordingSnapshots(resOrReq: Request | Response): RecordingSnapshot[] { + const replayRequest = getRequest(resOrReq); const events = getDecompressedRecordingEvents(replayRequest) as RecordingEvent[]; return events.filter(event => event.type === 3).map(event => event.data as RecordingSnapshot); } -function getDecompressedRecordingEvents(replayRequest: Request): RecordingEvent[] { +function getDecompressedRecordingEvents(resOrReq: Request | Response): RecordingEvent[] { + const replayRequest = getRequest(resOrReq); return replayEnvelopeRequestParser(replayRequest, 5) as RecordingEvent[]; } -export function getReplayRecordingContent(replayRequest: Request): RecordingContent { +export function getReplayRecordingContent(resOrReq: Request | Response): RecordingContent { + const replayRequest = getRequest(resOrReq); const fullSnapshots = getFullRecordingSnapshots(replayRequest); const incrementalSnapshots = getIncrementalRecordingSnapshots(replayRequest); const customEvents = getCustomRecordingEvents(replayRequest); @@ -255,3 +263,9 @@ function normalizeNumberAttribute(num: number): string { return `[${stepCount * step}-${(stepCount + 1) * step}]`; } + +/** Get a request from either a request or a response */ +function getRequest(resOrReq: Request | Response): Request { + // @ts-ignore we check this + return typeof resOrReq.request === 'function' ? (resOrReq as Response).request() : (resOrReq as Request); +}