// Node 22 or later: global fetch and WebSocket.
import { spawn } from "node:child_process";
const base = "http://127.0.0.1:9333";
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
const state = (ws) => new Promise((resolve) => {
const s = new WebSocket(ws);
s.onopen = () => s.send(JSON.stringify({ id: 1, method: "Runtime.evaluate", params: { expression: "document.visibilityState" } }));
s.onmessage = (e) => { s.close(); resolve(JSON.parse(e.data).result.result.value); };
});
// Without the flag, Windows hides a covered or off-screen window from the start.
const chrome = spawn("C:/Program Files/Google/Chrome/Application/chrome.exe", ["--remote-debugging-port=9333",
"--user-data-dir=.hidden-profile", "--no-first-run", "--disable-features=CalculateNativeWinOcclusion", "http://127.0.0.1:6813/"]);
try {
let pages;
for (let i = 0; i < 50 && !pages; i++) pages = await fetch(`${base}/json`).then((r) => r.json()).catch(() => wait(200));
const ours = pages.find((t) => t.type === "page");
const other = await (await fetch(`${base}/json/new?about:blank`, { method: "PUT" })).json();
await wait(500);
console.log(await state(ours.webSocketDebuggerUrl)); // hidden
await fetch(`${base}/json/activate/${ours.id}`);
await wait(500);
console.log(await state(ours.webSocketDebuggerUrl)); // visible
await fetch(`${base}/json/close/${other.id}`);
} finally {
chrome.kill();
}