v0.2.4
This release focuses on automation reliability, browser compatibility, and reducing unnecessary engine work. It fixes frame teardown crashes, adds recovery for failed CDP workers, improves input and navigation behavior, and tightens the release validation gate. 212 commits since v0.2.3.
Highlights
• Frame teardown no longer crashes under garbage collection. Borrowed iframe contexts are cleaned up safely when their isolate is destroyed, fixing process aborts during page closure (#1197).
• Failed CDP workers are reaped and restarted. Multiworker serving replaces exited workers and avoids routing new connections to workers known to be unavailable. Sessions on a failed worker still require reconnection (#1198).
• Automation spends less time waiting unnecessarily. Idle polling, CDP reply stalls, redundant DOM traversal, and unchanged rendering work were reduced. Ready timers and awaited evaluations now yield so other browser work can proceed (#1078, #1111, #1131, #1132, #1137).
• Input and page lifecycle behavior follow browsers more closely. Text insertion respects beforeinput and canceled keyboard events, readonly controls reject deletion, detached frames stop running timers, and document replacement preserves parser behavior (#1184, #1185, #1186, #1190, #1191).
• Release CI requires all 33 obstacle-course stages. A failure shared by the baseline and candidate can no longer satisfy the absolute behavioral gate (#1195).
Security
• Teredo addresses containing a forbidden IPv4 destination are rejected by the SSRF gate (#1098).
• The standalone renderer HTTP loader applies the same private-network restrictions as page networking (#1072).
• Malformed request-interception URL rewrites fail closed instead of bypassing URL validation (#1076).
• file:// navigation requires explicit permission at the browser layer, not just the CLI (#1070).
• history.pushState() and replaceState() enforce same-origin URLs (#1057).
• __Host- cookies require an explicit Path=/; cookie expiry parsing and IP-domain matching were hardened (#1099, #1073).
• CSS-sized image and mask allocations, robots cache growth, and protocol-supplied values have tighter bounds (#1062, #1064, #1094).
CDP and automation
• Network events reach observer sessions, including intercepted requests, without losing their target routing (#1128, #1194).
• Worker navigation responses expose the final HTTP status. Blocked requests no longer receive a fabricated status (#1119).
• Redirected navigation responses are associated with the final document URL (#1139).
• Active screencasts receive the new-document frame before load completion, reducing blank recordings of short navigations (#1134).
• Runtime.getHeapUsage reports native V8 heap measurements, and HeapProfiler.collectGarbage performs collection (#1135).
• Text insertion honors beforeinput cancellation, and canceled keydown events prevent default editing (#1184, #1185).
• Readonly deletion and textarea newline behavior were corrected (#1186).
• Readiness-file permission handling is portable to Windows (#1150).
Networking and runtime
• Fetch resolves when response headers are available rather than waiting for the complete buffered body (#1146).
• Fetch and XHR cancellation stop native request work and release network-readiness counters. Canceled requests emit Network.loadingFailed (#1193).
• Dynamic resources retain their request destinations (#1181).
• Folded HTTP/1 response headers are accepted by both the normal and stealth transports (#1160).
• Same-origin non-GET fetch and XHR requests send the appropriate Origin header (#1081, #1104).
• WebAssembly streaming calls no longer reach an unset native callback that aborts the process (#1163).
• Microtask exceptions are reported without discarding remaining queued work (#1174).
• Initial iframe realms are created synchronously; detached frames retire their timers and realms (#1140, #1191).
• Iframe discovery microtasks are covered by the termination watchdog (#1136).
Rendering
• Unchanged pages reuse retained rendering work, and transform measurement avoids repeated layout churn (#1111, #1110).
• Native controls inherit font shorthand correctly and retain their intrinsic size when stretched in grids (#1177, #1178).
• Percentage heights resolve across anonymous inline wrappers (#1179).
• Absolutely positioned inline content preserves its static position (#1180).
• Mixed inline content retains the correct owner geometry (#1188).
• Hit testing excludes the bottom and right boundaries of boxes. Borrowed document methods use the receiver’s realm (#1164, #1144).
• Caret lookup uses rendered text geometry, and focus scrolling handles nested containers (#1187, #1133).
• Canvas strokes and gradient color stops are implemented (#1022).
DOM and JavaScript
• new Option(text, value, defaultSelected, selected) creates a real option element (#1196).
• Concrete SVG element interfaces support standard prototype and interface checks (#1112).
• innerText uses rendered text rather than raw DOM text (#1106).
• Session history is exposed through window.history (#1105, #1074).
• Replacement documents and document.write preserve lifecycle, EOF processing, and live foster-parenting anchors (#1027, #1189, #1190).
• Mutation observers honor attribute filters (#1138).
• Response construction and static factories validate their inputs (#1173).
• No-op style.setProperty() calls leave the style attribute unchanged (#1172).
• Media-query changes and reduced-motion emulation reach page scripts and CSS (#1028).
• User Timing marks, measures, and observers are supported. Legacy navigation timing records implemented lifecycle milestones rather than fabricated values (#1166).
• Unsupported editing commands are reported truthfully; iframe IDs are excluded from Window named access (#1183, #1192).
MCP, packaging, and validation
• MCP text-search offsets remain correct across Unicode case folding (#1016).
• Local-network denial messages explain how to enable explicitly permitted local access (#1129, #1175).
• Build and V8 memory configuration documentation was corrected (#1114, #1115).
• CI reuses trusted dependency caches and validates rendering, no-render, and stealth configurations (#1147).
• Final main passed 2,115 render tests with five existing skips and the complete 33/33 obstacle course.
• Additional validation passed 50/50 GC-stressed page closures and the unchanged four-test Grafana admin subset in both Chromium and Obscura. These are bounded checks, not a claim of complete Playwright compatibility.
Current limitations
• IndexedDB can report successful writes without retaining data between transactions. Applications requiring IndexedDB correctness remain affected by #1093.
• Worker recovery replaces the process but does not restore its active sessions.
• Response bodies remain bounded and buffered; earlier header delivery does not provide incremental network streaming.
• Service workers, native media, some Web APIs, and long-tail rendering behavior remain incomplete relative to Chromium.
Contributors
Thanks to @SGavrl, @h4ckf0r0day, @mnaza, @ice-zeus, @flolep2607, @AntonioRossi, @Micaso, @jorgensandhaug, @visto-a11y, @vvinayakkk, @zorahrel, @DamoyY, @abn, and @Yi-111-a for contributions to this release.
Full Changelog: v0.2.3...v0.2.4