我在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
铸造在其他地方无问题。 有人可以帮忙吗?
答案 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
,则不会产生转换异常。这是最有可能在其他情况下必须为您工作的方式。