GStack browser readiness
This local page verifies navigation, reading, interaction, console, and network access.
WAITING
#!/usr/bin/env node import { randomBytes } from "node:crypto"; import http from "node:http"; import { pathToFileURL } from "node:url"; const HOST = "127.0.0.1"; export function createReadinessServer(options = {}) { const token = options.token ?? randomBytes(24).toString("hex"); if (!/^[a-f0-9]{32,128}$/.test(token)) throw new TypeError("Readiness token must be 32-128 lowercase hex characters"); let completed = false; let baseUrl = null; const server = http.createServer((request, response) => { const url = new URL(request.url ?? "/", baseUrl ?? `http://${HOST}`); const supplied = url.searchParams.get("token"); const headers = { "Cache-Control": "no-store", "Content-Security-Policy": "default-src 'none'; script-src 'unsafe-inline'; connect-src 'self'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'", "Referrer-Policy": "no-referrer", "X-Content-Type-Options": "nosniff", }; if (url.pathname === "/" && request.method === "GET") { response.writeHead(200, { ...headers, "Content-Type": "text/html; charset=utf-8" }); response.end(renderPage(token)); return; } if (url.pathname === "/proof") { if (request.method !== "POST") { response.writeHead(405, { ...headers, Allow: "POST" }); response.end(); return; } if (supplied !== token) { response.writeHead(403, headers); response.end(); return; } completed = true; response.writeHead(200, { ...headers, "Content-Type": "application/json" }); response.end(JSON.stringify({ ok: true, status: "READY" })); return; } if (url.pathname === "/status" && request.method === "GET") { if (supplied !== token) { response.writeHead(403, headers); response.end(); return; } response.writeHead(200, { ...headers, "Content-Type": "application/json" }); response.end(JSON.stringify({ ok: true, completed })); return; } response.writeHead(404, headers); response.end(); }); return { server, token, get completed() { return completed; }, async start() { if (baseUrl) return { url: `${baseUrl}/?token=${token}`, baseUrl, token }; await new Promise((resolve, reject) => { server.once("error", reject); server.listen(options.port ?? 0, HOST, resolve); }); const address = server.address(); if (!address || typeof address === "string") throw new Error("Readiness fixture did not acquire a TCP port"); baseUrl = `http://${HOST}:${address.port}`; return { url: `${baseUrl}/?token=${token}`, baseUrl, token }; }, async stop() { if (!server.listening) return; await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); }, }; } function renderPage(token) { return `
This local page verifies navigation, reading, interaction, console, and network access.
WAITING