Skip to content

Commit 15740ba

Browse files
committed
ref(wasm): Move integration tests to Playwright integration tests
1 parent 09c6cbe commit 15740ba

File tree

6 files changed

+130
-0
lines changed

6 files changed

+130
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as Sentry from '@sentry/browser';
2+
import { Wasm } from '@sentry/wasm';
3+
4+
window.Sentry = Sentry;
5+
6+
Sentry.init({
7+
dsn: 'https://[email protected]/1337',
8+
integrations: [new Wasm()],
9+
beforeSend: event => {
10+
window.events.push(event);
11+
return null;
12+
},
13+
});
Binary file not shown.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
window.events = [];
2+
3+
window.getEvent = async () => {
4+
function crash() {
5+
throw new Error('whoops');
6+
}
7+
8+
const { instance } = await WebAssembly.instantiateStreaming(fetch('https://localhost:5887/simple.wasm'), {
9+
env: {
10+
external_func: crash,
11+
},
12+
});
13+
14+
try {
15+
instance.exports.internal_func();
16+
} catch (err) {
17+
Sentry.captureException(err);
18+
return window.events.pop();
19+
}
20+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { expect } from '@playwright/test';
2+
import fs from 'fs';
3+
import path from 'path';
4+
5+
import { sentryTest } from '../../utils/fixtures';
6+
import { shouldSkipWASMTests } from '../../utils/wasmHelpers';
7+
8+
sentryTest(
9+
'captured exception should include modified frames and debug_meta attribute',
10+
async ({ getLocalTestPath, page }) => {
11+
if (shouldSkipWASMTests()) {
12+
sentryTest.skip();
13+
}
14+
15+
const url = await getLocalTestPath({ testDir: __dirname });
16+
17+
await page.route('**/simple.wasm', route => {
18+
const wasmModule = fs.readFileSync(path.resolve(__dirname, 'simple.wasm'));
19+
20+
return route.fulfill({
21+
status: 200,
22+
body: wasmModule,
23+
headers: {
24+
'Content-Type': 'application/wasm',
25+
},
26+
});
27+
});
28+
29+
await page.goto(url);
30+
31+
const event = await page.evaluate(async () => {
32+
// @ts-ignore this function exists
33+
return window.getEvent();
34+
});
35+
36+
expect(event.exception.values[0].stacktrace.frames).toEqual(
37+
expect.arrayContaining([
38+
expect.objectContaining({
39+
filename: expect.stringMatching(/simple\.wasm$/),
40+
function: 'internal_func',
41+
in_app: true,
42+
instruction_addr: '0x8c',
43+
addr_mode: 'rel:0',
44+
platform: 'native',
45+
}),
46+
expect.objectContaining({
47+
filename: expect.stringMatching(/subject\.bundle\.js$/),
48+
function: 'crash',
49+
in_app: true,
50+
}),
51+
]),
52+
);
53+
54+
expect(event.debug_meta).toMatchObject({
55+
images: [
56+
{
57+
code_file: expect.stringMatching(/simple\.wasm$/),
58+
code_id: '0ba020cdd2444f7eafdd25999a8e9010',
59+
debug_file: null,
60+
debug_id: '0ba020cdd2444f7eafdd25999a8e90100',
61+
type: 'wasm',
62+
},
63+
],
64+
});
65+
},
66+
);

packages/integration-tests/utils/generatePlugin.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ const BUNDLE_PATHS: Record<string, Record<string, string>> = {
4747
bundle_replay_es6: 'build/bundles/[INTEGRATION_NAME].js',
4848
bundle_replay_es6_min: 'build/bundles/[INTEGRATION_NAME].min.js',
4949
},
50+
wasm: {
51+
cjs: 'build/npm/cjs/index.js',
52+
esm: 'build/npm/esm/index.js',
53+
bundle_es6: 'build/bundles/wasm.js',
54+
bundle_es6_min: 'build/bundles/wasm.min.js',
55+
bundle_replay_es6: 'build/bundles/wasm.js',
56+
bundle_replay_es6_min: 'build/bundles/wasm.min.js',
57+
},
5058
};
5159

5260
/*
@@ -94,6 +102,7 @@ function generateSentryAlias(): Record<string, string> {
94102
class SentryScenarioGenerationPlugin {
95103
public requiresTracing: boolean = false;
96104
public requiredIntegrations: string[] = [];
105+
public requiresWASMIntegration: boolean = false;
97106

98107
private _name: string = 'SentryScenarioGenerationPlugin';
99108

@@ -107,6 +116,7 @@ class SentryScenarioGenerationPlugin {
107116
'@sentry/tracing': 'Sentry',
108117
'@sentry/integrations': 'Sentry.Integrations',
109118
'@sentry/replay': 'Sentry',
119+
'@sentry/wasm': 'Sentry.Integrations',
110120
}
111121
: {};
112122

@@ -121,6 +131,8 @@ class SentryScenarioGenerationPlugin {
121131
this.requiresTracing = true;
122132
} else if (source === '@sentry/integrations') {
123133
this.requiredIntegrations.push(statement.specifiers[0].imported.name.toLowerCase());
134+
} else if (source === '@sentry/wasm') {
135+
this.requiresWASMIntegration = true;
124136
}
125137
},
126138
);
@@ -148,6 +160,14 @@ class SentryScenarioGenerationPlugin {
148160
data.assetTags.scripts.unshift(integrationObject);
149161
});
150162

163+
if (this.requiresWASMIntegration && BUNDLE_PATHS['wasm'][bundleKey]) {
164+
const wasmObject = createHtmlTagObject('script', {
165+
src: path.resolve(PACKAGES_DIR, 'wasm', BUNDLE_PATHS['wasm'][bundleKey]),
166+
});
167+
168+
data.assetTags.scripts.unshift(wasmObject);
169+
}
170+
151171
data.assetTags.scripts.unshift(bundleObject);
152172
}
153173

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* We can only test WASM tests in certain bundles/packages:
3+
* - NPM (ESM, CJS)
4+
* - ES6 CDN bundles
5+
*
6+
* @returns `true` if we should skip the replay test
7+
*/
8+
export function shouldSkipWASMTests(): boolean {
9+
const bundle = process.env.PW_BUNDLE as string | undefined;
10+
return bundle != null && bundle.includes('es5');
11+
}

0 commit comments

Comments
 (0)