91 lines
2.2 KiB
JavaScript
91 lines
2.2 KiB
JavaScript
const fs = require("node:fs");
|
|
const os = require("node:os");
|
|
const path = require("node:path");
|
|
const { spawn } = require("node:child_process");
|
|
|
|
const repoRoot = path.resolve(__dirname, "..");
|
|
const baseUrl = process.env.SELENIUM_BASE_URL || "http://127.0.0.1:5095";
|
|
const healthUrl = new URL("/api/health", baseUrl).toString();
|
|
const smokeScript = process.argv[2] || "tests/e2e/smoke.js";
|
|
const tempDbPath = path.join(os.tmpdir(), `rpgroller-selenium-${Date.now()}-${Math.random().toString(16).slice(2)}.db`);
|
|
|
|
function delay(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
async function waitForHealthCheck() {
|
|
for (let attempt = 0; attempt < 60; attempt += 1) {
|
|
try {
|
|
const response = await fetch(healthUrl);
|
|
if (response.ok) {
|
|
return;
|
|
}
|
|
} catch {
|
|
}
|
|
|
|
await delay(500);
|
|
}
|
|
|
|
throw new Error(`Application failed to start on ${baseUrl}.`);
|
|
}
|
|
|
|
function spawnProcess(command, args, options) {
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn(command, args, options);
|
|
child.once("error", reject);
|
|
resolve(child);
|
|
});
|
|
}
|
|
|
|
async function run() {
|
|
const app = await spawnProcess(
|
|
"dotnet",
|
|
["run", "--project", "RpgRoller/RpgRoller.csproj", "--verbosity", "minimal", "--urls", baseUrl],
|
|
{
|
|
cwd: repoRoot,
|
|
stdio: "inherit",
|
|
env: {
|
|
...process.env,
|
|
ConnectionStrings__RpgRoller: `Data Source=${tempDbPath}`
|
|
}
|
|
}
|
|
);
|
|
|
|
try {
|
|
await waitForHealthCheck();
|
|
|
|
const smoke = await spawnProcess("node", [smokeScript], {
|
|
cwd: repoRoot,
|
|
stdio: "inherit",
|
|
env: {
|
|
...process.env,
|
|
SELENIUM_BASE_URL: baseUrl
|
|
}
|
|
});
|
|
|
|
const exitCode = await new Promise((resolve, reject) => {
|
|
smoke.once("error", reject);
|
|
smoke.once("exit", resolve);
|
|
});
|
|
|
|
if (exitCode !== 0) {
|
|
throw new Error(`Selenium smoke exited with code ${exitCode}.`);
|
|
}
|
|
} finally {
|
|
app.kill("SIGTERM");
|
|
await delay(500);
|
|
if (!app.killed) {
|
|
app.kill("SIGKILL");
|
|
}
|
|
|
|
if (fs.existsSync(tempDbPath)) {
|
|
fs.rmSync(tempDbPath, { force: true });
|
|
}
|
|
}
|
|
}
|
|
|
|
run().catch((error) => {
|
|
console.error(error.stack || error);
|
|
process.exitCode = 1;
|
|
});
|