v0.2.6
This release improves request interception, frame navigation, CDP responsiveness, and JavaScript startup. It also fixes browser API behavior, updates security-sensitive dependencies, and strengthens performance regression checks. 117 commits since v0.2.5.
Highlights
- Main-document requests can be intercepted before transport. Playwright and Puppeteer can fulfill navigation requests directly. Binary bodies, repeated cookies, continuation overrides, redirects, and request completion retain their expected behavior (#1384).
- CDP remains responsive while evaluations await promises. Other commands and interception replies can proceed while asynchronous evaluations settle. Script evaluation runs directly through V8 and preserves global lexical bindings (#1310).
- Frame navigation stays in the correct document. Child-frame Location methods and named form targets navigate their owning frames. Blank iframe documents initialize during insertion, and iframe shadow roots use the correct document (#1357, #1359, #1385).
- Startup and response handling avoid repeated work. Common browser methods are precompiled, bootstrap source is shared across isolates, inline styles are allocated on demand, and stored response bodies are encoded only when a client reads them.
- Security dependencies are updated without replacing stealth profiles. Compression, Tokio, and TLS verification dependencies receive patched versions. Dependency audits pass without additional advisory exceptions (#1352, #1393).
Rust API change
StoredResponseBody.body changes from String to Vec<u8> and now contains the raw response bytes.
Rust callers needing the previous text or base64 representation should use .cdp_body(). CDP response formats are unchanged (#1335).
Security
- Tokio is updated to 1.53.3,
rustls-webpkito 0.103.16, and the affected WebPKI root packages to 1.0.10 (#1352). - Compression dependencies move to patched
zstd0.14.3,zstd-safe8.2.0, andzstd-sys2.1.2, with Brotli dependencies aligned. The existing emulation profiles are retained. Already-buffered certificate input avoids an unnecessary decoder allocation (#1393). - The network loader itself enforces the
file://opt-in, protecting callers that do not pass through navigation-level checks. Explicitly permitted file access remains available (#1280). - Scripted
fetch()ignores forbidden request headers (#1358). - Wrapped JWK serialization and parsing use native JSON handling. Key wrapping validates permissions and extractability (#1290).
CDP and automation
Runtime.evaluateexecutes directly in V8. Replacing the page’sevalno longer intercepts protocol evaluation, and global lexical bindings remain accessible to later evaluations (#1310).- Awaited evaluations no longer hold up all subsequent CDP commands. Function calls use native invocation and preserve JSON arguments.
DOM.getAttributes,DOM.requestNode,DOM.requestChildNodes, andDOM.getNodeForLocationsupport the top-level light DOM. Published node tracking belongs to each session and resets during navigation and teardown (#1300).- Initialization scripts are scoped to their target instead of leaking into unrelated pages (#1360).
- Main-document interception preserves supplied bytes and repeated
Set-Cookieheaders. Failed and canceled requests complete once under their original request IDs (#1384). - Explicit network-idle navigation respects its configured deadline and reports failure if requests remain active. It no longer reports successful idle after an unconditional five-second cutoff (#1388).
- MCP
browser_wait_for_functioncontinues driving page tasks, allowing predicates dependent on network callbacks to complete (#1298).
Networking and page lifecycle
Responseaccepts suppliedReadableStreambodies without stringifying or draining them during construction. Consumption preserves byte validation, errors, locking, cancellation, cloning, and pull backpressure (#1386).- Child-frame Location navigation loads that frame without replacing its parent. Detached frame windows cannot queue parent navigation (#1385).
- Forms honor named child-frame targets (#1357).
- Blank iframe documents initialize during insertion. Initial frame setup also handles reentrant operations safely, fixing an iframe initialization abort (#1359, #1306).
- Fragment navigation updates same-document history and dispatches
hashchangewithout reloading the document. Assigning an unchanged fragment preserves the existing history entry (#1287). robots.txtparsing keeps consecutive user-agent lines in one group and separates wildcard matches from named-agent matches (#1350).--user-agentis accepted as a global CLI option. Explicit overrides reach both stealth requests andnavigator.userAgent, with per-request headers taking precedence (#1279, #1389).
DOM, JavaScript, and rendering
- Twenty-eight missing HTML interface globals gain distinct prototypes and tag-specific brands. Namespace-aware creation and cloning preserve qualified names and prefixes (#1387).
- Worker globals expose ECMAScript built-ins and Web APIs as properties of their scope (#1368).
DOMImplementationis exposed globally (#1375).window.eventidentifies the current event during handlers and listeners, restoring the previous value after nested dispatch or exceptions (#1345).documentis read-only, and ordered-list and list-item attributes reflect through their DOM properties (#1303, #1297).- Summary activation toggles details elements, and changes to
openqueue toggle events (#1299). - Shadow-root creation and lookup inside iframes use the owning frame’s document (#1343).
checkVisibility()evaluates implemented visibility rules instead of always returning true. Render builds also preserve inherited computed visibility (#1071).- Hidden table rows are excluded from layout, and table row and row-group display values are respected (#1304, #1307).
- Previously missing computed-style longhands and the
cssFloatalias are exposed (#762). - WebCrypto supports AES-KW key wrapping and unwrapping with native JWK serialization (#1290).
Runtime performance
- Common DOM, URL, and response methods are precompiled into the startup snapshot. Their bodies are not executed during preparation, and compiler hooks are removed before page execution (#1325).
- Bootstrap source is shared across isolates, inline style objects are allocated on demand, and parallel runtime startup is bounded.
- Window named-property lookup batches work in the native DOM, and UTF-8 decoding uses the native path while preserving explicit encoding handling.
- Native-function source metadata uses weak references so discarded functions can be collected (#1322).
- Response bodies remain raw bytes until CDP serialization is requested, avoiding eager text or base64 conversion for unread bodies (#1335).
Packaging and validation
- Patched compression, font, and layout dependencies propagate to embedded Rust consumers (#1393).
- Release packaging runs the dependency audit before building and publishing artifacts.
- Performance CI checks sustained DOM workloads and CPU consumption alongside latency and memory. Obstacle-course latency regressions also fail the performance gate (#1351, #1383).
- Rendering fixture checks enforce zero-count assertions (#1305).
- Final validation passed 2,459 render tests with five existing skips, 1,505 no-render workspace tests with three existing skips, 31 library API tests, and the stealth networking checks.
- All four release build configurations passed: render, render+stealth, no-render, and no-render+stealth.
- Main passed the complete 33/33 obstacle course.
- The shipping render+stealth binary received separate paired CPU, memory, and screenshot checks. Both rendering fixtures produced pixel-identical output against the preceding shipping baseline.
Current limitations
- The new CDP node commands cover the top-level light DOM. Live mutation events, detached-node publication, and frame or shadow-tree traversal remain incomplete.
- Supplied
Responsestreams are supported; network response bodies remain bounded and buffered. - PDF output remains raster-backed.
- Service workers, native media, some Web APIs, and long-tail rendering behavior remain incomplete relative to Chromium.
Contributors
Thanks to @alexskinner, @anzal1, @bkircher, @chiliec, @flolep2607, @fwonce, @HyperionBurn, @Kevsosmooth, @lisa0314, @lucasbrito-wdt, @Micaso, @ntdatt812, @orezraey, @shaipe, @suleman-dawood, and @yzyf1312 for contributions to this release.
Full Changelog: v0.2.5...v0.2.6