Open chadwtkns opened 3 years ago
I have almost zero experience with shadow dom and web components, so I can comment very little on what the cause is or how to fix it.
That being said, I do not object to making it work as long as the changes needed for it are manageable in terms of future maintenance and of course that they do not affect the existing functionality. I'd be open to see a draft of what it would take, say, with a single custom matcher first, before we set out to make all custom matchers compatible with these requirements.
Hello!
@chadwtkns I tried to create a simple repro and it worked for me
class CustomElement extends window.HTMLElement {
constructor() {
super()
this.attachShadow({mode: 'open'})
this.shadowRoot.innerHTML = '<template><slot /></template>'
}
}
window.customElements.define('custom-element', CustomElement)
test('shadow dom support', () => {
const defaultElement = document.createElement('custom-element')
expect(defaultElement.shadowRoot.querySelector('template')).toContainHTML(
'<slot>',
)
})
There could be additional gotchas you will need to watch out:
defaultElement.shadowRoot
, not defaultElement.shadow
defaultElement.shadow.querySelector('slot')
returns null, because the content of <template>
element is passive and not queryablecustom-element
implementation, it is hard to tell without the full demo.It would be helpful if you create a demo using official codesandbox template: https://codesandbox.io/s/5z6x4r7n0p
Just recently a package appeared which makes it really easy to interact with the shadow Dom using Testing Library methods: https://www.npmjs.com/package/shadow-dom-testing-library
Hi. I'm the maintainer of said package, I needed it for work and figured I'd share with the world 🤷♂️
For anyone in the wide world future seeing this, there is an easy way to port queries to check shadow DOM that I haven't seen anywhere else on there internet.
You can do a slightly different version of this for all different types of queries or create some sort of factory to do so.
import { AllByRole, buildQueries, ByRoleMatcher, ByRoleOptions, queryAllByRole } from '@testing-library/dom'
const _queryAllByRoleDeep: AllByRole = function (container, ...rest) {
const result = queryAllByRole(container, ...rest) // replace here with different queryAll* variants.
for (const element of container.querySelectorAll('*')) {
if (element.shadowRoot) {
result.push(..._queryAllByRoleDeep(element.shadowRoot as ParentNode as HTMLElement, ...rest))
}
}
return result
}
const [_queryByRoleDeep, _getAllByRoleDeep, _getByRoleDeep, _findAllByRoleDeep, _findByRoleDeep] = buildQueries<
[ByRoleMatcher, ByRoleOptions?]
>(
_queryAllByRoleDeep,
(_, role) => `Found multiple elements with the role ${role}`,
(_, role) => `Unable to find an element with the role ${role}`
)
export const queryAllByRoleDeep = _queryAllByRoleDeep.bind(null, document.body)
export const queryByRoleDeep = _queryByRoleDeep.bind(null, document.body)
export const getAllByRoleDeep = _getAllByRoleDeep.bind(null, document.body)
export const getByRoleDeep = _getByRoleDeep.bind(null, document.body)
export const findAllByRoleDeep = _findAllByRoleDeep.bind(null, document.body)
export const findByRoleDeep = _findByRoleDeep.bind(null, document.body)
@milky2028 thats roughly what shadow-dom-testing-library is doing for queries.
https://github.com/KonnorRogers/shadow-dom-testing-library/blob/main/src/shadow-queries.ts
https://github.com/KonnorRogers/shadow-dom-testing-library/blob/main/src/deep-query-selectors.ts
as I worked on it there were additional warts:
<slot>
projected elements weren't detectedouterHTML
https://github.com/KonnorRogers/shadow-dom-testing-library/blob/main/src/pretty-shadow-dom.ts
There's probably more I've forgotten.
Hi Im curious if Jest DOM can support Web Components using the Shadow DOM
For example Ive got the following test
and the test is complaining that received is not an HTMLElement or SVGElement. My understanding is that the shadow DOM doesn't appear to be supported by jest-dom so I am curious if this is something that could be considered. I know its not a trivial thing to add and depending on how much time I get I'm open to giving a shot to implement it myself too but I'd like the maintainer's thoughts on this. Thank you!