vitest-dev / vitest-dev/vitest
Web Component `<slot />` support for locators
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 17.1k
- Forks
- 2k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 94
Description
Clear and concise description of the problem
The locators currently do not follow the slots of Web Components, which is pretty unintuitive, especially when using the accessibility tree in the browser dev tools as primary source.
Consider the following custom element:
<my-list>
<template shadowrootmode="open">
<ul>
<slot></slot>
</ul>
</template>
<li>Item 1</li>
</my-list>
My expectation would be that I can do the following:
const item = page.getRyRole('list')
.getByRole('listitem')
But that does not work because getByRole('list') finds the <ul> and the locators don't chain through the slot.
I created a reproduction repo to play around with this.
Suggested solution
Have locators follow slots and thereby the accessibility tree
Alternative
I added one possible workaround in the reproduction repo. This works for simple cases, does not come without issues:
- It's not really intuitive
- it requires the tag-name of the custom element (which could be considered an implementation detail)
- lt falls apart for more complex Web Components:
Example
<my-dialog>
<template shadowrootmode="open">
<dialog aria-label="Custom element list">
<header>
<slot name="header"></slot>
</header>
<slot></slot>
<footer>
<slot name="footer"></slot>
</footer>
</dialog>
</template>
<div slot="header">
<button aria-label="Close">X</button>
</div>
<div slot="footer">
<button>Close</button>
</div>
</my-dialog>
With chaining through slots this would be possible:
const item = page.getRyRole('dialog')
.getByRole('header')
.getByRole('button', { name: 'Close' })
But without the only way would be via the have to start in the <my-dialog> component and then probably use something like [slot="header"] to get to the right button.
Additional context
This is a long-standing issue with the Playwright locators, but they consider this a breaking change and don't want to fix this without enough upvotes. I summarized everything in this comment. Since the browser mode is still fresh, I hope this change is possible in Vitest.
On another note: I considered opening this issue in the ivya repo, but figured other people looking for this would probably start here.
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked reproduction repo, vitest-slot-feature-request, and compare its locator behavior with the documented Web Component examples. Define done as locators chaining through open shadow-root slots so the list and dialog examples resolve their slotted descendants, including named slots.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- playwright, typescript
- Domain
- testing-qa, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100