orbit/dev/bounty-hunt-shot-run.mjs

59 lines
2.3 KiB
JavaScript

/**
* Dev-only runner for the BOUNTY HUNT in-browser probe (dev/bounty-hunt-shot.mjs).
*
* node dev/server.mjs 8080 # the no-store dev server
* CHROME_PATH=/path/to/chrome node dev/bounty-hunt-shot-run.mjs [baseUrl]
*
* Loads each stage in a real headless Chromium, waits for the page's own
* report (window.__BH), writes dev/shots/bh-<stage>.json + .png for every
* stage, and prints one line per stage. Exit 0 only when no stage FAILED and
* no page error was captured.
*/
import fs from 'node:fs';
import path from 'node:path';
import { launch, CDP } from './cdpshot.mjs';
const BASE = process.argv[2] || 'http://127.0.0.1:8080/dev/bounty-hunt-shot.html';
const STAGES = ['locked', 'dossier', 'hunt', 'mark'];
const OUT = path.resolve('dev/shots');
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
fs.mkdirSync(OUT, { recursive: true });
let bad = 0;
for (const stage of STAGES) {
const url = `${BASE}#${stage}`;
const { url: wsUrl, kill } = await launch(url);
const cdp = new CDP(wsUrl);
try {
await cdp.open();
await cdp.send('Runtime.enable');
await cdp.send('Page.enable');
let rep = null;
const t0 = Date.now();
while (Date.now() - t0 < 180000) {
try {
const r = await cdp.send('Runtime.evaluate', { expression: 'window.__BH && window.__BH.stage && window.__BH.stage !== "running" ? JSON.stringify(window.__BH) : null', returnByValue: true });
if (r.result?.value) { rep = JSON.parse(r.result.value); break; }
} catch { /* still booting */ }
await sleep(500);
}
if (!rep) {
bad++;
console.log(`${stage.padEnd(8)} ✘ TIMEOUT — the page never reported`);
continue;
}
const shot = await cdp.send('Page.captureScreenshot', { format: 'png' });
fs.writeFileSync(path.join(OUT, `bh-${stage}.png`), Buffer.from(shot.data, 'base64'));
fs.writeFileSync(path.join(OUT, `bh-${stage}.json`), JSON.stringify(rep, null, 1));
if (rep.stage === 'FAILED' || (rep.errors && rep.errors.length)) bad++;
console.log(`${stage.padEnd(8)} ${rep.stage === 'FAILED' ? '✘ FAILED' : '✔'} ${JSON.stringify(rep).slice(0, 240)}`);
} finally {
cdp.close();
kill();
await sleep(400);
}
}
console.log(bad ? `\n${bad} stage(s) need attention` : '\nall BOUNTY HUNT browser stages reported clean');
process.exitCode = bad ? 1 : 0;