Add "selectAll" parameter to extract and observe methods#2081
Add "selectAll" parameter to extract and observe methods#2081NahomAgidew wants to merge 2 commits intobrowserbase:mainfrom
Conversation
|
|
This PR is from an external contributor and must be approved by a stagehand team member with write access before CI can run. |
There was a problem hiding this comment.
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-resolvedobjectIds, 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
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
why
what changed
selectorAllparameter toextract()andobserve()so selector scoping can include all matching elements’ subtrees instead of only the first match; default behavior is unchanged when omitted or falsetest 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 optionssnapshot-a11y-resolvers.test.ts: Cover multi-match scoping (selectAll: true), ensure single-match path doesn’t call bulk resolvers, addresolveObjectIdsForCsscoverage, and asserttryScopedSnapshotforwardsselectAllintoa11yForFrameSummary by cubic
Adds an optional
selectAllflag toextract()andobserve()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
selectAll?: booleantoExtractOptionsandObserveOptions.selectAllfor both CSS and XPath selectors.resolveObjectIdsForCssandresolveObjectIdsForXPath.tryScopedSnapshotto passselectAllthrough to snapshot capture.openapi.v3.yaml; tests cover request serialization (observe/extract) and multi-match scoping.Bug Fixes
dragAndDroptarget IDs and logs details instead of failing.Written for commit 5c5de90. Summary will update on new commits.