4 ms·
I'm currently working on testing a UI with Selenium that uses Shadow DOM all over the place. It's hot garbage, and I have no idea why anybody thought this was a
by kazoomonger 5y ago
I'm currently working on testing a UI with Selenium that uses Shadow DOM all over the place. It's hot garbage, and I have no idea why anybody thought this was a good idea.
Something goes wrong in CI and you'd like to dump the DOM to figure out why? Too bad, the entire page is sitting inside a Shadow DOM, and you get to see an empty body tag and a timeout waiting for an element to appear.
Want to click that button that's nested 5 Shadow DOMs deep? Have fun creating a monster JS query to manually trawl though the Shadow DOMs to click it, because Selenium has no idea how to access the button. And that's if you're lucky and the Shadow DOM is marked "open". If it's marked closed, you can go sit on your thumb.
It's like someone looked at iframes and thought "hey, that's a great idea!" and never stopped to think why they were considered bad practice already 20 years ago.
- jcbrand 5y agoIMO the shadow DOM should be used sparingly and in most cases not at all. You can use web components without the shadow DOM (I've seen them being called "custom elements" then). That's what I do and I'm happy with the results.
- zdragnar 5y ago"Web components" is really a collection of several independent specifications. Custom elements and shadow Dom are two of those, and I tend to agree that sticking with just custom elements will save a lot of headaches with the way things are now.
- tmcneal 5y agoIt's surprising how poorly supported Shadow DOM is across the major UI testing frameworks. To access a Shadow DOM element you'll typically need to write a JS shim that uses the DOM APIs to get at the element, and then do other tricks to work around things like closed vs. open shadow roots and handle how event propagation works with shadow DOM. Shameless plug, but we're building a no-code testing framework (https://reflect.run https://reflect.run) that does all of this for you automatically. Works great with Shadow DOM (both open and closed) as well as more esoteric things - for example did you know Salesforce's Lightning framework overrides how Shadow DOM works? :D
- kazoomonger 5y agoThat looks cool, but from what I can tell, not really something I can use. All of the Selenium testing I'm doing is accessed via localhost, often on bare metal. None of it's available via the internet, which it looks like is required by your service.
- mhoad 5y agoI don't really how you took a bug in Selenium and somehow turned it into an indictment of Shadow DOM.
- kazoomonger 5y agoIt's not just Selenium, it's anything that has to interact with Shadow DOM. If you want to use pure JS to click the button in my above example, you can't just write this: document.querySelector("#foo").click() You have to write something like this: document.querySelector("#nested-1").shadowRoot.querySelector("#nested-2").shadowRoot.querySelector("#foo").click() It's not just the length of the query (which can get stupidly long), it's that you have to know and care about the overall structure of the document and where the button sits in it. I just want to click the damn button. It has a nice, easy-to-find ID attached to it, why does that have to be so hard? Also, it's not a Selenium bug that you can't dump the entire DOM when Shadow DOM gets involved. That's by design; Selenium just allows you to call `innerHTML` or similar, and if the <body> tag is using Shadow DOM because someone else thought it was a great idea to make the whole page a Web Component then you're SOL and you'll just get `<body></body>`. Have fun debugging that. The worst part about all this bad design is that it wasn't even necessary. Are you worried about a bad CSS rule from some fancy component causing havoc with the rest of your page? There should exist something as simple as `<div style-link="foo.css">...</div>`. Have those rules scoped to that div element and you're done, problem solved. Worried about some component's JS causing havoc? Same thing, `<div script-link="foo.js">...</div>`. All JS is automatically scoped to that div element. That would have been far better than the brain-dead approach of Shadow DOM.