Skip to content

Commit b33ee8d

Browse files
Ease adoption of testing c-s-s (#1797)
* Ease adoption of testing c-s-s * Document * Move to npm * Fix lint
1 parent 8e91deb commit b33ee8d

File tree

5 files changed

+3921
-361
lines changed

5 files changed

+3921
-361
lines changed

injected/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ npm test
5353

5454
### Individual Commands
5555
```shell
56-
npm run test-unit # Unit tests (Jasmine)
57-
npm run test-int # Integration tests (Playwright)
58-
npm run build # Build platform-specific artifacts
56+
npm run test-unit # Unit tests (Jasmine)
57+
npm run test-int # Integration tests (Playwright)
58+
npm run build # Build platform-specific artifacts
59+
npm run fake-extension # Runs an example extension used within the integration tests
5960
```
6061

6162
### Project Structure

injected/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"playwright": "playwright test --grep-invert '@screenshots'",
2323
"playwright-screenshots": "playwright test --grep '@screenshots'",
2424
"playwright-e2e": "playwright test -c playwright-e2e.config.js --project duckplayer-e2e",
25-
"playwright-e2e-headed": "npm run playwright-e2e -- --headed"
25+
"playwright-e2e-headed": "npm run playwright-e2e -- --headed",
26+
"fake-extension": "node ./scripts/run-fake-extension.js"
2627
},
2728
"type": "module",
2829
"dependencies": {
@@ -42,6 +43,7 @@
4243
"@types/node": "^24.0.3",
4344
"@typescript-eslint/eslint-plugin": "^8.34.1",
4445
"fast-check": "^4.1.1",
45-
"jasmine": "^5.7.1"
46+
"jasmine": "^5.7.1",
47+
"web-ext": "^8.8.0"
4648
}
4749
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env node
2+
import { spawn } from 'child_process';
3+
import waitOn from 'wait-on';
4+
import path from 'path';
5+
import { fileURLToPath } from 'url';
6+
7+
const fileName = fileURLToPath(import.meta.url);
8+
const dirName = path.dirname(fileName);
9+
10+
/**
11+
* Run a command as a child process and return a Promise that resolves when it exits.
12+
* @param {string} cmd
13+
* @param {string[]} args
14+
* @param {object} opts
15+
* @returns {Promise<void>}
16+
*/
17+
function run(cmd, args, opts = {}) {
18+
return new Promise((resolve, reject) => {
19+
const proc = spawn(cmd, args, { stdio: 'inherit', shell: true, ...opts });
20+
proc.on('close', (code) => {
21+
if (code !== 0) reject(new Error(`${cmd} exited with code ${code}`));
22+
else resolve();
23+
});
24+
proc.on('error', reject);
25+
});
26+
}
27+
28+
async function main() {
29+
// 1. Build
30+
await run('npm', ['run', 'build']);
31+
32+
// 2. Start server
33+
const serveProc = spawn('npm', ['run', 'serve'], {
34+
cwd: path.resolve(dirName, '..'),
35+
stdio: 'ignore',
36+
shell: true,
37+
detached: true,
38+
});
39+
40+
// Ensure server is killed on exit
41+
const cleanup = () => {
42+
if (serveProc.pid) {
43+
try {
44+
if (process.platform === 'win32') {
45+
spawn('taskkill', ['/pid', String(serveProc.pid), '/f', '/t']);
46+
} else {
47+
process.kill(-serveProc.pid, 'SIGTERM');
48+
}
49+
} catch (e) {}
50+
}
51+
};
52+
process.on('exit', cleanup);
53+
process.on('SIGINT', () => {
54+
cleanup();
55+
process.exit(1);
56+
});
57+
process.on('SIGTERM', () => {
58+
cleanup();
59+
process.exit(1);
60+
});
61+
62+
// 3. Wait for server
63+
await waitOn({ resources: ['http://localhost:3220/index.html'] });
64+
65+
// 4. Run web-ext
66+
try {
67+
await run(
68+
'npx',
69+
[
70+
'web-ext',
71+
'run',
72+
'--source-dir=integration-test/extension',
73+
'--target=chromium',
74+
'--start-url=http://localhost:3220/index.html',
75+
'--start-url=https://privacy-test-pages.site',
76+
],
77+
{ cwd: path.resolve(dirName, '..') },
78+
);
79+
} finally {
80+
cleanup();
81+
}
82+
}
83+
84+
main().catch((err) => {
85+
console.error(err);
86+
process.exit(1);
87+
});

0 commit comments

Comments
 (0)