I have an application made with Polymer that I need to automate. The problem is it has a lot of Shadow DOMs.
I'm using FluentAutomation that only knows to work with CSS selectors and some jQuery.
Is there a way to identify the elements inside a Shadow DOMs using CSS selectors?
do you mean to select a dom node that is part of a shadow dom?
as there I no selector that pierces shadow dom you will have to provide the full path to a dom node. Example Source:
<my-app>
#shadow-root
<h3 part="header">My App Header</h3>
<my-dialog>
#shadow-root
<p part="header">My Dialog Header</p>
<my-alert>
#shadow-root
<span part="header">My Alert Header</span>
</my-alert>
<my-alert>
#shadow-root
<span part="header">My Alert Header</span>
</my-alert>
</my-dialog>
</my-app>
To select the first my-alert you would need to do
document.querySelector('my-app').shadowRoot.querySelector('my-dialog').shadowRoot.querySelector('my-alert');
if you have ids like so
<my-app id="app">
#shadow-root
<h3 part="header">My App Header</h3>
<my-dialog id="dialog">
#shadow-root
<p part="header">My Dialog Header</p>
<my-alert id="alert1">
#shadow-root
<span part="header">My Alert Header</span>
</my-alert>
<my-alert id="alert2">
#shadow-root
<span part="header">My Alert Header</span>
</my-alert>
</my-dialog>
</my-app>
You can use a more optimized path.
document.querySelector('my-app').$.dialog.$.alert1
PS: if you are interested there is a selector in the works that lets you pierce the shadow dom for certain “exported” dom parts…
Spec: https://tabatkins.github.io/specs/css-shadow-parts/
Blog Post: https://meowni.ca/posts/part-theme-explainer/
I ended up using a script provided by a colleague that searches the elements in the shadow domes :
(() => {
if (window.DeepShadowDom !== undefined) {
return;
}
const findAll = (selector, root = document) => {
let elements = [ ];
Array.prototype.push.apply(elements, root.querySelectorAll(selector));
Array.prototype.slice.call(root.querySelectorAll('*'))
.filter(e => e.shadowRoot !== null)
.forEach((currentElement, index, array) => {
let candidates = findAll(selector, currentElement.shadowRoot);
Array.prototype.push.apply(elements, candidates);
});
return elements;
};
const find = (selector, root = document) => {
let elements = findAll(selector, document);
if (elements.length > 1) {
throw new Error(`Multiple results returned by selector '${selector}'`);
}
return elements[0];
};
window.DeepShadowDom = { find, findAll };
})();
the element can be then found by selecting DeepshadowDom.Find(selector)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.