selenium-webdriverselenium-chromedriverserenity-bddtestautomationfx

ClassCastException with WebElement in Serenity Screenplay project (Chrome Browser)


I am trying to run a Serenity Screenplay suite on latest Chrome Browser. In this suite I have a testcase to validate a Dropdown field which is inside a Shadow Root and for this reason I am using JavascriptExecutor and the code looks like:

WebDriver driver = actor.usingAbilityTo(BrowseTheWeb.class).getDriver();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        WebElement shadowHost = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#theEmbed")));
        JavascriptExecutor jse = (JavascriptExecutor) driver;
            WebElement shadowR = (WebElement) jse.executeScript("return arguments[0].shadowRoot", shadowHost);
            WebElement dropdown = shadowR.findElement(By.xpath("//*[@data-testid='field-block__column-count-1']//div//div//select"));
            dropdown.isDisplayed();

When running this code on Chrome Browser it gives this error:

java.lang.ClassCastException: class org.openqa.selenium.remote.ShadowRoot cannot be cast to class org.openqa.selenium.WebElement (org.openqa.selenium.remote.ShadowRoot and org.openqa.selenium.WebElement are in unnamed module of loader 'app')

To solve this error I am replacing the Cast 'WebElement' to 'SearchContext' like:

SearchContext shadowR = (SearchContext) jse.executeScript("return arguments[0].shadowRoot", shadowHost);

but then it gives this error:

org.openqa.selenium.InvalidArgumentException: invalid argument: invalid locator

HTML body of Shadow Root looks like: enter image description here

Does anyone encounter this situation/error? Any suggestions on how to tackle this issue? I am using Chrome Browser version: 115.0.5790.102 with Chromedriver version: 114.0.5735.90


Solution

  • By parsing shadowR as List WebElement it works fine

    WebDriver driver = actor.usingAbilityTo(BrowseTheWeb.class).getDriver();
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            WebElement shadowHost = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#theEmbed")));
            JavascriptExecutor jse = (JavascriptExecutor) driver;
                WebElement shadowR = (WebElement) jse.executeScript("return arguments[0].shadowRoot.children", shadowHost);
                WebElement dropdown = shadowR.findElement(By.cssSelector("[data-testid='field-block__column-count-1'] select"));
                dropdown.isDisplayed();