Skip to content

Add "selectAll" parameter to extract and observe methods#2081

Open
NahomAgidew wants to merge 2 commits intobrowserbase:mainfrom
NahomAgidew:nahom/issues/1904
Open

Add "selectAll" parameter to extract and observe methods#2081
NahomAgidew wants to merge 2 commits intobrowserbase:mainfrom
NahomAgidew:nahom/issues/1904

Conversation

@NahomAgidew
Copy link
Copy Markdown

@NahomAgidew NahomAgidew commented May 5, 2026

why

what changed

  • Adds optional selectorAll parameter to extract() and observe() so selector scoping can include all matching elements’ subtrees instead of only the first match; default behavior is unchanged when omitted or false

test plan

  • public-types.test.ts: Extended the expected ExtractOptions / ObserveOptions type shapes to include the new optional selectAll?: boolean field.
  • api-client-observe-variables.test.ts: Verify observe/extract wire requests preserve selectAll in options
  • snapshot-a11y-resolvers.test.ts: Cover multi-match scoping (selectAll: true), ensure single-match path doesn’t call bulk resolvers, add resolveObjectIdsForCss coverage, and assert tryScopedSnapshot forwards selectAll into a11yForFrame

Summary by cubic

Adds an optional selectAll flag to extract() and observe() so scoping can target all matching elements, not just the first. Also preserves partial results during multi-match resolution and filters invalid drag-and-drop targets for more resilient observations (addresses #1904).

  • New Features

    • Added selectAll?: boolean to ExtractOptions and ObserveOptions.
    • Snapshot scoping honors selectAll for both CSS and XPath selectors.
    • A11y snapshot supports multiple scope roots via resolveObjectIdsForCss and resolveObjectIdsForXPath.
    • Updated handlers and tryScopedSnapshot to pass selectAll through to snapshot capture.
    • Updated public types and openapi.v3.yaml; tests cover request serialization (observe/extract) and multi-match scoping.
  • Bug Fixes

    • Multi-match resolvers keep already-found elements if later evaluations fail.
    • Observation mapping drops actions with invalid dragAndDrop target IDs and logs details instead of failing.

Written for commit 5c5de90. Summary will update on new commits.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 5, 2026

⚠️ No Changeset found

Latest commit: 5c5de90

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

This PR is from an external contributor and must be approved by a stagehand team member with write access before CI can run.
Approving the latest commit mirrors it into an internal PR owned by the approver.
If new commits are pushed later, the internal PR stays open but is marked stale until someone approves the latest external commit and refreshes it.

@github-actions github-actions Bot added external-contributor Tracks PRs mirrored from external contributor forks. external-contributor:awaiting-approval Waiting for a stagehand team member to approve the latest external commit. labels May 5, 2026
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

1 issue found across 14 files

Confidence score: 4/5

  • This PR looks safe to merge overall, with one moderate-risk issue rather than a clear merge blocker.
  • In packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts, exception handling appears to drop already-resolved objectIds, which can lose partial results and reduce snapshot completeness when failures occur.
  • Given the 5/10 severity (high confidence), this is a targeted correctness concern but not strong evidence of broad breakage across the PR.
  • Pay close attention to packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts - preserve previously resolved IDs when exceptions are raised.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts">

<violation number="1" location="packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts:318">
P2: Exception handling discards already-resolved objectIds instead of preserving partial results.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant Client
    participant API as Stagehand API Client
    participant V3 as V3 Core
    participant Handler as ExtractHandler / ObserveHandler
    participant Snapshot as Snapshot Capture
    participant A11y as A11y Processor
    participant CDP as Chrome DevTools Protocol

    Note over Client,CDP: NEW: selectAll parameter flow for extract() and observe()

    Client->>API: extract() / observe() with options.selectAll = true
    API->>V3: Forward instruction, selector, selectAll
    V3->>Handler: Pass selectAll in params

    alt selectAll is true
        Handler->>Snapshot: captureHybridSnapshot(selectAll: true)
        Snapshot->>A11y: tryScopedSnapshot(focusSelector, selectAll: true)
        A11y->>CDP: DOM.getDocument for each matched element
        A11y->>CDP: resolveObjectIdsForCss(".card") or resolveObjectIdsForXPath("//a")
        Note over A11y,CDP: NEW: returns array of all matching objectIds
        CDP-->>A11y: ["object-1", "object-2", ...]
        A11y->>CDP: DOM.describeNode for each objectId
        CDP-->>A11y: backendDOMNodeId for each match
        A11y->>A11y: Build set of top-level target backend nodes
        A11y->>A11y: Filter a11y tree to keep subtree of all targets
        A11y-->>Snapshot: scoped accessibility tree with multiple roots
        Snapshot-->>Handler: snapshot scoped to all matching elements
    else selectAll is false or omitted (default)
        Handler->>Snapshot: captureHybridSnapshot(selectAll: false)
        Snapshot->>A11y: tryScopedSnapshot(focusSelector, selectAll: false)
        A11y->>CDP: resolveObjectIdForCss(".card") or resolveObjectIdForXPath("//a")
        Note over A11y,CDP: Existing: single match path
        CDP-->>A11y: single objectId
        A11y->>CDP: DOM.describeNode
        CDP-->>A11y: single backendDOMNodeId
        A11y->>A11y: Filter tree to single root subtree
        A11y-->>Snapshot: scoped tree with one root
        Snapshot-->>Handler: snapshot scoped to first match only
    end

    alt Extract flow
        Handler->>Handler: LLM extraction using scoped snapshot
        Handler-->>V3: Extracted data
        V3-->>API: Result
        API-->>Client: Response
    else Observe flow
        Handler->>Handler: LLM observation using scoped snapshot
        alt selectAll is true
            Handler->>Handler: Resolve all matched element selectors
        else selectAll is false
            Handler->>Handler: Resolve only first matched element selector
        end
        Handler-->>V3: Observed actions
        V3-->>API: Result
        API-->>Client: Response
    end

    Note over Client,CDP: Key Branches for resolveObjectIdsForCss/XPath
    loop For index 0..N while objectId found
        A11y->>CDP: Runtime.evaluate(resolver(index))
        CDP-->>A11y: objectId or null
        alt objectId returned
            A11y->>A11y: Add to array
        else null returned
            A11y->>A11y: Stop iteration
        end
    end
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread packages/core/lib/v3/understudy/a11y/snapshot/focusSelectors.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external-contributor:awaiting-approval Waiting for a stagehand team member to approve the latest external commit. external-contributor Tracks PRs mirrored from external contributor forks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant