java.lang.ClassCastException:com.sun.proxy。$ Proxy8无法强制转换为org.openqa.selenium.internal.WrapsDriver

时间:2013-08-13 10:23:11

标签: java webdriver aspectj

我在AspectJ中有以下切入点和给定的建议

@Pointcut("(call(* org.openqa.selenium.WebElement.sendKeys(..)))")
    public void onWebElementAction() {
}

@After("onWebElementAction() && target(webelement)")
public void afterWebElementAction(JoinPoint joinPoint, WebElement webelement) {
    System.out.println(webelement.getAttribute("name")); //1
    WebDriver driver = ((WrapsDriver) webelement).getWrappedDriver(); //2
    //DO SOMETHING HERE
}

执行第1行时没有任何错误。它在第2行我得到错误

java.lang.ClassCastException: com.sun.proxy.$Proxy8 cannot be cast to org.openqa.selenium.internal.WrapsDriver

铸造在其他地方无问题。 有人可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

虽然标记为正确的答案确实指出了问题,但它没有解释问题,也没有提出确实存在的解决方案。让我首先介绍一下基础问题的更多细节,这是WebElement可以实例化的方式。

一方面,当WebElement作为调用WebDriver#findElement的结果而被实例化时,实际的RemoteWebElement对象在那个时刻被构造,但是,当WebElement 1}}通过PageFactory#initElements实例化,实际的具体类对象(RemoteWebElement)不会在那时创建,而是由代理创建。

这是主要问题依赖的地方。代理对象没有实现WrapsDriver接口,这就是抛出强制转换异常的原因。但是,如果您好奇地看到实际的代理创建是如何完成的(至少是默认的装饰器),您将看到实例化为代理的对象改为实现提供该方法的WrapsElement接口getWrappedElement因此,使用它,您可以提取基础WebElement,然后使用此提取基础WebDriver,就像您尝试一样。

现在,关键是通过WebElement实例化的任何WebDriver#findElement都没有实现WrapsElement,因为它是实际的元素而不是代理,因此,在您尝试使用{{1}之前首先,您需要检查传递的WrapsElement#getWrappedElement是否实际上是代理。

你可以通过反思实现这一点,即

WebElement

TL;博士 您正在使用的if(WrapsElement.class.isAssignableFrom(element.getClass())) webDriver = ((WrapsDriver)((WrapsElement)element).getWrappedElement()).getWrappedDriver(); else webDriver = ((WrapsDriver)element).getWrappedDriver(); 实例已通过WebElement进行实例化,您首先需要使用PageFactory#initElements提取基础WebElement,然后从中提取WrapsElement#getWrappedElement

答案 1 :(得分:1)

这是一个疯狂的猜测,因为我没有看到它实际工作的情况。从异常看来,传递给afterWebElementAction的WebElement似乎是通过PageFactory初始化的。我的猜测是,如果将从Driver.findElement()派生的WebElement传递给afterWebElementAction,则不会产生转换异常。这是最有可能在其他情况下必须为您工作的方式。