Files
Zhifei Li 7c2057a1df feat(render): one CDP backend, auto turbo/standard (delete websocket.py) (#38)
* fix(render): wait for load + scroll per tile in CDP backend

The websocket CDP backend fired document.fonts.ready immediately after
Page.navigate and never scrolled between tiles. On JS/SPA pages this captured
a transient pre-hydration layout (tall, mostly empty) -> blank tiles; at small
--tile-height it also left every tile past the first blank, since content below
the device viewport is never rasterized without scrolling.

- Wait for the load event (readyState shortcut + 12s cap) before measuring and
  capturing. SSR pages fire load ~as fast as fonts.ready, so ~no cost.
- Scroll each tile into view before capture (matches the batch renderer).
- Add opt-in --wait-network-idle for pages that fetch content after load; the
  pixelbrowse skill enables it by default.

Verified against bench ground truth (100% on the smoke set); Wikipedia render
time unchanged.

* docs(render): document the SPA-render fix and backend reconciliation

* feat(render): deterministic turbo-capability detection (no runtime probe)

is_turbo_capable(path) is True only for the pixelrag-installed patched
headless_shell (by install-path provenance + version.json marker). Lets the
backend default to turbo when the patched Chrome is present and fall back to
standard capture on stock Chrome, without a hang-prone runtime probe.

* feat(render): unify on one CDP backend with auto turbo/standard selection

Rename websocket.py -> cdp.py and make render_urls the single entry point:
it auto-selects the TURBO path (delegates to fast_cdp: rawFilePath + parallel
JPEG) when a turbo-capable patched Chrome is present, else the portable STANDARD
path. Selection is deterministic via chrome.is_turbo_capable (provenance, no
runtime probe), so a stock Chrome is never sent the patched-only CDP params.

- Turbo only engages for fast_cdp's capture profile (jpeg, default viewport,
  fromSurface, no network-idle); other requests use the standard path.
- Both paths emit the same {stem}.png.tiles/ layout (turbo via path='{stem}.png').
- file:// inputs normalized for fast_cdp (it prepends file:// to non-http paths).
- render.py points at backends.cdp; 'websocket' kept as a back-compat alias.

Verified: turbo (patched chrome) and standard (patched + stock Playwright
Chromium) both produce correct content tiles; ruff + tests/test_render.py green.

* style: ruff format cdp.py

* fix(render): use --headless=new (bare --headless is deprecated on modern Chrome)

Bare --headless hangs google-chrome 149+. --headless=new works on stock Chrome
and the patched headless_shell. Verified: standard path on Playwright Chromium
and turbo path on the patched binary both still render correctly.
2026-06-11 19:38:05 +08:00
..
2026-06-01 22:41:36 -07:00
2026-06-01 22:41:36 -07:00