Skip to content

fix: XPath resolution for shadow DOM with <slot> elements #1736

Draft
miguelg719 wants to merge 2 commits intomainfrom
miguelgonzalez/stg-1433-cardinal-financial-cardinal-financial
Draft

fix: XPath resolution for shadow DOM with <slot> elements #1736
miguelg719 wants to merge 2 commits intomainfrom
miguelgonzalez/stg-1433-cardinal-financial-cardinal-financial

Conversation

@miguelg719
Copy link
Collaborator

@miguelg719 miguelg719 commented Feb 23, 2026

why

what changed

Changes Made

In packages/core/lib/v3/dom/locatorScripts/xpathResolver.ts
Two changes that fixed the actual XPath resolution failure:

  • composedChildren - slot handling: Added support for elements by using slot.assignedElements({ flatten: true }) to return distributed/assigned content instead of fallback content. This is critical for pages using native shadow DOM with elements.
  • resolveXPathAtIndex - native-first fallback: Changed the hasShadow = true branch to always try native document.evaluate() first before falling back to composed resolution. Previously, when any shadow root existed on the page, native XPath was completely skipped, even for XPaths that don't cross shadow boundaries.

test plan


Summary by cubic

Fixes XPath resolution across native shadow DOM with slot elements and correctly re-renders shadow hosts, restoring Stagehand’s ability to find and fill form fields. Addresses STG-1433 “Could not find an element for the given xpaths.”

  • Bug Fixes
    • XPath: Treat correctly by using assignedElements({ flatten: true }) to traverse distributed content.
    • XPath: Always try native document.evaluate first, then fall back to composed resolution when needed.
    • Shadow hosts: Recreate elements with createElement and transfer attributes/children to trigger constructors and attachShadow.
    • Regenerated DOM scripts and added unit tests for rerenderMissingShadows.

Written for commit 5ac5b4a. Summary will update on new commits. Review in cubic

  1. packages/core/lib/v3/dom/rerenderMissingShadows.runtime.ts

  Replaced cloneNode(true) with document.createElement(tag) to properly trigger custom
  element constructors, plus attribute transfer and child migration.

  2. packages/core/lib/v3/dom/locatorScripts/xpathResolver.ts (additional fix)

  Two changes that fixed the actual XPath resolution failure:

  - composedChildren - slot handling: Added support for <slot> elements by using
  slot.assignedElements({ flatten: true }) to return distributed/assigned content
  instead of fallback content. This is critical for pages using native shadow DOM with
  <slot> elements.
  - resolveXPathAtIndex - native-first fallback: Changed the hasShadow = true branch to
  always try native document.evaluate() first before falling back to composed
  resolution. Previously, when any shadow root existed on the page, native XPath was
  completely skipped, even for XPaths that don't cross shadow boundaries.

  3. Regenerated build artifacts

  Both build/rerender-index.js, build/reRenderScriptContent.ts, and
  build/locatorScripts.generated.ts were regenerated via pnpm run build-dom-scripts.

  4. packages/core/tests/unit/rerender-missing-shadows.test.ts (new)

  Unit tests for the rerenderMissingShadowHosts function (6 test cases). The tests need
  the build:esm pipeline to pass to run, which has pre-existing @types/jsdom issues.
@changeset-bot
Copy link

changeset-bot bot commented Feb 23, 2026

⚠️ No Changeset found

Latest commit: dd48a1a

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

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