Seems that ShadowDOM support is still missing:
Background
I am working with some Polymer 2 components which implements ShadowDOM v1 spec and I need to select elements inside their shadowRoots to run e2e tests. deepCss might be a solution but it doesn't work for me. As far as I can see, by.deepCss is nothing special difference with by.css but appending * /deep/ at the beginning of the given CSS selector, however, /deep/ seems deprecated on the browser.
I am working with the following versions:
- Node Version:
v6.10.3
- Protractor Version:
v5.1.2
- Angular Version:
v4.2.4
- Browser(s):
Chrome
- Operating System and Version:
Ubuntu v16.04.2 AMD64 LTS Xenial
I think I checked all relevant articles including the followings and I couldn't get any satisfied answer:
Workaround
Anyway, I can select inner elements of ShadowDOM elements by adding a custom locator. Here is my workaround:
/**
* Usage:
* O element(by.css_sr('#parentElement #innerElement')) <=> $('#parentElement #innerElement')
* O element(by.css_sr('#parentElement::sr #innerElement')) <=> $('#parentElement').shadowRoot.$('#innerElement')
* O element.all(by.css_sr('#parentElement .inner-element')) <=> $$('#parentElement .inner-element')
* O element.all(by.css_sr('#parentElement::sr .inner-element')) <=> $$('#parentElement').shadowRoot.$$('.inner-element')
* O parentElement.element(by.css_sr('#innerElement')) <=> parentElement.$('#innerElement')
* O parentElement.element(by.css_sr('::sr #innerElement')) <=> parentElement.shadowRoot.$('#innerElement')
* O parentElement.all(by.css_sr('.inner-element')) <=> parentElement.$$('.inner-element')
* O parentElement.all(by.css_sr('::sr .inner-element')) <=> parentElement.shadowRoot.$$('.inner-element')
*/
by.addLocator('css_sr', (cssSelector: string, opt_parentElement, opt_rootSelector) => {
let selectors = cssSelector.split('::sr');
if (selectors.length === 0) {
return [];
}
let shadowDomInUse = (document.head.createShadowRoot || document.head.attachShadow);
let getShadowRoot = (el) => ((el && shadowDomInUse) ? el.shadowRoot : el);
let findAllMatches = (selector: string, targets: any[], firstTry: boolean) => {
let using, i, matches = [];
for (i = 0; i < targets.length; ++i) {
using = (firstTry) ? targets[i] : getShadowRoot(targets[i]);
if (using) {
if (selector === '') {
matches.push(using);
} else {
Array.prototype.push.apply(matches, using.querySelectorAll(selector));
}
}
}
return matches;
};
let matches = findAllMatches(selectors.shift().trim(), [opt_parentElement || document], true);
while (selectors.length > 0 && matches.length > 0) {
matches = findAllMatches(selectors.shift().trim(), matches, false);
}
return matches;
});
Conclusion
Since the workaround works on my side, so I am asking~ is there anything I missed or I misused the background principle of Protractor in my workaround? I am politely saying ... if I don't violate your certain rules too much, is it possible to add ShadowDOM support something like that into the next update of Protractor?
Thank you.
Seems that ShadowDOM support is still missing:
Background
I am working with some Polymer 2 components which implements ShadowDOM v1 spec and I need to select elements inside their
shadowRoots to run e2e tests.deepCssmight be a solution but it doesn't work for me. As far as I can see,by.deepCssis nothing special difference withby.cssbut appending* /deep/at the beginning of the given CSS selector, however,/deep/seems deprecated on the browser.I am working with the following versions:
v6.10.3v5.1.2v4.2.4ChromeUbuntu v16.04.2 AMD64 LTS XenialI think I checked all relevant articles including the followings and I couldn't get any satisfied answer:
Workaround
Anyway, I can select inner elements of ShadowDOM elements by adding a custom locator. Here is my workaround:
Conclusion
Since the workaround works on my side, so I am asking~ is there anything I missed or I misused the background principle of Protractor in my workaround? I am politely saying ... if I don't violate your certain rules too much, is it possible to add ShadowDOM support something like that into the next update of Protractor?
Thank you.