diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a5f73684e0ff..9716113ce134 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -533,6 +533,8 @@ jobs: - bundle_es5_min - bundle_es6 - bundle_es6_min + - bundle_replay_es6 + - bundle_replay_es6_min tracing_only: - true - false diff --git a/packages/integration-tests/suites/replay/captureReplay/test.ts b/packages/integration-tests/suites/replay/captureReplay/test.ts index e1319c3d0d6b..0801f13101c4 100644 --- a/packages/integration-tests/suites/replay/captureReplay/test.ts +++ b/packages/integration-tests/suites/replay/captureReplay/test.ts @@ -4,11 +4,10 @@ import type { ReplayEvent } from '@sentry/types'; import { sentryTest } from '../../../utils/fixtures'; import { envelopeRequestParser } from '../../../utils/helpers'; -import { waitForReplayRequest } from '../../../utils/replayHelpers'; +import { shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers'; sentryTest('should capture replays', async ({ getLocalTestPath, page }) => { - // Replay bundles are es6 only - if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { + if (shouldSkipReplayTest()) { sentryTest.skip(); } diff --git a/packages/integration-tests/suites/replay/compression/init.js b/packages/integration-tests/suites/replay/compression/init.js index f20e4054e34f..639cf05628e4 100644 --- a/packages/integration-tests/suites/replay/compression/init.js +++ b/packages/integration-tests/suites/replay/compression/init.js @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/browser'; -import { Replay } from '@sentry/replay'; window.Sentry = Sentry; -window.Replay = new Replay({ +window.Replay = new Sentry.Replay({ flushMinDelay: 500, flushMaxDelay: 500, useCompression: true, diff --git a/packages/integration-tests/suites/replay/compression/test.ts b/packages/integration-tests/suites/replay/compression/test.ts index e92d7f2dde40..d9a88a91a995 100644 --- a/packages/integration-tests/suites/replay/compression/test.ts +++ b/packages/integration-tests/suites/replay/compression/test.ts @@ -2,11 +2,15 @@ import { expect } from '@playwright/test'; import { sentryTest } from '../../../utils/fixtures'; import { getExpectedReplayEvent } from '../../../utils/replayEventTemplates'; -import { getFullRecordingSnapshots, getReplayEvent, waitForReplayRequest } from '../../../utils/replayHelpers'; +import { + getFullRecordingSnapshots, + getReplayEvent, + shouldSkipReplayTest, + waitForReplayRequest, +} from '../../../utils/replayHelpers'; sentryTest('replay recording should be compressed by default', async ({ getLocalTestPath, page }) => { - // Replay bundles are es6 only - if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { + if (shouldSkipReplayTest()) { sentryTest.skip(); } diff --git a/packages/integration-tests/suites/replay/customEvents/init.js b/packages/integration-tests/suites/replay/customEvents/init.js index f02e43c7235c..db6a0aa21821 100644 --- a/packages/integration-tests/suites/replay/customEvents/init.js +++ b/packages/integration-tests/suites/replay/customEvents/init.js @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/browser'; -import { Replay } from '@sentry/replay'; window.Sentry = Sentry; -window.Replay = new Replay({ +window.Replay = new Sentry.Replay({ flushMinDelay: 500, flushMaxDelay: 500, useCompression: false, diff --git a/packages/integration-tests/suites/replay/customEvents/test.ts b/packages/integration-tests/suites/replay/customEvents/test.ts index ac900cfe0961..a317ea281e9b 100644 --- a/packages/integration-tests/suites/replay/customEvents/test.ts +++ b/packages/integration-tests/suites/replay/customEvents/test.ts @@ -10,13 +10,19 @@ import { expectedNavigationPerformanceSpan, getExpectedReplayEvent, } from '../../../utils/replayEventTemplates'; -import { getCustomRecordingEvents, getReplayEvent, waitForReplayRequest } from '../../../utils/replayHelpers'; +import { + getCustomRecordingEvents, + getReplayEvent, + shouldSkipReplayTest, + waitForReplayRequest, +} from '../../../utils/replayHelpers'; 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') { + // We only test this against the NPM package and replay bundles + // and only on chromium as most performance entries are only available in chromium + if (shouldSkipReplayTest() || browserName !== 'chromium') { sentryTest.skip(); } @@ -68,8 +74,7 @@ sentryTest( sentryTest( 'replay recording should contain a click breadcrumb when a button is clicked', async ({ getLocalTestPath, page }) => { - // Replay bundles are es6 only - if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { + if (shouldSkipReplayTest()) { sentryTest.skip(); } diff --git a/packages/integration-tests/suites/replay/errorResponse/test.ts b/packages/integration-tests/suites/replay/errorResponse/test.ts index 68b90697410c..d81d16196b8e 100644 --- a/packages/integration-tests/suites/replay/errorResponse/test.ts +++ b/packages/integration-tests/suites/replay/errorResponse/test.ts @@ -1,14 +1,17 @@ import { expect } from '@playwright/test'; import { sentryTest } from '../../../utils/fixtures'; -import { getReplaySnapshot, REPLAY_DEFAULT_FLUSH_MAX_DELAY, waitForReplayRequest } from '../../../utils/replayHelpers'; +import { + getReplaySnapshot, + REPLAY_DEFAULT_FLUSH_MAX_DELAY, + shouldSkipReplayTest, + waitForReplayRequest, +} from '../../../utils/replayHelpers'; sentryTest('should stop recording after receiving an error response', async ({ getLocalTestPath, page }) => { - // Currently bundle tests are not supported for replay - if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { + if (shouldSkipReplayTest()) { sentryTest.skip(); } - let called = 0; await page.route('https://dsn.ingest.sentry.io/**/*', route => { diff --git a/packages/integration-tests/suites/replay/init.js b/packages/integration-tests/suites/replay/init.js index 16b46e3adc54..7a0337445768 100644 --- a/packages/integration-tests/suites/replay/init.js +++ b/packages/integration-tests/suites/replay/init.js @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/browser'; -import { Replay } from '@sentry/replay'; window.Sentry = Sentry; -window.Replay = new Replay({ +window.Replay = new Sentry.Replay({ flushMinDelay: 200, flushMaxDelay: 200, }); diff --git a/packages/integration-tests/suites/replay/sampling/init.js b/packages/integration-tests/suites/replay/sampling/init.js index 92a9fb51b959..9e99c3536d05 100644 --- a/packages/integration-tests/suites/replay/sampling/init.js +++ b/packages/integration-tests/suites/replay/sampling/init.js @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/browser'; -import { Replay } from '@sentry/replay'; window.Sentry = Sentry; -window.Replay = new Replay({ +window.Replay = new Sentry.Replay({ flushMinDelay: 200, flushMaxDelay: 200, }); diff --git a/packages/integration-tests/suites/replay/sampling/test.ts b/packages/integration-tests/suites/replay/sampling/test.ts index f1afa573551a..3475669a2a00 100644 --- a/packages/integration-tests/suites/replay/sampling/test.ts +++ b/packages/integration-tests/suites/replay/sampling/test.ts @@ -1,11 +1,10 @@ import { expect } from '@playwright/test'; import { sentryTest } from '../../../utils/fixtures'; -import { getReplaySnapshot } from '../../../utils/replayHelpers'; +import { getReplaySnapshot, shouldSkipReplayTest } from '../../../utils/replayHelpers'; sentryTest('should not send replays if both sample rates are 0', async ({ getLocalTestPath, page }) => { - // Replay bundles are es6 only - if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) { + if (shouldSkipReplayTest()) { sentryTest.skip(); } diff --git a/packages/integration-tests/utils/generatePlugin.ts b/packages/integration-tests/utils/generatePlugin.ts index 4c8d4bd9471e..d7f57007d5c8 100644 --- a/packages/integration-tests/utils/generatePlugin.ts +++ b/packages/integration-tests/utils/generatePlugin.ts @@ -7,6 +7,7 @@ import type { Compiler } from 'webpack'; const PACKAGES_DIR = '../../packages'; const tracingOnly = process.env.PW_TRACING_ONLY === 'true'; + const bundleKey = process.env.PW_BUNDLE; // `esm` and `cjs` builds are modules that can be imported / aliased by webpack @@ -23,6 +24,8 @@ const BUNDLE_PATHS: Record> = { bundle_es5_min: 'build/bundles/bundle.es5.min.js', bundle_es6: 'build/bundles/bundle.js', bundle_es6_min: 'build/bundles/bundle.min.js', + bundle_replay_es6: 'build/bundles/bundle.replay.js', + bundle_replay_es6_min: 'build/bundles/bundle.replay.min.js', }, tracing: { cjs: 'build/npm/cjs/index.js', @@ -31,6 +34,8 @@ const BUNDLE_PATHS: Record> = { bundle_es5_min: 'build/bundles/bundle.tracing.es5.min.js', bundle_es6: 'build/bundles/bundle.tracing.js', bundle_es6_min: 'build/bundles/bundle.tracing.min.js', + bundle_replay_es6: 'build/bundles/bundle.tracing.replay.js', + bundle_replay_es6_min: 'build/bundles/bundle.tracing.replay.min.js', }, integrations: { cjs: 'build/npm/cjs/index.js', @@ -39,12 +44,8 @@ const BUNDLE_PATHS: Record> = { bundle_es5_min: 'build/bundles/[INTEGRATION_NAME].es5.min.js', bundle_es6: 'build/bundles/[INTEGRATION_NAME].js', bundle_es6_min: 'build/bundles/[INTEGRATION_NAME].min.js', - }, - replay: { - cjs: 'build/npm/cjs/index.js', - esm: 'build/npm/esm/index.js', - bundle_es6: 'build/bundles/replay.js', - bundle_es6_min: 'build/bundles/replay.min.js', + bundle_replay_es6: 'build/bundles/[INTEGRATION_NAME].js', + bundle_replay_es6_min: 'build/bundles/[INTEGRATION_NAME].min.js', }, }; @@ -93,7 +94,6 @@ function generateSentryAlias(): Record { class SentryScenarioGenerationPlugin { public requiresTracing: boolean = false; public requiredIntegrations: string[] = []; - public requiresReplay = false; private _name: string = 'SentryScenarioGenerationPlugin'; @@ -106,7 +106,7 @@ class SentryScenarioGenerationPlugin { '@sentry/browser': 'Sentry', '@sentry/tracing': 'Sentry', '@sentry/integrations': 'Sentry.Integrations', - '@sentry/replay': 'Sentry.Integrations', + '@sentry/replay': 'Sentry', } : {}; @@ -121,8 +121,6 @@ class SentryScenarioGenerationPlugin { this.requiresTracing = true; } else if (source === '@sentry/integrations') { this.requiredIntegrations.push(statement.specifiers[0].imported.name.toLowerCase()); - } else if (source === '@sentry/replay') { - this.requiresReplay = true; } }, ); @@ -150,14 +148,6 @@ class SentryScenarioGenerationPlugin { data.assetTags.scripts.unshift(integrationObject); }); - if (this.requiresReplay && BUNDLE_PATHS['replay'][bundleKey]) { - const replayObject = createHtmlTagObject('script', { - src: path.resolve(PACKAGES_DIR, 'replay', BUNDLE_PATHS['replay'][bundleKey]), - }); - - data.assetTags.scripts.unshift(replayObject); - } - data.assetTags.scripts.unshift(bundleObject); } diff --git a/packages/integration-tests/utils/replayHelpers.ts b/packages/integration-tests/utils/replayHelpers.ts index b133ee1a3fe7..11a4131e6753 100644 --- a/packages/integration-tests/utils/replayHelpers.ts +++ b/packages/integration-tests/utils/replayHelpers.ts @@ -177,3 +177,15 @@ const replayEnvelopeParser = (request: Request | null): unknown[] => { return lines; }; + +/** + * We can only test replay tests in certain bundles/packages: + * - NPM (ESM, CJS) + * - CDN bundles that contain the Replay integration + * + * @returns `true` if we should skip the replay test + */ +export function shouldSkipReplayTest(): boolean { + const bundle = process.env.PW_BUNDLE as string | undefined; + return bundle != null && !bundle.includes('replay') && !bundle.includes('esm') && !bundle.includes('cjs'); +}