Skip to content

v0.4.7

@Averyy Averyy tagged this 02 Aug 14:47
Callers that need the per-exchange request/response log rather than a
settled document have to drive their own Playwright, and were
reimplementing the launch hardening badly. Measured: a discovery browser
launched with a bare headless=True advertises
HeadlessChrome/147.0.7727.15, which is enough for metacareers.com to
answer its own search query with HTTP 200 and
{"errors":[{"message":"Rate limit exceeded"}]}, and for Cloudflare to 403
jobs.uber.com's RSC prefetches. Both boards answer plain wafer with 200
and full payloads, so those were facts about the browser, not the boards.

hardened_launch_config() and scrub_headless_ua() are now exported from
wafer.browser and consumed by _ensure_browser, so there is one source of
truth that a Chrome bump reaches. --headless=new does not remove the
HeadlessChrome token, so the UA scrub is separate and both are needed.

The CDP screenX/screenY patch is deliberately excluded: it is only
correct on a Chrome whose event descriptors are already wrong, which
wafer establishes with a real-input probe at solve time.

A missing user agent now raises instead of leaving _browser_ua unset,
which would make _create_context skip the override and leak
HeadlessChrome on every request.

These flags had no test coverage at all. Adds 27, including two that pin
_ensure_browser to the exported function so the two cannot drift apart.
ref-headless.md documented --disable-site-isolation-trials as active
when it was removed because Cloudflare detects it; corrected, with the
three genuinely-active args it was missing.

No behavior change. Verified identical argv against the pre-refactor
logic across darwin/linux/win32 x headless/headed x proxied/direct, and
live against scrapingcourse.com/cloudflare-challenge on Chrome
150.0.7871.187: headed 200/4,264B in 5.6s, headless 200/4,264B in 5.5s,
7 cookies and 0 rotations each, replay 200 in 0.3s/0.4s, headless UA
carrying no Headless token.
Assets 2
Loading