Skip to content

Commit 601a1ee

Browse files
authored
Guard Playwright security override (#166)
1 parent 48f9c45 commit 601a1ee

File tree

6 files changed

+80
-10
lines changed

6 files changed

+80
-10
lines changed

frontend/tests/e2e/cache.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { test, expect } from '@playwright/test';
1+
import { test, expect } from './fixtures';
22

33
test('static asset cache headers from manifest', async ({ request }) => {
44
const manifestResponse = await request.get('/models/manifest.json');

frontend/tests/e2e/fixtures.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { expect, test as base } from '@playwright/test';
2+
3+
import { registerDracoRoutes } from './utils/draco';
4+
5+
const test = base.extend({
6+
context: async ({ context }, use) => {
7+
await registerDracoRoutes(context);
8+
await use(context);
9+
},
10+
page: async ({ page }, use) => {
11+
await registerDracoRoutes(page.context());
12+
await use(page);
13+
},
14+
});
15+
16+
export { expect, registerDracoRoutes, test };

frontend/tests/e2e/perf.p90.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { test, expect } from '@playwright/test';
1+
import { test, expect } from './fixtures';
22
import { readFileSync } from 'node:fs';
33
import { resolve } from 'node:path';
44

frontend/tests/e2e/perf/perf-budget.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect, test } from '@playwright/test';
1+
import { expect, registerDracoRoutes, test } from '../fixtures';
22
import type { Browser } from '@playwright/test';
33
import fs from 'node:fs';
44
import path from 'node:path';
@@ -112,6 +112,7 @@ const collectNavigationMetrics = async (
112112
waits: WaitConfig[] | undefined,
113113
): Promise<{ navigation: number; lcp: number }> => {
114114
const context = await browser.newContext();
115+
await registerDracoRoutes(context);
115116

116117
await context.addInitScript(() => {
117118
(window as typeof window & {

frontend/tests/e2e/utils/draco.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import fs from 'node:fs';
2+
import path from 'node:path';
3+
import type { BrowserContext, Route } from '@playwright/test';
4+
5+
const frontendRoot = path.resolve(__dirname, '../../..');
6+
7+
let dracoPackageDir: string;
8+
9+
try {
10+
dracoPackageDir = path.dirname(require.resolve('draco3d/package.json', { paths: [frontendRoot] }));
11+
} catch (error) {
12+
throw new Error(
13+
'Unable to locate the draco3d package. Make sure frontend dependencies are installed before running Playwright tests.',
14+
);
15+
}
16+
17+
const decoderBaseUrl = 'https://www.gstatic.com/draco/v1/decoders/';
18+
19+
const wasmWrapperSource = fs.readFileSync(
20+
path.join(dracoPackageDir, 'draco_wasm_wrapper.js'),
21+
'utf8',
22+
);
23+
const wasmBinary = fs.readFileSync(path.join(dracoPackageDir, 'draco_decoder.wasm'));
24+
const decoderSource = fs.readFileSync(path.join(dracoPackageDir, 'draco_decoder.js'), 'utf8');
25+
26+
const patchedContexts = new WeakSet<BrowserContext>();
27+
28+
const fulfill = (route: Route, body: string | Buffer, contentType: string) =>
29+
route.fulfill({ status: 200, body, contentType, headers: { 'cache-control': 'public, max-age=86400' } });
30+
31+
export async function registerDracoRoutes(context: BrowserContext): Promise<void> {
32+
if (patchedContexts.has(context)) {
33+
return;
34+
}
35+
36+
patchedContexts.add(context);
37+
38+
await Promise.all([
39+
context.route(`${decoderBaseUrl}draco_wasm_wrapper.js`, (route) =>
40+
fulfill(route, wasmWrapperSource, 'application/javascript'),
41+
),
42+
context.route(`${decoderBaseUrl}draco_decoder.js`, (route) =>
43+
fulfill(route, decoderSource, 'application/javascript'),
44+
),
45+
context.route(`${decoderBaseUrl}draco_decoder.wasm`, (route) =>
46+
fulfill(route, wasmBinary, 'application/wasm'),
47+
),
48+
]);
49+
}

playwright.config.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import { defineConfig } from '@playwright/test';
33

44
const testDir = path.resolve(__dirname, 'frontend/tests/e2e');
55
const junitOutputFile = path.resolve(__dirname, 'artifacts/junit.xml');
6+
const launchArgs = [
7+
'--ignore-gpu-blocklist',
8+
'--use-gl=swiftshader',
9+
'--enable-webgl',
10+
'--disable-gpu-sandbox',
11+
];
12+
13+
if (process.env.PLAYWRIGHT_ALLOW_INSECURE === '1') {
14+
launchArgs.push('--disable-web-security');
15+
}
616

717
export default defineConfig({
818
testDir,
@@ -21,13 +31,7 @@ export default defineConfig({
2131
headless: true,
2232
trace: 'retain-on-failure',
2333
launchOptions: {
24-
args: [
25-
'--ignore-gpu-blocklist',
26-
'--use-gl=swiftshader',
27-
'--enable-webgl',
28-
'--disable-gpu-sandbox',
29-
'--disable-web-security',
30-
],
34+
args: launchArgs,
3135
},
3236
},
3337
});

0 commit comments

Comments
 (0)