Skip to content

[V3]: fix xpath building logic for coordinates inside of iframes - #2836

Merged
seanmcguire12 merged 7 commits into
v3from
fix-coordinate-resolver
Aug 27, 2026
Merged

seanmcguire12 merged 7 commits into
v3from
fix-coordinate-resolver

Conversation

@seanmcguire12

@seanmcguire12 seanmcguire12 commented Aug 27, 2026

Copy link
Copy Markdown
Member

why

coordinate based targeting can resolve elements inside iframes differently depending on chrome's frame site isolation behavior. when chrome reports the inner frame directly, stagehand was returning the element path inside the iframe without the owning iframe path from the parent page. this caused the xpath-for-location-deep.spec.ts test to fail

this showed up in when using the --disable-features=SitePerProcess chrome flag

this PR also replaces the incorrect -disable-features=site-per-process flag with the correct --disable-features=SitePerProcess flag

what changed

  • updated coordinate xpath resolution to handle direct child frame hits from chrome
  • when DOM.getNodeForLocation reports a different frameId, stagehand now looks up that frame's owning iframe with DOM.getFrameOwner
  • the owning iframe is added to the xpath chain before resolving the inner-frame node
  • this keeps coordinate based iframe targeting consistent across same-process and isolated iframe behavior

test plan

  • e2e test for resolveNodeForLocationDeep now passes

Summary by cubic

Fixes coordinate-based iframe targeting so XPath resolution stays consistent when DOM.getNodeForLocation reports a frame other than the current one, including nested iframes.

  • Resolves each intermediate owning iframe via DOM.getFrameOwner and prepends them to the XPath chain.
  • Returns no XPath when the reported frame's ancestry can't be fully traced to the current frame.
  • Replaces the incorrect --site-per-process flag with --disable-features=SitePerProcess.

Written for commit f48ea11. Summary will update on new commits.

Review in cubic

@changeset-bot

changeset-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f48ea11

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@browserbasehq/stagehand Patch
@browserbasehq/stagehand-evals Patch
@browserbasehq/stagehand-server-v3 Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Architecture diagram
sequenceDiagram
    participant CDP as Chrome DevTools Protocol
    participant CR as coordinateResolver.ts
    participant Page as Page (Session Manager)
    participant BAP as buildAbsoluteXPathFromChain
    participant Map as parentByFrame Map

    Note over CDP,Map: Coordinate-based XPath resolution with cross-frame support

    CR->>CDP: DOM.getNodeForLocation(x, y)
    CDP-->>CR: { backendNodeId, frameId }

    alt Reported frame matches current frame
        CR->>BAP: Build XPath from current iframe chain
        BAP-->>CR: absoluteXPath
        CR-->>CDP: Return { frameId, backendNodeId, absoluteXPath }
    else Reported frame is different (cross-frame hit)
        CR->>Map: Look up parent frame for reportedFrameId
        alt Parent frame found in map
            Map-->>CR: parentFrameId
            CR->>Page: getSessionForFrame(parentFrameId)
            Page-->>CR: parentSession
        else No parent frame in map
            CR->>Page: getSessionForFrame(currentFrameId)
            Page-->>CR: curSession
        end

        CR->>CDP: DOM.getFrameOwner(frameId: reportedFrameId)
        CDP-->>CR: { backendNodeId: iframeBackendNodeId }

        alt Valid iframe backendNodeId returned
            CR->>CR: Append { parentSession, iframeBackendNodeId } to iframe chain
        else Frame owner lookup failed
            CR->>CR: Silently skip (catch block)
        end

        CR->>Page: getSessionForFrame(reportedFrameId)
        Page-->>CR: leafSession

        CR->>BAP: buildAbsoluteXPathFromChain(chain, leafSession)
        BAP-->>CR: absoluteXPath

        alt XPath resolved successfully
            CR-->>CDP: Return { frameId: reportedFrameId, backendNodeId, absoluteXPath }
        else XPath resolution returned null
            CR-->>CDP: Return null
        end
    end
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/core/lib/v3/understudy/a11y/snapshot/coordinateResolver.ts
Comment thread packages/core/lib/v3/launch/local.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/core/lib/v3/understudy/a11y/snapshot/coordinateResolver.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/core/lib/v3/understudy/a11y/snapshot/coordinateResolver.ts Outdated
@seanmcguire12
seanmcguire12 merged commit 94a0ee4 into v3 Aug 27, 2026
468 of 471 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 27, 2026
seanmcguire12 pushed a commit that referenced this pull request Aug 28, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to v3, this PR will
be updated.


# Releases
## @browserbasehq/stagehand@3.7.3

### Patch Changes

- [#2842](#2842)
[`f86e609`](f86e609)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - update the
MCP SDK to v1.30 and refresh supporting dependency versions

- [#2836](#2836)
[`94a0ee4`](94a0ee4)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - fix
cross-frame xpaths building logic for coordinates inside of iframes.

## @browserbasehq/stagehand-evals@2.1.2

### Patch Changes

- Updated dependencies
\[[`f86e609`](f86e609),
[`94a0ee4`](94a0ee4)]:
    -   @browserbasehq/stagehand@3.7.3

## @browserbasehq/stagehand-server-v3@3.7.6

### Patch Changes

- [#2845](#2845)
[`c2eef9c`](c2eef9c)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - refresh
server routing and OpenAPI dependencies

- Updated dependencies
\[[`f86e609`](f86e609),
[`94a0ee4`](94a0ee4)]:
    -   @browserbasehq/stagehand@3.7.3

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants