Skip to content

Commit 0c3f0fb

Browse files
authored
Add end2end tests (#470)
- Move unittests to run-unittests.mjs - Move common test driver and server setup to separate helper.mjs module - Add "SpeedometerReady" and "SpeedometerDone" events for easier testing - Add simple end2end tests that invoke the benchmark via the html page
1 parent 9f85f8e commit 0c3f0fb

11 files changed

+357
-182
lines changed

.github/workflows/test.yml

+4
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ jobs:
5757
run: |
5858
echo "Running in $BROWSER"
5959
npm run test:${{ matrix.browser }}
60+
- name: Run end2end
61+
run: |
62+
echo "Running in $BROWSER"
63+
npm run test-e2e:${{ matrix.browser }}

package-lock.json

+52-34
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+9-5
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@
2222
"pretty:check": "prettier --check ./",
2323
"pretty:fix": "prettier --write ./",
2424
"format": "npm run pretty:fix && npm run lint:fix",
25-
"test:chrome": "node tests/run.mjs --browser chrome",
26-
"test:firefox": "node tests/run.mjs --browser firefox",
27-
"test:safari": "node tests/run.mjs --browser safari",
28-
"test:edge": "node tests/run.mjs --browser edge"
25+
"test:chrome": "node tests/run-unittests.mjs --browser chrome",
26+
"test:firefox": "node tests/run-unittests.mjs --browser firefox",
27+
"test:safari": "node tests/run-unittests.mjs --browser safari",
28+
"test:edge": "node tests/run-unittests.mjs --browser edge",
29+
"test-e2e:chrome": "node tests/run-end2end.mjs --browser chrome",
30+
"test-e2e:firefox": "node tests/run-end2end.mjs --browser firefox",
31+
"test-e2e:safari": "node tests/run-end2end.mjs --browser safari",
32+
"test-e2e:edge": "node tests/run-end2end.mjs --browser edge"
2933
},
3034
"devDependencies": {
3135
"@babel/core": "^7.21.3",
@@ -45,7 +49,7 @@
4549
"http-server": "^14.1.1",
4650
"mocha": "^10.2.0",
4751
"prettier": "^2.8.3",
48-
"selenium-webdriver": "^4.8.0",
52+
"selenium-webdriver": "^4.27.0",
4953
"sinon": "^17.0.1",
5054
"typescript": "^5.0.4"
5155
}

resources/main.mjs

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class MainBenchmarkClient {
2323
constructor() {
2424
window.addEventListener("DOMContentLoaded", () => this.prepareUI());
2525
this._showSection(window.location.hash);
26+
window.dispatchEvent(new Event("SpeedometerReady"));
2627
}
2728

2829
start() {
@@ -150,6 +151,7 @@ class MainBenchmarkClient {
150151
this.showResultsDetails();
151152
else
152153
this.showResultsSummary();
154+
globalThis.dispatchEvent(new Event("SpeedometerDone"));
153155
}
154156

155157
handleError(error) {
@@ -159,6 +161,7 @@ class MainBenchmarkClient {
159161
this._metrics = Object.create(null);
160162
this._populateInvalidScore();
161163
this.showResultsSummary();
164+
throw error;
162165
}
163166

164167
_populateValidScore(scoreResults) {

tests/helper.mjs

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import commandLineUsage from "command-line-usage";
2+
import commandLineArgs from "command-line-args";
3+
import serve from "./server.mjs";
4+
5+
import { Builder, Capabilities, logging } from "selenium-webdriver";
6+
7+
const optionDefinitions = [
8+
{ name: "browser", type: String, description: "Set the browser to test, choices are [safari, firefox, chrome]. By default the $BROWSER env variable is used." },
9+
{ name: "port", type: Number, defaultValue: 8010, description: "Set the test-server port, The default value is 8010." },
10+
{ name: "help", alias: "h", description: "Print this help text." },
11+
];
12+
13+
function printHelp(message = "", exitStatus = 0) {
14+
const usage = commandLineUsage([
15+
{
16+
header: "Run all tests",
17+
},
18+
{
19+
header: "Options",
20+
optionList: optionDefinitions,
21+
},
22+
]);
23+
if (message) {
24+
console.error(message);
25+
console.error();
26+
}
27+
console.log(usage);
28+
process.exit(exitStatus);
29+
}
30+
31+
export default async function testSetup(helpText) {
32+
const options = commandLineArgs(optionDefinitions);
33+
34+
if ("help" in options)
35+
printHelp(helpText);
36+
37+
const BROWSER = options?.browser;
38+
if (!BROWSER)
39+
printHelp("No browser specified, use $BROWSER or --browser", 1);
40+
41+
let capabilities;
42+
switch (BROWSER) {
43+
case "safari":
44+
capabilities = Capabilities.safari();
45+
break;
46+
47+
case "firefox": {
48+
capabilities = Capabilities.firefox();
49+
break;
50+
}
51+
case "chrome": {
52+
capabilities = Capabilities.chrome();
53+
break;
54+
}
55+
case "edge": {
56+
capabilities = Capabilities.edge();
57+
break;
58+
}
59+
default: {
60+
printHelp(`Invalid browser "${BROWSER}", choices are: "safari", "firefox", "chrome", "edge"`);
61+
}
62+
}
63+
const prefs = new logging.Preferences();
64+
prefs.setLevel(logging.Type.BROWSER, logging.Level.ALL); // Capture all log levels
65+
capabilities.setLoggingPrefs(prefs);
66+
67+
const PORT = options.port;
68+
const server = serve(PORT);
69+
let driver;
70+
71+
process.on("unhandledRejection", (err) => {
72+
console.error(err);
73+
process.exit(1);
74+
});
75+
process.once("uncaughtException", (err) => {
76+
console.error(err);
77+
process.exit(1);
78+
});
79+
process.on("exit", () => stop());
80+
81+
driver = await new Builder().withCapabilities(capabilities).build();
82+
driver.manage().window().setRect({ width: 1200, height: 1000 });
83+
84+
function stop() {
85+
server.close();
86+
if (driver)
87+
driver.close();
88+
}
89+
return { driver, PORT, stop };
90+
}

tests/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
});
2929

30-
await import("./benchmark-runner-tests.mjs");
30+
await import("./unittests/benchmark-runner.mjs");
3131

3232
globalThis.testResults = undefined;
3333
globalThis.testRunner = mocha.run();

0 commit comments

Comments
 (0)