Skip to content

Commit 6227e44

Browse files
authored
test(replay): Test against CDN bundles in Playwright integration tests (#6770)
Test against addon CDN bundles in PW integration tests. Ensures minified bundles are still working correctly
1 parent b598e54 commit 6227e44

File tree

11 files changed

+126
-9
lines changed

11 files changed

+126
-9
lines changed

.github/workflows/build.yml

-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ jobs:
191191
- name: Check build cache
192192
uses: actions/cache@v3
193193
id: cache_built_packages
194-
if: needs.job_get_metadata.outputs.force_skip_cache == 'false'
195194
with:
196195
path: ${{ env.CACHED_BUILD_PATHS }}
197196
key: ${{ env.BUILD_CACHE_KEY }}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { sentryTest } from '../../../utils/fixtures';
66
import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers';
77

88
sentryTest('captureReplay', async ({ getLocalTestPath, page }) => {
9-
// Currently bundle tests are not supported for replay
10-
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_')) {
9+
// Replay bundles are es6 only
10+
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) {
1111
sentryTest.skip();
1212
}
1313

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
window.Replay = new Sentry.Replay({
5+
flushMinDelay: 200,
6+
initialFlushDelay: 200,
7+
});
8+
9+
Sentry.init({
10+
dsn: 'https://[email protected]/1337',
11+
sampleRate: 0,
12+
replaysSessionSampleRate: 1.0,
13+
replaysOnErrorSampleRate: 0.0,
14+
15+
integrations: [window.Replay],
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button onclick="console.log('Test log')">Click me</button>
8+
</body>
9+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { expect } from '@playwright/test';
2+
import { SDK_VERSION } from '@sentry/browser';
3+
import type { Event } from '@sentry/types';
4+
5+
import { sentryTest } from '../../../utils/fixtures';
6+
import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers';
7+
8+
sentryTest('captureReplay', async ({ getLocalTestPath, page }) => {
9+
// For this test, we skip all bundle tests, as we're only interested in Replay being correctly
10+
// exported from the `@sentry/browser` npm package.
11+
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_')) {
12+
sentryTest.skip();
13+
}
14+
15+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
16+
return route.fulfill({
17+
status: 200,
18+
contentType: 'application/json',
19+
body: JSON.stringify({ id: 'test-id' }),
20+
});
21+
});
22+
23+
const url = await getLocalTestPath({ testDir: __dirname });
24+
await page.goto(url);
25+
26+
await page.click('button');
27+
await page.waitForTimeout(300);
28+
29+
const replayEvent = await getFirstSentryEnvelopeRequest<Event>(page, url);
30+
31+
expect(replayEvent).toBeDefined();
32+
expect(replayEvent).toEqual({
33+
type: 'replay_event',
34+
timestamp: expect.any(Number),
35+
error_ids: [],
36+
trace_ids: [],
37+
urls: [expect.stringContaining('/dist/index.html')],
38+
replay_id: expect.stringMatching(/\w{32}/),
39+
segment_id: 2,
40+
replay_type: 'session',
41+
event_id: expect.stringMatching(/\w{32}/),
42+
environment: 'production',
43+
sdk: {
44+
integrations: [
45+
'InboundFilters',
46+
'FunctionToString',
47+
'TryCatch',
48+
'Breadcrumbs',
49+
'GlobalHandlers',
50+
'LinkedErrors',
51+
'Dedupe',
52+
'HttpContext',
53+
'Replay',
54+
],
55+
version: SDK_VERSION,
56+
name: 'sentry.javascript.browser',
57+
},
58+
sdkProcessingMetadata: {},
59+
request: {
60+
url: expect.stringContaining('/dist/index.html'),
61+
headers: {
62+
'User-Agent': expect.stringContaining(''),
63+
},
64+
},
65+
platform: 'javascript',
66+
tags: { sessionSampleRate: 1, errorSampleRate: 0 },
67+
});
68+
});

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { getReplaySnapshot } from '../../../utils/helpers';
55

66
sentryTest('errorResponse', async ({ getLocalTestPath, page }) => {
77
// Currently bundle tests are not supported for replay
8-
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_')) {
8+
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) {
99
sentryTest.skip();
1010
}
1111

@@ -31,7 +31,9 @@ sentryTest('errorResponse', async ({ getLocalTestPath, page }) => {
3131
await page.waitForTimeout(5001);
3232

3333
expect(called).toBe(1);
34+
3435
const replay = await getReplaySnapshot(page);
3536

36-
expect(replay['_isEnabled']).toBe(false);
37+
// @ts-ignore private API
38+
expect(replay._isEnabled).toBe(false);
3739
});

packages/integration-tests/suites/replay/init.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as Sentry from '@sentry/browser';
2+
import { Replay } from '@sentry/replay';
23

34
window.Sentry = Sentry;
4-
window.Replay = new Sentry.Replay({
5+
window.Replay = new Replay({
56
flushMinDelay: 200,
67
initialFlushDelay: 200,
78
});

packages/integration-tests/suites/replay/sampling/init.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as Sentry from '@sentry/browser';
2+
import { Replay } from '@sentry/replay';
23

34
window.Sentry = Sentry;
4-
window.Replay = new Sentry.Replay({
5+
window.Replay = new Replay({
56
flushMinDelay: 200,
67
initialFlushDelay: 200,
78
});

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { sentryTest } from '../../../utils/fixtures';
44
import { getReplaySnapshot } from '../../../utils/helpers';
55

66
sentryTest('sampling', async ({ getLocalTestPath, page }) => {
7-
// Currently bundle tests are not supported for replay
8-
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_')) {
7+
// Replay bundles are es6 only
8+
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_es5')) {
99
sentryTest.skip();
1010
}
1111

packages/integration-tests/utils/generatePlugin.ts

+18
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ const BUNDLE_PATHS: Record<string, Record<string, string>> = {
4040
bundle_es6: 'build/bundles/[INTEGRATION_NAME].js',
4141
bundle_es6_min: 'build/bundles/[INTEGRATION_NAME].min.js',
4242
},
43+
replay: {
44+
cjs: 'build/npm/cjs/index.js',
45+
esm: 'build/npm/esm/index.js',
46+
bundle_es6: 'build/bundles/replay.js',
47+
bundle_es6_min: 'build/bundles/replay.min.js',
48+
},
4349
};
4450

4551
/*
@@ -87,6 +93,7 @@ function generateSentryAlias(): Record<string, string> {
8793
class SentryScenarioGenerationPlugin {
8894
public requiresTracing: boolean = false;
8995
public requiredIntegrations: string[] = [];
96+
public requiresReplay = false;
9097

9198
private _name: string = 'SentryScenarioGenerationPlugin';
9299

@@ -99,6 +106,7 @@ class SentryScenarioGenerationPlugin {
99106
'@sentry/browser': 'Sentry',
100107
'@sentry/tracing': 'Sentry',
101108
'@sentry/integrations': 'Sentry.Integrations',
109+
'@sentry/replay': 'Sentry.Integrations',
102110
}
103111
: {};
104112

@@ -113,6 +121,8 @@ class SentryScenarioGenerationPlugin {
113121
this.requiresTracing = true;
114122
} else if (source === '@sentry/integrations') {
115123
this.requiredIntegrations.push(statement.specifiers[0].imported.name.toLowerCase());
124+
} else if (source === '@sentry/replay') {
125+
this.requiresReplay = true;
116126
}
117127
},
118128
);
@@ -140,6 +150,14 @@ class SentryScenarioGenerationPlugin {
140150
data.assetTags.scripts.unshift(integrationObject);
141151
});
142152

153+
if (this.requiresReplay && BUNDLE_PATHS['replay'][bundleKey]) {
154+
const replayObject = createHtmlTagObject('script', {
155+
src: path.resolve(PACKAGES_DIR, 'replay', BUNDLE_PATHS['replay'][bundleKey]),
156+
});
157+
158+
data.assetTags.scripts.unshift(replayObject);
159+
}
160+
143161
data.assetTags.scripts.unshift(bundleObject);
144162
}
145163

rollup/plugins/bundlePlugins.js

+3
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ export function makeTerserPlugin() {
107107
'_driver',
108108
'_initStorage',
109109
'_support',
110+
// We want to keept he _replay and _isEnabled variable unmangled to enable integration tests to access it
111+
'_replay',
112+
'_isEnabled',
110113
],
111114
},
112115
},

0 commit comments

Comments
 (0)