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

Selenium Java/Kotlin混用时JavascriptExecutor报类转换异常问题

问题背景

现有基于Selenium、Cucumber搭建的测试框架,大部分测试步骤定义采用Java编写,当前正在逐步将代码迁移至Kotlin,新增工具类统一使用Kotlin开发。

初始可正常运行的代码

初始版本SeleniumUtils.kt仅实现了判断页面元素是否存在的方法,代码如下:

import no.our.e2e.framework.selenium.Browser
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor

object SeleniumUtils {
  fun elementExistsOnPage(idSelector: String?): Boolean {
      return Browser.extendedDriver().findElements(By.id(idSelector)).size > 0
  }
}

该方法可在Java编写的步骤定义文件中正常调用,调用示例:

@When("^jeg go to the contakt page$")
public void goToContaktPage() throws InterruptedException {
    if (SeleniumUtils.INSTANCE.elementExistsOnPage("messageDraftLink")) {
        goToContaktPageViaMessagebox();
    } else {
        navigationPage.contakt.click();
    }
}    
新增方法后的运行异常

在SeleniumUtils.kt中新增基于JavascriptExecutor实现的页面滚动至顶部方法后,代码如下:

import no.our.e2e.framework.selenium.Browser
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor

object SeleniumUtils {
  fun elementExistsOnPage(idSelector: String?): Boolean {
      return Browser.extendedDriver().findElements(By.id(idSelector)).size > 0
  }

  fun scrollPage() {
      (Browser.extendedDriver() as JavascriptExecutor)
        .executeScript("window.scrollTo(0, -document.body.scrollHeight)")
  }
}

在步骤定义中调用scrollPage()方法时抛出如下异常:

java.lang.ClassCastException: class 
no.our.e2e.framework.selenium.driver.ExtendedWebDriver cannot be cast to class 
org.openqa.selenium.JavascriptExecutor  
(no.our.e2e.framework.selenium.driver.ExtendedWebDriver and 
org.openqa.selenium.JavascriptExecutor are in unnamed module of loader 'app')
问题原因

该异常与Kotlin、Java混合编译无直接关联,属于Selenium依赖版本冲突导致的类型不匹配问题:

  • ExtendedWebDriver在编译时依赖的Selenium版本,与运行时classpath中实际加载的Selenium API版本不一致,导致运行时识别到的ExtendedWebDriver类未实现同路径下的JavascriptExecutor接口,触发类型强转失败。
  • 初始版本的方法未触发异常,是因为elementExistsOnPage仅使用了WebDriver基础接口、By定位器等核心类,没有涉及JavascriptExecutor的类型强转,因此没有暴露依赖冲突问题,问题恰好出现在Kotlin迁移阶段属于时间上的巧合。
  • Kotlin中的类型强转逻辑与Java完全一致,编译后同样会生成checkcast字节码指令,不存在混编场景下特殊的强转逻辑差异。
解决方案
  • 统一全项目Selenium依赖版本:使用mvn dependency:tree(Maven项目)或gradle dependencies(Gradle项目)排查所有传递引入的Selenium依赖,排除版本不一致的selenium-api、selenium-remote-driver包,保证ExtendedWebDriver编译时使用的Selenium版本与运行时加载的版本完全一致。
  • 优化滚动方法实现,增加类型判断兜底,同时修正滚动到顶部的JS脚本逻辑(原脚本使用负scrollHeight参数存在逻辑问题,滚动到顶部的正确坐标为(0,0)),优化后代码:
import org.openqa.selenium.Keys

fun scrollPage() {
    val driver = Browser.extendedDriver()
    if (driver is JavascriptExecutor) {
        driver.executeScript("window.scrollTo(0, 0);")
        return
    }
    // 非JS执行器环境兜底:用快捷键滚动到顶部
    driver.findElement(By.tagName("body")).sendKeys(Keys.CONTROL, Keys.HOME)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:03:24