Open Legiew opened 1 year ago
@Legiew , I have replicated your problem in the latest version of Cypress and will forward this ticket to the appropriate team. They will soon evaluate the priority of this ticket and consider their capacity to pick it up. Please note that this does not guarantee that this issue will be resolved. The ticket will indicate status changes during evaluation, so we ask that you please refrain from asking for updates. Thanks!
@Legiew Did you find a workaround for this? Experiencing the same issue when rendering a standalone component that uses ShadowDom ViewEncapsulation
I to would be keen or a fix or workaround. Otherwise using Cypress is an unattainable position for my product.
@jtuds @Legiew @warrensplayer I have a tentative workaround at the moment.
The root of the problem appears to be Cypress tries to redefine a shadowRoot
, on a DOM Element that already has a shadowRoot
attached to. As per the HTML spec, you cannot do this and you cannot remove a shadowRoot
on an element that already has one.
What I have done, is in the beforeEach
block, I call a utility function I have created. This utility function removes the element with the property data-cy-root
and replace it with a new dom element <div data-cy-root></div>
.
// find an element with attribute `data-cy-root`
const el = document.querySelector('[data-cy-root]');
// if the el has a shadow root them remove it
if (el?.shadowRoot) {
el.remove();
// create <div data-cy-root></div> and attach to body
const div = document.createElement('div');
div.setAttribute('data-cy-root', '');
document.body.appendChild(div);
}
This mimics the initial DOM state of the runner before the first test is mounted and ran. However, I am not sure of the robustness of this workaround as I am not sure if there is any other cleanup that is required to unmount.
I suspect this should be fine, as Cypress appears to be doing the rest of its cleanup as expected, it just needs a defensive check to ensure it doesn't run Element.attachShadow()
on a element that already has a shadow root.
Just to share more information, before I found this issue ticket, I raised the question on stack overflow and got an answer very similar to my above workaround, in case people need other workarounds:
Current behavior
If you create a component tests for an angular component the mounting steps execute without an error. If you switch the ViewEncapsulation for this component to ShadowDom only the first mount executes without an error. All other mount calls result in the error "NottSupportedError: Failed to execute 'attachShadow' on 'Element': Shadow root cannot be created on a host which already hosts a shadow tree." The order of the tests is important not the tests themselfs. If you switch the order of the tests again the first one runs through and all others fail.
Desired behavior
Component testing with angular and ViewEncapsulation ShadowDom should mount everytime without a problem.
Test code to reproduce
Minimal repo created with Angular CLI 15, latest cypress version and failing component tests: https://github.com/Legiew/cy-component-shadow-dom npm run cypress:open > execute component tests for app.component
Cypress Version
12.11.0
Node version
18.16.0
Operating System
Windows 11
Debug Logs
No response
Other
No response