You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Selenium 3中,如何在JavaScript中正确转换Object为WebElement/SearchContext?

Selenium v3 ShadowRoot类型转换报错解决方法

问题说明

在Java中通过(SearchContext)或(WebElement)强转JavascriptExecutor.executeScript返回的ShadowRoot对象可正常使用,但在使用as SearchContext(注:此处应为Kotlin语法,用户误标注为JavaScript)转换时,抛出异常:

Caused by: java.lang.ClassCastException: com.google.common.collect.Maps$TransformedEntriesMap cannot be cast to org.openqa.selenium.SearchContext

受限于Selenium v3版本,无法使用getShadowRoot()方法。

可行的Java代码

WebElement webElemHost = browser.findElement(By.xpath("//tagHere[@id='idHere']"));
String strCSSSelector = "#idHere";
JavascriptExecutor js = (JavascriptExecutor) browser;
SearchContext shadowRoot = (SearchContext) js.executeScript("return arguments[0].shadowRoot", webElemHost);
WebElement shadowContent = shadowRoot.findElement(By.cssSelector(strCSSSelector));

报错代码(用户误标注为JavaScript,实际为Kotlin)

val webElemHost = browser.findElement(By.xpath("//tagHere[@id='idHere']"))
val strCSSSelector = "#idHere"
val js = browser as JavascriptExecutor
val shadowRoot = js.executeScript("return arguments[0].shadowRoot", webElemHost) as SearchContext // 报错行
val shadowContent = shadowRoot.findElement(By.cssSelector(strCSSSelector))

原因分析

Selenium v3中,executeScript返回的ShadowRoot对象在JVM层面实际是TransformedEntriesMap类型,并非真正的SearchContext实例。Java的强转能生效是因为运行时允许隐式适配,但Kotlin的as转换会严格校验类型,因此抛出类型转换异常。

解决方案

方案1:直接通过JavaScript完成元素查找(推荐)

跳过类型转换,直接在executeScript中借助ShadowRoot查找元素,代码简洁且稳定:

val webElemHost = browser.findElement(By.xpath("//tagHere[@id='idHere']"))
val strCSSSelector = "#idHere"
val js = browser as JavascriptExecutor
val shadowContent = js.executeScript(
    "return arguments[0].shadowRoot.querySelector(arguments[1])",
    webElemHost,
    strCSSSelector
) as WebElement

方案2:手动包装为SearchContext(不推荐)

若必须使用SearchContext的findElement方法,可借助Selenium内部类将返回的Map包装为ShadowRoot实例(依赖内部实现,存在兼容性风险):

import org.openqa.selenium.remote.RemoteWebElement
import org.openqa.selenium.remote.ShadowRoot

val webElemHost = browser.findElement(By.xpath("//tagHere[@id='idHere']"))
val strCSSSelector = "#idHere"
val js = browser as JavascriptExecutor
val shadowRootMap = js.executeScript("return arguments[0].shadowRoot", webElemHost) as Map<*, *>
val shadowRoot = ShadowRoot((webElemHost as RemoteWebElement).getWrappedDriver(), shadowRootMap)
val shadowContent = shadowRoot.findElement(By.cssSelector(strCSSSelector))

内容的提问来源于stack exchange,提问作者PQ Co

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:24:52