fix(web): place nodes inside iframes in page coordinates
Summary
On web targets, coordinate presses on elements inside an iframe missed. agent-browser measures a node inside an iframe against that frame's own viewport, so presses landed on the page around the frame.
The snapshot now places each such node from its frame's unclipped viewport (page position plus border and padding, read only when a page has iframes) and clips it to the part of the frame the page shows. Content scrolled out of its frame, or inside a frame that cannot be measured, gets no rect. Frames under CSS transform: scale() or zoom are not scaled.
Reuse: one intersectRects in kernel/rect replaces copies in selectors and maestro and backs intersectScreenshotRect. Box and style reads share one batched reader.
The test-app WebView fixture gains same-origin, data: and cross-site iframes. Its whitelist adds only about:srcdoc and data:, which the default blocks for iframes.
Validation
Head cdbea80368:
pnpm check:affected --run --head cdbea80368passed, and so dideager-closure-budgets.test.ts.- New tests (nested placement, clipped nested frame, clipping, unmeasurable inset or box) fail with the projection, clip, or origin fix reverted.
- Live, agent-browser 0.39 (evidence): with the page scrolled, presses in a self-scrolled same-origin frame and an out-of-process cross-site frame land on the exact point the frame records, and a cross-site link navigates its frame. agent-browser lists no nested-iframe content, so nested placement is unit-tested only.
Out of scope: web @ref presses fail with "no usable bounds" on main-frame elements too.
š¤ Generated with Claude Code