-
Notifications
You must be signed in to change notification settings - Fork 962
add support for shadow doms (open & closed mode) #954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: fd7338a The changes in this PR will be included in the next version bump. 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 |
bd4a3ab
to
be7f776
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Summary
This PR introduces comprehensive Shadow DOM support to Stagehand, enabling interaction with elements inside both open and closed shadow roots. The implementation addresses multiple user-reported issues where Stagehand previously returned 'not-supported' errors for shadow DOM elements.
The solution uses a multi-layered approach: (1) JavaScript injection that intercepts Element.prototype.attachShadow
early in the page lifecycle to capture closed shadow roots in a WeakMap, (2) a global window.__stagehand__
backdoor API providing safe access to closed shadow roots without DOM mutations, (3) a custom Playwright selector engine 'stagehand' that performs depth-first search traversal across regular DOM nodes, open shadow roots via el.shadowRoot
, and closed roots via the backdoor API.
The feature integrates throughout the codebase by adding experimental flag support to all handlers (ActHandler, ExtractHandler, ObserveHandler), modifying XPath generation to include shadow root markers using '//' syntax, enhancing accessibility tree building to traverse shadow boundaries, and adding specialized error classes for shadow DOM failures. Eight comprehensive evaluation tests validate different combinations of shadow DOM modes (open/closed) with iframe contexts (OOPIF/SPIF).
The implementation is gated behind the experimental: true
flag in the Stagehand constructor to prevent breaking existing behavior and is not yet available on the API. This architectural choice allows users to opt into the enhanced functionality while maintaining backward compatibility for production environments.
Confidence score: 3/5
- This PR introduces significant complexity with experimental shadow DOM support that could cause issues if not thoroughly tested in production scenarios
- Score reflects the experimental nature of the feature and potential edge cases in shadow DOM traversal, especially with the global window object modification and WeakMap approach
- Pay close attention to
lib/StagehandPage.ts
where shadow DOM detection logic may incorrectly identify elements, and evaluate files that lack proper return statements for failure cases
17 files reviewed, 10 comments
why
what changed
Element.prototype.attachShadow
early and stashes closed mode shadow roots in aWeakMap
selectors.register('stagehand', …)
el.shadowRoot
,window.__stagehand__.getClosedRoot(el)
note
experimental
flag in the stagehand constructor, so that we can give people access without breaking existing behaviourexperimental: true
in order to use ittest plan
regression
evalsact
evalsextract
evalsobserve
evals