You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Nested iframe support needs a request-scoped frame path #1784
We are hitting this as a real blocker in browser automation workflows.
0.27.3 improved frame-scoped selectors and waits, and #925 added the basic OOPIF session routing. #1697 also addresses eval and cross-origin selector behavior. But deeply nested frames still do not have one consistent execution model:
A main-frame snapshot only inlines one iframe level.
Deeper workflows depend on mutable frame state across separate commands.
Refs, CSS selectors, snapshots, and eval do not all resolve through the same complete frame chain.
There is no request-scoped way to address something like outer iframe → embedded app → editor/auth/payment iframe.
Three iframe levels are not unusual in real products. Once observation and action use different frame scopes, the agent cannot reliably tell what it saw or where the next command will run.
I would strongly like to see this treated as a core correctness issue, not a niche feature. Fixing frame support command by command will keep leaving inconsistent behavior.
The behavior we need is:
Recursively inline nested iframe snapshots, with a sensible depth limit and cycle protection.
Preserve the complete frame ancestry for refs so click, fill, type, and wait work directly at any nesting depth.
Allow CSS-selector and eval commands to carry a request-scoped frame path instead of depending only on ambient active_frame_id.
Resolve the same path for same-origin frames and cross-origin/OOPIF targets.
If a frame navigates or detaches, fail clearly rather than silently falling back to the top document.
Add regression coverage for same-origin, cross-origin, and three-level nested iframes across snapshot, ref, CSS, and eval.
I am not attached to a specific CLI syntax. A --frame-path option or an equivalent structured protocol field would both work. The important part is that the complete frame scope travels with the command and is resolved atomically.
Another data point for this, from 0.39.1 against a production legal practice-management web app. Everything is same-origin, and the frames go three levels deep: shell, then content frame, then a results or detail frame.
What we measured:
The main-frame snapshot inlines level 1 only, as snapshot.rs intends (if frame_id.is_none() around L646 at v0.39.1). The app's real content is at level 2, so every screen first comes back as an empty Iframe [ref=eN].
frame @e1 then frame @e4 works, with no snapshot needed between the two hops.
frame '<css>' resolves from the top document only. With level 1 selected, frame '[name=gframe]' fails with Could not find frame for selector.
A snapshot taken inside a frame drops the refs of every other frame. Going back to frame @e1 then fails with Unknown ref: e1.
The selected frame survived a page-opened popup that took focus. The first snapshot in the popup failed with CDP error (Accessibility.getFullAXTree): Frame with the given frameId is not found, and frame main fixed it. tab new resets the frame correctly, so this looks specific to popups the page opens.
Taken together, getting back into a level-3 frame after looking at another level costs frame main, snapshot -i, frame @a, frame @b, snapshot -i, frame @c every time. That's the ambient-state problem described above, and points 1, 2 and 5 of the proposal would remove all of it. #1414 (snapshot --frames) would cover point 1 on its own.
Activity
bundyfx commentedon Oct 19, 2026
Another data point for this, from 0.39.1 against a production legal practice-management web app. Everything is same-origin, and the frames go three levels deep: shell, then content frame, then a results or detail frame.
What we measured:
snapshot.rsintends (if frame_id.is_none()around L646 at v0.39.1). The app's real content is at level 2, so every screen first comes back as an emptyIframe [ref=eN].frame @e1thenframe @e4works, with no snapshot needed between the two hops.frame '<css>'resolves from the top document only. With level 1 selected,frame '[name=gframe]'fails withCould not find frame for selector.frame @e1then fails withUnknown ref: e1.CDP error (Accessibility.getFullAXTree): Frame with the given frameId is not found, andframe mainfixed it.tab newresets the frame correctly, so this looks specific to popups the page opens.Taken together, getting back into a level-3 frame after looking at another level costs
frame main,snapshot -i,frame @a,frame @b,snapshot -i,frame @cevery time. That's the ambient-state problem described above, and points 1, 2 and 5 of the proposal would remove all of it. #1414 (snapshot --frames) would cover point 1 on its own.