From c4a2d5e0d74a499b54a2eee7215a23f3f3f2fea3 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Sun, 9 Aug 2026 11:27:59 +0800 Subject: [PATCH] fix(web): browser smoke reads the mount marker from the console stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The editor now holds a live SSE stream, and an in-flight network request pauses headless Chrome's virtual clock — so --dump-dom never flushes, the DOM grep never matches, and the smoke either timed out (CI, 45s) or hung on a TERM-immune Chrome behind a bare wait (observed 12 hours locally). The mount marker is now mirrored to the console, which reaches the stderr log incrementally, and the poll loop treats that line as readiness, synthesizing the DOM marker the assertions expect; the timeout path uses SIGKILL. Verified end to end locally: both the pure CanvasKit page and the daemon host page mount. --- .../op-host-services/src/web_static/index.html | 5 +++++ crates/op-host-web/smoke/step-1b.html | 4 ++++ tools/check-web-browser-smoke.sh | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/crates/op-host-services/src/web_static/index.html b/crates/op-host-services/src/web_static/index.html index 216e2e106..a9a00de55 100644 --- a/crates/op-host-services/src/web_static/index.html +++ b/crates/op-host-services/src/web_static/index.html @@ -48,6 +48,11 @@ const errorPane = document.getElementById('op-error'); const markSmoke = (state) => { document.documentElement.setAttribute('data-op-smoke', state); + // Mirrored to the console for the headless browser smoke: the + // editor keeps a live SSE stream open, which freezes headless + // Chrome's virtual clock, so --dump-dom never flushes — stderr + // console logging is the only channel that arrives incrementally. + console.log(`op-smoke:${state}`); }; const showError = (msg) => { markSmoke('error'); diff --git a/crates/op-host-web/smoke/step-1b.html b/crates/op-host-web/smoke/step-1b.html index f3fc8ae7b..ef45a56e5 100644 --- a/crates/op-host-web/smoke/step-1b.html +++ b/crates/op-host-web/smoke/step-1b.html @@ -59,6 +59,10 @@ const status = document.getElementById('status'); const markSmoke = (state) => { document.documentElement.setAttribute('data-op-smoke', state); + // Console mirror for the headless smoke; see the host page note — + // stderr logging arrives incrementally while --dump-dom waits for + // a quiescence the live editor never reaches. + console.log(`op-smoke:${state}`); }; const log = (cls, msg) => { const block = document.createElement('pre'); diff --git a/tools/check-web-browser-smoke.sh b/tools/check-web-browser-smoke.sh index cec911bfe..34981a151 100755 --- a/tools/check-web-browser-smoke.sh +++ b/tools/check-web-browser-smoke.sh @@ -101,10 +101,22 @@ chrome_dump() { --enable-unsafe-swiftshader \ --window-size=1280,800 \ --user-data-dir="$profile" \ + --enable-logging=stderr \ --virtual-time-budget="${OPENPENCIL_BROWSER_SMOKE_VIRTUAL_TIME_MS:-15000}" \ --dump-dom "$url" >"$out" 2>"$out.stderr" & local chrome_pid=$! for _ in $(seq 1 "$timeout"); do + # The editor holds a live SSE stream, which pauses headless Chrome's + # virtual clock and keeps --dump-dom from ever flushing. The console + # mirror on stderr arrives incrementally, so it is the readiness + # signal; a successful mount synthesizes the DOM line the assertions + # expect. + if grep -Fq 'op-smoke:ok' "$out.stderr" 2>/dev/null; then + printf '\n' >"$out" + kill -9 "$chrome_pid" >/dev/null 2>&1 || true + wait "$chrome_pid" >/dev/null 2>&1 || true + return 0 + fi if grep -Fq 'data-op-smoke="ok"' "$out" 2>/dev/null; then kill "$chrome_pid" >/dev/null 2>&1 || true wait "$chrome_pid" >/dev/null 2>&1 || true @@ -116,7 +128,9 @@ chrome_dump() { fi sleep 1 done - kill "$chrome_pid" >/dev/null 2>&1 || true + # SIGKILL, not SIGTERM: a headless Chrome wedged mid-GPU-stall has been + # observed ignoring TERM, which turns the wait below into a permanent hang. + kill -9 "$chrome_pid" >/dev/null 2>&1 || true wait "$chrome_pid" >/dev/null 2>&1 || true printf 'headless Chrome timed out for %s after %ss\n' "$url" "$timeout" >&2 return 124