#!/usr/bin/env node import { chromium } from "playwright"; function parseArgs(argv) { const args = {}; for (let i = 2; i < argv.length; i += 1) { const part = argv[i]; if (!part.startsWith("--")) continue; const key = part.slice(2); const next = argv[i + 1]; if (!next || next.startsWith("--")) { args[key] = true; continue; } args[key] = next; i += 1; } return args; } const args = parseArgs(process.argv); const serverId = args["server-id"] ?? process.env.PASEO_SERVER_ID; const daemonPublicKeyB64 = args["daemon-public-key-b64"] ?? process.env.PASEO_DAEMON_PUBLIC_KEY_B64; const relayEndpoint = args["relay-endpoint"] ?? process.env.PASEO_RELAY_ENDPOINT ?? "relay.paseo.sh:443"; const baseUrl = args["base-url"] ?? process.env.PASEO_APP_URL ?? "https://app.paseo.sh"; const timeoutMs = Number(args["timeout-ms"] ?? process.env.PASEO_PROVE_TIMEOUT_MS ?? 60_000); const stabilityMs = Number(args["stability-ms"] ?? process.env.PASEO_PROVE_STABILITY_MS ?? 30_000); if (!serverId || typeof serverId !== "string") { console.error("Missing server ID. Provide --server-id or PASEO_SERVER_ID."); process.exit(2); } if (!daemonPublicKeyB64 || typeof daemonPublicKeyB64 !== "string") { console.error( "Missing daemon public key. Provide --daemon-public-key-b64 or PASEO_DAEMON_PUBLIC_KEY_B64.", ); process.exit(2); } const nowIso = new Date().toISOString(); const daemon = { serverId, label: "relay-daemon", connections: [{ id: `relay:${relayEndpoint}`, type: "relay", relayEndpoint, daemonPublicKeyB64 }], preferredConnectionId: `relay:${relayEndpoint}`, createdAt: nowIso, updatedAt: nowIso, }; const browser = await chromium.launch({ headless: true }); const context = await browser.newContext(); const page = await context.newPage(); page.on("console", (m) => console.log(`[browser:${m.type()}] ${m.text()}`)); page.on("pageerror", (e) => console.error(`[browser:pageerror] ${e.message}`)); await page.addInitScript( (seed) => { localStorage.setItem("@paseo:daemon-registry", JSON.stringify([seed.daemon])); localStorage.removeItem("@paseo:settings"); }, { daemon }, ); await page.goto(`${baseUrl}/settings`, { waitUntil: "domcontentloaded", timeout: timeoutMs }); const card = page.getByTestId(`daemon-card-${serverId}`); await card.waitFor({ timeout: timeoutMs }); await card.getByText("Online", { exact: true }).waitFor({ timeout: timeoutMs }); await card.getByText("Relay", { exact: true }).waitFor({ timeout: timeoutMs }); // Stability window: ensure it doesn't flap. await page.waitForTimeout(stabilityMs); await card.getByText("Online", { exact: true }).waitFor({ timeout: 5_000 }); console.log( JSON.stringify( { ok: true, serverId, relayEndpoint, baseUrl, stabilityMs, }, null, 2, ), ); await browser.close();