blob: b7e4886cd03e322003552359325f8f28d58ff2c0 [file] [edit]
#! /usr/bin/env node
import assert from "assert";
import testSetup from "./helper.mjs";
import { Suites } from "../resources/tests.mjs";
const HELP = `
This script runs end2end tests by invoking the benchmark via the main
Speedometer page in /index.html.
`.trim();
const { driver, PORT, stop } = await testSetup(HELP);
async function testPage(url) {
console.log(`Testing: ${url}`);
await driver.get(`http://localhost:${PORT}/${url}`);
await driver.executeAsyncScript((callback) => {
if (globalThis.benchmarkClient)
callback();
else
globalThis.addEventListener("SpeedometerReady", () => callback(), { once: true });
});
console.log(" - Awaiting Benchmark");
const { error, metrics } = await driver.executeAsyncScript((callback) => {
globalThis.addEventListener(
"SpeedometerDone",
() =>
callback({
metrics: globalThis.benchmarkClient.metrics,
}),
{ once: true }
);
// Install error handlers to report page errors back to selenium.
globalThis.addEventListener("error", (message, source, lineno, colno, error) =>
callback({
error: { message, source, lineno, colno, error },
})
);
globalThis.addEventListener("unhandledrejection", (e) => {
callback({
error: {
message: e.reason.toString(),
stack: e.reason?.stack,
},
});
});
globalThis.benchmarkClient.start();
});
if (error)
throw new Error(error.message + (error?.stack ?? ""));
validateMetrics(metrics);
return metrics;
}
function validateMetrics(metrics) {
for (const [name, metric] of Object.entries(metrics))
validateMetric(name, metric);
assert(metrics.Geomean.mean > 0);
assert(metrics.Score.mean > 0);
}
function validateMetric(name, metric) {
assert(metric.name === name);
assert(metric.mean >= 0);
}
async function testIterations() {
const iterationCount = 2;
const metrics = await testPage(`index.html?iterationCount=${iterationCount}`);
Suites.forEach((suite) => {
if (!suite.disabled) {
const metric = metrics[suite.name];
assert(metric.values.length === iterationCount);
} else {
assert(!(suite.name in metrics));
}
});
assert(metrics.Geomean.values.length === iterationCount);
assert(metrics.Score.values.length === iterationCount);
}
async function testAll() {
const metrics = await testPage("index.html?iterationCount=1&tags=all");
Suites.forEach((suite) => {
assert(suite.name in metrics);
const metric = metrics[suite.name];
assert(metric.values.length === 1);
});
assert(metrics.Geomean.values.length === 1);
assert(metrics.Score.values.length === 1);
}
async function testDeveloperMode() {
const params = ["developerMode", "iterationCount=1", "warmupBeforeSync=2", "waitBeforeSync=2", "shuffleSeed=123", "suites=Perf-Dashboard"];
const metrics = await testPage(`index.html?${params.join("&")}`);
Suites.forEach((suite) => {
if (suite.name === "Perf-Dashboard") {
const metric = metrics[suite.name];
assert(metric.values.length === 1);
} else {
assert(!(suite.name in metrics));
}
});
}
async function test() {
try {
await driver.manage().setTimeouts({ script: 60000 });
await testIterations();
await testAll();
await testDeveloperMode();
console.log("\nTests complete!");
} catch (e) {
console.error("\nTests failed!");
throw e;
} finally {
stop();
}
}
setImmediate(test);