Skip to content

fix(extension): speed up text locator count and nth on large lists - #3308

Open
ShivanshSinghaL06 wants to merge 1 commit into
browserbase:mainfrom
ShivanshSinghaL06:fix/text-locator-count-nth-perf
Open

ShivanshSinghaL06 wants to merge 1 commit into
browserbase:mainfrom
ShivanshSinghaL06:fix/text-locator-count-nth-perf

Conversation

@ShivanshSinghaL06

@ShivanshSinghaL06 ShivanshSinghaL06 commented Oct 23, 2026 •

Copy link
Copy Markdown

why

text= locator count() and nth() take seconds on large repeated lists: text matching removes ancestor matches with a pairwise contains loop, and indexed resolution re-scans the page once per index and keeps a remote handle for every preceding match.

Closes #3238

what changed

  • Added a shared linear text walk (textMatches.ts) used by both countTextMatches and resolveTextSelector. Ancestors are suppressed during the walk and leaves skip layout when their text has no whitespace to collapse. nth stops early once the requested index is found.
  • FrameSelectorResolver.resolveAtIndex now evaluates the selector helper once and creates one remote object, instead of going through resolveAll.
  • Updated the resolution tests that assumed prefix handles, and added tests for ordering, shadow hosts, closed and nested shadow roots, hidden text, whitespace collapsing and a 10,000-row list.
  • Added a changeset.

test plan

  • Extension unit tests: 68 files, 1057 tests pass.
  • Locator integration tests (textSelectorInnermost, locatorNth, locatorCount): 26 of 26 pass in Edge on Windows.
  • Issue repro (10,000 rows): count() ~4,124 ms to ~15 ms, nth(2).innerText() ~12,498 ms to ~15 ms. The first call is ~1.25 s because of cold-start setup.

Summary by cubic

Speeds up text= locator count() and nth() on large repeated lists.

  • Text matching now runs in a single linear walk that suppresses ancestor matches without a pairwise contains loop, and nth() stops early after finding the requested index.
  • FrameSelectorResolver.resolveAtIndex now evaluates the selector helper once and returns one remote object, instead of resolving and releasing all preceding matches.
  • Updated resolution tests to match the new single-evaluation behavior, and added tests for match ordering, shadow hosts and nested shadow roots, hidden text, whitespace collapsing, and a 10,000-row list.

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

View guided diff

@changeset-bot

changeset-bot Bot commented Oct 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f4f1ba4

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

This PR includes changesets to release 24 packages
Name Type
@browserbasehq/stagehand-extension Patch
@browserbasehq/stagehand Patch
@browserbasehq/stagehand-python Patch
@browserbasehq/stagehand-go Patch
browse Patch
@browserbasehq/stagehand-examples Patch
@browserbasehq/stagehand-integrations-claude-cua-sdk Patch
@browserbasehq/stagehand-integrations Patch
@browserbasehq/eve Patch
@browserbasehq/stagehand-integrations-gemini-cua-sdk Patch
@browserbasehq/stagehand-integrations-example-pi-facade Patch
@browserbasehq/stagehand-integrations-claude-agent-sdk Patch
@browserbasehq/stagehand-integrations-example-claude-code-facade Patch
@browserbasehq/stagehand-integrations-codex-sdk Patch
@browserbasehq/stagehand-integrations-example-codex-facade Patch
@browserbasehq/stagehand-integrations-cursor-sdk Patch
@browserbasehq/stagehand-integrations-example-cursor-facade Patch
@browserbasehq/stagehand-integrations-deepagents-sdk Patch
@browserbasehq/stagehand-integrations-eve-sdk Patch
@browserbasehq/stagehand-integrations-fx-sdk Patch
@browserbasehq/stagehand-integrations-mastra-sdk Patch
@browserbasehq/stagehand-integrations-example-mastra-facade Patch
@browserbasehq/stagehand-integrations-pi-sdk Patch
@browserbasehq/stagehand-integrations-example-vercel-ai-facade 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

@github-actions

Copy link
Copy Markdown
Contributor

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 Oct 23, 2026

This branch has not been deployed

No deployments
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.

Text locator count and nth lookups take seconds on large repeated lists

1 participant