Skip to content

Nested iframe support needs a request-scoped frame path #1784

Closed

Description

@MaxWang007

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:

  1. Recursively inline nested iframe snapshots, with a sensible depth limit and cycle protection.
  2. Preserve the complete frame ancestry for refs so click, fill, type, and wait work directly at any nesting depth.
  3. Allow CSS-selector and eval commands to carry a request-scoped frame path instead of depending only on ambient active_frame_id.
  4. Resolve the same path for same-origin frames and cross-origin/OOPIF targets.
  5. If a frame navigates or detaches, fail clearly rather than silently falling back to the top document.
  6. 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.

Related: #318, #279, #925, #1697

Activity

  1. bundyfx commented on Oct 19, 2026

    @bundyfx

    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.

  2. locked and limited conversation to collaborators on Nov 3, 2026
  3. converted this issue into a discussion #2328 on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions