testing-library / testing-library/user-event

Support open shadow DOM components

Open
#1,026 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
2.3k
Forks
258
PR merge metrics
No merged PRs in 30d

Description

Problem description

Hello,

this is a follow up to #1025. Currently the library doesn't support web components which use shadow dom. This feature request only deals with open shadow doms. The underlying issue seems to be that with web components the element that is focused can be different from the one where input needs to take place: Web Components wrap builtin elements on which the input takes place. To get the element to interact with document.activeElement seems to be used. In case of web components this would return the web component, while the element that would need to be interacted with (e. g. an input element within the shadow DOM) is hidden from the library.

Suggested solution

There has been prior art in the form of getActiveElement (https://github.com/testing-library/user-event/blob/main/src/utils/focus/getActiveElement.ts) which iterates over potential shadow DOM's activeElement property, until the element to interact with is reached.

This could be used as a replacement for document.activeElement to make the library open shadow DOM compatible. I quickly hacked this together on paste() and it seems to get the job done:
https://github.com/Christian24/user-event/blob/f4242842c1ed51d2ec8042263bee7abdbafea21e/src/clipboard/paste.ts#L14

In some cases like keyboard input it seems to be more an issue of getting the element to focus properly first.

Interestingly, user.click(element) doesn't seem to focus the input within the web component, not sure why. I had to manually querySelector the input to get my paste test to work:
https://github.com/Christian24/user-event/blob/main/tests/webcomponents/index.ts#L29

jsdom doesn't implement delegatesFocus currently: https://github.com/jsdom/jsdom/issues/3418

Additional context

I have been playing a little bit with this this afternoon: https://github.com/Christian24/user-event
Not sure it will evolve into a PR though, would like to hear seasoned contributors opinion first. Also for some reason I couldn't get the tests to debug in VS Code...

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/utils/focus/getActiveElement.ts and the existing handling in src/clipboard/paste.ts, then inspect tests/webcomponents/index.ts. Run the web-component tests and trace focus and active-element behavior; done means open shadow DOM components are supported for the affected interactions without relying on manual input lookup.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
frontend, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.