you will not be able to use xpath with shadowroots, since xpath is applied to DOM
Here, you can pull back all the elements, then use css or other to check if text exists, eg (use driver instead of session, since I wrap my driver):
public static String getAllShadowRootsText(DriverSessions session, String rootNode)
{
String elsText = "";
try {
List<SearchContext> sroots = getAllShadowRoots(session, rootNode);
for(SearchContext sroot : sroots){
// we have to specify the elements with shadowroot children, we cant just get all *
List<WebElement> els = sroot.findElements(By.cssSelector(validDomTypes));
for(WebElement el : els) {
elsText = elsText + el.getText();
}
}
}
catch (Exception e) {} // we might want to loop this, pages change and shadow roots move / go stale
return elsText;
}
public static List<SearchContext> getAllShadowRoots(DriverSessions session, String rootNode)
{
String script = ""
+ "function getShadowRoots (node, sroots, func) { "
+ "var done = func(node); "
+ "if (done) {return true;} "
+ "if ('shadowRoot' in node && node.shadowRoot) { "
+ "sroots.push(node.shadowRoot); "
+ "var done = getShadowRoots(node.shadowRoot, sroots, func); "
+ "if (done) {return true;} "
+ "} "
+ "node = node.firstChild; "
+ "while (node) { "
+ "var done = getShadowRoots(node, sroots, func); "
+ "if (done) {return true;} "
+ "node = node.nextSibling; "
+ "} "
+ "} "
+ "try { "
+ "sroots = new Array(); "
+ "getShadowRoots("+rootNode+", sroots, function (node, sroots) {}); "
+ "return sroots;"
+ "} "
+ "catch(err){return null};";
JavascriptExecutor js = (JavascriptExecutor)session.getDriver();
@SuppressWarnings("unchecked")
List<SearchContext> els = (List<SearchContext>) js.executeScript(script);
return els;
}