Record the dashboard, and make the page capturable
node scripts/record-dashboard.mjs drives the gateway with real requests and screenshots the real dashboard between them with headless Chrome. Screen recording was the obvious route and the wrong one: it would photograph whatever else happened to be on screen and needs a permission grant. Headless captures only the page, needs no permission, and writes frames straight to disk. The dashboard never finished loading under a headless browser, because it holds an SSE connection open and polls on an interval — so ?nolive=1 now renders once and goes quiet. That also makes the page screenshot-testable in general. Chrome does not reliably exit after --screenshot, so the recorder waits for the PNG to appear and stop growing rather than guessing a sleep, and treats profile cleanup as best-effort since Chrome keeps flushing after SIGKILL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
eeb5cad4ce
commit
6c41b6d804
5 files changed
+160
-3
No files matched your search
@@ -317,6 +317,7 @@ td.n{font-family:var(--mono); white-space:nowrap}
|
||||
const POLL_MS = 3000;
|
||||
const KEY_STORAGE = 'freeway.key';
|
||||
|
||||
const STATIC = new URLSearchParams(location.search).has('nolive');
|
||||
let apiKey = localStorage.getItem(KEY_STORAGE) || '';
|
||||
let paused = false;
|
||||
let timer = null;
|
||||
@@ -786,6 +787,10 @@ function setPulse(kind) {
|
||||
|
||||
function schedule() {
|
||||
clearInterval(timer);
|
||||
// ?nolive=1 renders once and then goes quiet: no polling interval, no event
|
||||
// stream. A page that never stops working never finishes loading, which is
|
||||
// what screenshot tools and headless browsers wait for.
|
||||
if (STATIC) return;
|
||||
// Polling a hidden tab burns CPU for nobody; the visibilitychange handler
|
||||
// brings it straight back with a fresh fetch.
|
||||
timer = setInterval(() => { if (!paused && !document.hidden) refresh(); }, POLL_MS);
|
||||
@@ -802,6 +807,9 @@ let liveBackoff = 1000;
|
||||
let liveConnected = false;
|
||||
|
||||
async function connectLive() {
|
||||
// ?nolive=1 keeps the page from holding an open SSE connection. Headless
|
||||
// browsers and screenshot tools otherwise wait for a stream that never ends.
|
||||
if (STATIC) { setLiveState(false); return; }
|
||||
if (liveAbort) liveAbort.abort();
|
||||
liveAbort = new AbortController();
|
||||
|
||||
|
||||
Reference in new issue
Block a user