Skip to content

Commit 5cd8bb1

Browse files
committed
adding test
1 parent d2ed65b commit 5cd8bb1

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

tests/run.mjs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#! /usr/bin/env node
2+
/* eslint-disable-next-line no-unused-vars */
3+
import serve from "./server.mjs";
4+
import { Builder, Capabilities } from "selenium-webdriver";
5+
import commandLineArgs from "command-line-args";
6+
import commandLineUsage from "command-line-usage";
7+
import assert from "assert";
8+
9+
const optionDefinitions = [
10+
{ name: "browser", type: String, description: "Set the browser to test, choices are [safari, firefox, chrome]. By default the $BROWSER env variable is used." },
11+
{ name: "port", type: Number, defaultValue: 8010, description: "Set the test-server port, The default value is 8010." },
12+
{ name: "help", alias: "h", description: "Print this help text." },
13+
];
14+
15+
function printHelp(message = "") {
16+
const usage = commandLineUsage([
17+
{
18+
header: "Run all tests",
19+
},
20+
{
21+
header: "Options",
22+
optionList: optionDefinitions,
23+
},
24+
]);
25+
if (!message) {
26+
console.log(usage);
27+
process.exit(0);
28+
} else {
29+
console.error(message);
30+
console.error();
31+
console.error(usage);
32+
process.exit(1);
33+
}
34+
}
35+
36+
const options = commandLineArgs(optionDefinitions);
37+
38+
if ("help" in options)
39+
printHelp();
40+
41+
const BROWSER = options?.browser;
42+
if (!BROWSER)
43+
printHelp("No browser specified, use $BROWSER or --browser");
44+
45+
let capabilities;
46+
switch (BROWSER) {
47+
case "safari":
48+
capabilities = Capabilities.safari();
49+
break;
50+
51+
case "firefox": {
52+
capabilities = Capabilities.firefox();
53+
break;
54+
}
55+
case "chrome": {
56+
capabilities = Capabilities.chrome();
57+
break;
58+
}
59+
case "edge": {
60+
capabilities = Capabilities.edge();
61+
break;
62+
}
63+
default: {
64+
printHelp(`Invalid browser "${BROWSER}", choices are: "safari", "firefox", "chrome", "edge"`);
65+
}
66+
}
67+
68+
process.on("unhandledRejection", (err) => {
69+
console.error(err);
70+
process.exit(1);
71+
});
72+
process.once("uncaughtException", (err) => {
73+
console.error(err);
74+
process.exit(1);
75+
});
76+
77+
const PORT = options.port;
78+
const server = serve(PORT);
79+
80+
async function testEnd2End() {
81+
const driver = await new Builder().withCapabilities(capabilities).build();
82+
let results;
83+
try {
84+
await driver.get(`http://localhost:${PORT}/index.html?worstCaseCount=2&iterationCount=3`);
85+
await driver.executeAsyncScript((callback) => {
86+
globalThis.addEventListener("JetStreamReady", callback);
87+
// We might not get a chance to install the on-ready listener, thus
88+
// we also check if the runner is ready synchronously.
89+
if (globalThis?.JetStream?.isReady)
90+
callback()
91+
});
92+
await driver.manage().setTimeouts({ script: 60_000 });
93+
results = await driver.executeAsyncScript((callback) => {
94+
globalThis.addEventListener("JetStreamDone", event => callback(event.detail));
95+
JetStream.start();
96+
});
97+
} finally {
98+
console.log("\nTests complete!");
99+
console.log(results)
100+
driver.quit();
101+
server.close();
102+
}
103+
}
104+
105+
setImmediate(testEnd2End);

tests/server.mjs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Simple server adapted from https://developer.mozilla.org/en-US/docs/Learn/Server-side/Node_server_without_framework:
2+
import * as fs from "fs";
3+
import * as http from "http";
4+
import * as path from "path";
5+
const MIME_TYPES = {
6+
default: "application/octet-stream",
7+
html: "text/html; charset=UTF-8",
8+
js: "application/javascript; charset=UTF-8",
9+
mjs: "application/javascript; charset=UTF-8",
10+
css: "text/css",
11+
png: "image/png",
12+
jpg: "image/jpg",
13+
gif: "image/gif",
14+
ico: "image/x-icon",
15+
svg: "image/svg+xml",
16+
};
17+
18+
const STATIC_PATH = path.join(process.cwd(), "./");
19+
const toBool = [() => true, () => false];
20+
21+
export default function serve(port) {
22+
if (!port)
23+
throw new Error("Port is required");
24+
25+
const prepareFile = async (url) => {
26+
const paths = [STATIC_PATH, url];
27+
if (url.endsWith("/"))
28+
paths.push("index.html");
29+
const filePath = path.join(...paths);
30+
const pathTraversal = !filePath.startsWith(STATIC_PATH);
31+
const exists = await fs.promises.access(filePath).then(...toBool);
32+
const found = !pathTraversal && exists;
33+
const streamPath = found ? filePath : `${STATIC_PATH}/index.html`;
34+
const ext = path.extname(streamPath).substring(1).toLowerCase();
35+
const stream = fs.createReadStream(streamPath);
36+
return { found, ext, stream };
37+
};
38+
39+
const server = http
40+
.createServer(async (req, res) => {
41+
const file = await prepareFile(req.url);
42+
const statusCode = file.found ? 200 : 404;
43+
const mimeType = MIME_TYPES[file.ext] || MIME_TYPES.default;
44+
res.writeHead(statusCode, { "Content-Type": mimeType });
45+
file.stream.pipe(res);
46+
})
47+
.listen(port);
48+
49+
console.log(`Server running at http://127.0.0.1:${port}/`);
50+
return server;
51+
}

0 commit comments

Comments
 (0)