orbit/dev/cdp-eval.mjs

39 lines
2.2 KiB
JavaScript

// Evaluate an expression in a headless Chrome (CDP) page and print the result.
// Usage: node cdp-eval.mjs <url> <expr> [waitMs]
import { spawn } from 'node:child_process';
import fs from 'node:fs';
const [url, expr, waitMs = '6000'] = process.argv.slice(2);
const PORT = 9333 + Math.floor(Math.random() * 200);
const CHROME = 'C:/Program Files/Google/Chrome/Application/chrome.exe';
const udd = 'C:/Users/BRIAN~1.FER/AppData/Local/Temp/cdp-eval-' + process.pid + '-' + Date.now();
const chrome = spawn(CHROME, [
'--headless', `--remote-debugging-port=${PORT}`, `--user-data-dir=${udd}`,
'--no-first-run', '--disable-gpu', '--enable-unsafe-swiftshader', 'about:blank',
], { stdio: 'ignore' });
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
try {
let v;
for (let i = 0; i < 100; i++) {
try { v = await (await fetch(`http://127.0.0.1:${PORT}/json/version`)).json(); break; } catch { await sleep(200); }
}
if (!v) throw new Error('CDP never came up');
let t;
try { t = await (await fetch(`http://127.0.0.1:${PORT}/json/new?${encodeURIComponent(url)}`, { method: 'PUT' })).json(); }
catch { t = await (await fetch(`http://127.0.0.1:${PORT}/json/new?${encodeURIComponent(url)}`, { method: 'POST' })).json(); }
const ws = new WebSocket(t.webSocketDebuggerUrl);
let id = 0; const p = new Map();
const send = (m, pa = {}) => new Promise((res, rej) => { const i = ++id; p.set(i, { res, rej }); ws.send(JSON.stringify({ id: i, method: m, params: pa })); });
ws.onmessage = (m) => { const x = JSON.parse(m.data); if (x.id && p.has(x.id)) { const { res, rej } = p.get(x.id); p.delete(x.id); x.error ? rej(new Error(x.error.message)) : res(x.result); } };
await new Promise((r) => (ws.onopen = r));
await send('Runtime.enable');
await sleep(Number(waitMs));
const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true });
if (r.exceptionDetails) throw new Error(JSON.stringify(r.exceptionDetails).slice(0, 400));
console.log(typeof r.result.value === 'object' ? JSON.stringify(r.result.value) : r.result.value);
ws.close();
} finally {
chrome.kill();
setTimeout(() => fs.rmSync(udd, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }), 1500);
}