selenium: [🐛 Bug]: Confusing JAVA API documentation, failed to cast org.openqa.selenium.remote.ShadowRoot

What happened?

With Chrome 96 update, our tests broke because of shadow DOM handling. I have tried to update selenium from v3.141.59 to v4.0.0 and this also breaks the code. I can solve it and it’s fine but I don’t understand. In the documentation I can’t find the definition of this class. I have found the new getShadowRoot() method in the documentation. The problem is that from the code this method is only available from RemoteWebElement. Simple WebElement doesn’t implement this method in the code, but the documentation still contains it. Furthermore, in the documentation the getShadowRoot method returns SearchContext and not ShadowRoot… Which documentation should I use? Previously the attached code worked fine.

How can we reproduce the issue?

private static ExpectedCondition<WebElement> jsReturnsShadowRoot(WebElement parent) {
      return new ExpectedCondition<WebElement>() {
          @Override
          public WebElement apply(WebDriver driver) {
              return (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", parent);
          }
      };
  }

Relevant log output

org.openqa.selenium.remote.ShadowRoot cannot be cast to org.openqa.selenium.WebElement
java.lang.ClassCastException: org.openqa.selenium.remote.ShadowRoot cannot be cast to org.openqa.selenium.WebElement

Operating System

Windows 10

Selenium version

Java 4.0.0

What are the browser(s) and version(s) where you see this issue?

Chrome v96.0.4664.45

What are the browser driver(s) and version(s) where you see this issue?

chromedriver v96.0.4664.45

Are you using Selenium Grid?

No response

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 28 (9 by maintainers)

Most upvoted comments

@titusfortner Thank you very much for your solution. This works with Selenium 3.14.x.

Based on our needs at the moment to temporarily support both ChromeDriver 95 and 96 with Selenium 3, here’s the workaround based on your solution:


    public WebElement expandRootElement(WebElement shadowHost) {
        WebElement returnObj = null;
        Object shadowRoot = ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot", shadowHost);
        if (shadowRoot instanceof WebElement) {
            // ChromeDriver 95
            returnObj = (WebElement) shadowRoot;
        }
        else if (shadowRoot instanceof Map)  {
            // ChromeDriver 96+
            // Based on https://github.com/SeleniumHQ/selenium/issues/10050#issuecomment-974231601
            Map<String, Object> shadowRootMap = (Map<String, Object>) shadowRoot;
            String shadowRootKey = (String) shadowRootMap.keySet().toArray()[0];
            String id = (String) shadowRootMap.get(shadowRootKey);
            RemoteWebElement remoteWebElement = new RemoteWebElement();
            remoteWebElement.setParent((RemoteWebDriver) driver);
            remoteWebElement.setId(id);
            returnObj = remoteWebElement;
        }
        else {
            Assert.fail("Unexpected return type for shadowRoot in expandRootElement()");
        }
        return returnObj;
    }

omg, i’m so stupid, This is the solution at the time: is working when i change “shadowRoot” from “WebElement” to “SearchContext”, also in the javascript-executor https://bugs.chromium.org/p/chromedriver/issues/detail?id=3958

WebElement shadowHost = seleniumWebDriver.findElement(By.cssSelector(“#shadowrootcontainer”)); JavascriptExecutor javascriptExecutor = (JavascriptExecutor) seleniumWebDriver; SearchContext shadowRoot = (SearchContext) javascriptExecutor.executeScript(“return arguments[0].shadowRoot”, shadowHost); WebElement shadowContent = shadowRoot.findElement(By.cssSelector(“#shadowcontentcss”));

thats it ;D greats and thx titusfortner and sorry for my delay ^^