fertig-classic-games/tools/__jig_random_driver.mjs

73 lines
2.7 KiB
JavaScript

// Headless-chromium CDP driver for the jigsaw random-start test page.
// Usage: node tools/__jig_random_driver.mjs <url>
import { spawn } from 'node:child_process';
import { setTimeout as sleep } from 'node:timers/promises';
const url = process.argv[2];
if (!url) { console.error('usage: driver <url>'); process.exit(2); }
const BIN = process.env.HOME + '/.cache/ms-playwright/chromium_headless_shell-1234/chrome-headless-shell-linux64/chrome-headless-shell';
const PORT = 9333;
const chrome = spawn(BIN, [
'--headless', '--no-sandbox', '--disable-gpu',
`--remote-debugging-port=${PORT}`,
'about:blank',
], { stdio: ['ignore', 'pipe', 'pipe'] });
chrome.stderr.on('data', (d) => { const s = d.toString(); if (!/Fontconfig|dbus|DBus|ozone/i.test(s)) process.stderr.write(s); });
async function httpJson(path) {
const r = await fetch(`http://127.0.0.1:${PORT}${path}`);
return r.json();
}
let ws, idc = 0;
const pending = new Map();
const send = (method, params = {}) => new Promise((resolve, reject) => {
const id = ++idc;
pending.set(id, { resolve, reject });
ws.send(JSON.stringify({ id, method, params }));
});
try {
// Wait for the debug endpoint.
let targets = null;
for (let i = 0; i < 60; i++) {
try { targets = await httpJson('/json/list'); break; } catch { await sleep(250); }
}
if (!targets) throw new Error('chrome devtools endpoint never came up');
const page = targets.find((t) => t.type === 'page');
if (!page) throw new Error('no page target');
ws = new WebSocket(page.webSocketDebuggerUrl);
await new Promise((res, rej) => { ws.onopen = res; ws.onerror = rej; });
ws.onmessage = (m) => {
const msg = JSON.parse(m.data);
if (msg.id && pending.has(msg.id)) {
const { resolve, reject } = pending.get(msg.id);
pending.delete(msg.id);
if (msg.error) reject(new Error(msg.error.message)); else resolve(msg.result);
}
};
await send('Runtime.enable');
await send('Page.enable');
await send('Page.navigate', { url });
const t0 = Date.now();
let title = '';
while (Date.now() - t0 < 240000) {
const { result: { value } } = await send('Runtime.evaluate', { expression: 'document.title', returnByValue: true });
title = value || '';
if (title === 'PASS' || title.startsWith('FAIL')) break;
await sleep(500);
}
const { result: { value: logText } } = await send('Runtime.evaluate', { expression: 'document.getElementById("log").textContent', returnByValue: true });
console.log('===== page log =====');
console.log(logText.trimEnd());
console.log('===== result: ' + (title || 'TIMEOUT') + ' =====');
process.exitCode = title === 'PASS' ? 0 : 1;
} finally {
try { ws && ws.close(); } catch {}
chrome.kill('SIGKILL');
}