Skip to content

Conversation

@sfc-gh-mochen
Copy link
Contributor

@sfc-gh-mochen sfc-gh-mochen commented Jan 9, 2026

Motivation

AI agents naturally try to use Playwright-style selectors because they're expressive and precise:

bdg dom click 'button:text("Submit")'

Problem 1: This fails because bdg only supported standard CSS selectors.

AI agents then fall back to bdg dom eval:

bdg dom eval "document.querySelector('button[class*=\"red\"]')"

Problem 2: This fails with "Object reference chain is too long" because DOM elements can't be serialized.

Problem 3: The previous 2-step workflow was clunky:

# Step 1: Query to get indices
bdg dom query "button"
# Found 3 nodes: [0], [1], [2]

# Step 2: Use cached nodeId
bdg dom click 0

This required maintaining a nodeId cache (QueryCacheManager, DomElementResolver) that could go stale.

Solution

With Playwright selectors, one precise selector replaces the 2-step workflow:

# Old way (2 steps + cache)
bdg dom query "button"        # → [0] Save, [1] Cancel
bdg dom click 0               # hope cache is still valid

# New way (1 step, no cache)
bdg dom click 'button:text("Save")'

Changes

New Playwright Selectors

bdg dom query 'button:has-text("Submit")'  # Contains text (case-insensitive)
bdg dom click ':text("Login")'              # Smallest element with text
bdg dom fill 'input:text-is("Email")'       # Exact text match
bdg dom click 'button:visible'              # Only visible elements

Removed NodeId Caching

  • Deleted DomElementResolver.ts and QueryCacheManager.ts
  • Removed index-based operations (bdg dom click 0)
  • Use --index N flag when selector matches multiple: bdg dom click "button" --index 0

Bug Fixes

  1. eval serialization: bdg dom eval "document.querySelector('button')" now returns element description instead of failing
  2. script execution: Fixed IIFE structure that caused "Uncaught" errors
  3. Next steps suggestions: Shows --index examples when multiple matches found

Test plan

  • bdg dom query 'button:has-text("Submit")' finds buttons with text
  • bdg dom click 'button' --index 0 clicks first match
  • bdg dom eval "document.querySelector('button')" returns description
  • Multiple matches show correct "Next steps" with --index

🤖 Generated with Claude Code

- Remove session.json file write on stop
- Remove offline session fallback from network commands
- Delete unused output.ts module
- Update skill to discourage premature stop calls
- Remove 'save output' references from UI messages
- Demote 'bdg stop' in command listings (show peek/tail first)
- Update golden workflow test to use peek instead of session.json
- Users should use bdg peek to inspect telemetry data
# Conflicts:
#	package-lock.json
Add Playwright-style pseudo-selectors:
- :has-text("text") - element contains text (case-insensitive)
- :text("text") - smallest element with exact text
- :text-is("text") - exact text match (case-sensitive)
- :visible - element is visible

Remove nodeId caching layer:
- Delete DomElementResolver and QueryCacheManager
- Remove index-based operations (bdg dom click 0)
- Always use selectors with optional --index flag

Bug fixes:
- Fix "Object reference chain is too long" in bdg dom eval by handling
  non-serializable DOM elements gracefully
- Fix script execution errors by embedding QUERY_ELEMENTS_HELPER inside
  each IIFE instead of concatenating before it
- Update "Next steps" to show --index when multiple matches found
- Add Playwright Selectors section with :has-text, :text, :text-is, :visible
- Explain why Playwright selectors replace 2-step query+index workflow
- Update Form Interaction to show selector-based approach with --index
- Document that dom eval now handles DOM elements gracefully
- Remove references to index-based operations (bdg dom fill 0)
- Add 'Click Button by Text' pattern example
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.

1 participant