Selenium+Kotlin+PageFactory:WebElement列表初始化失败问题
Kotlin + Selenium PageFactory 初始化List报错原因及解决方法
问题原因
核心问题出在Java反射的类型擦除和Kotlin lateinit的特性冲突上:
- Selenium PageFactory基于Java反射实现,处理Kotlin的
List<WebElement>字段时,由于泛型类型擦除,无法获取到泛型参数WebElement的具体类型,导致无法创建对应的延迟加载代理对象,因此没有给lateinit修饰的列表字段赋值,触发UninitializedPropertyAccessException。 - 单个
WebElement字段能正常工作,是因为字段的直接类型就是WebElement,PageFactory可以直接识别并创建代理对象完成赋值。
另外,你改用可空类型能运行,是因为可空变量默认被赋值为null,即使PageFactory没完成初始化,也不会触发未初始化异常;而lateinit要求变量必须被显式赋值为非null实例,所以当PageFactory无法完成赋值时就会报错。
解决方法
方法一:添加@JvmField注解
给列表字段加上@JvmField,让Kotlin将该字段暴露为Java风格的字段,帮助PageFactory正确识别泛型类型:
@JvmField @FindBy(css = "timeline-instances [data-e2e-selector=inst]") lateinit var timelineInst: List<WebElement>
方法二:改用MutableList类型
部分场景下,PageFactory对可变列表的泛型识别更友好,可将字段类型改为MutableList<WebElement>:
@FindBy(css = "timeline-instances [data-e2e-selector=inst]") lateinit var timelineInst: MutableList<WebElement>
方法三:手动初始化(绕开PageFactory懒加载)
如果不需要PageFactory的延迟加载特性,可直接通过驱动手动查找元素初始化列表:
val timelineInst: List<WebElement> get() = driver.findElements(By.cssSelector("timeline-instances [data-e2e-selector=inst]"))
内容的提问来源于stack exchange,提问作者kakemonsteret
相关产品推荐
相关产品推荐

