[英]java.lang.ClassCastException: com.sun.proxy.$Proxy8 cannot be cast to org.openqa.selenium.internal.WrapsDriver
I have following pointcut and the given advice in 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
}
While the line 1 is executed without any error.虽然第 1 行执行时没有任何错误。 It is on line 2 I get error
在第 2 行我收到错误
java.lang.ClassCastException: com.sun.proxy.$Proxy8 cannot be cast to org.openqa.selenium.internal.WrapsDriver
The casting works in other places without issues.铸造在其他地方工作没有问题。 Can someone please help?
有人可以帮忙吗?
While the answer flagged as correct does point out the issue, it doesn't explain the issue nor suggests a solution which does actually exist.虽然标记为正确的答案确实指出了问题,但它并没有解释问题,也没有提出实际存在的解决方案。 Let me begin with giving a bit more of detail around the underlying issue here which is the way the
WebElement
could have been instantiated.首先让我详细介绍一下这里的潜在问题,即
WebElement
可以实例化的方式。
On one hand, when a WebElement
gets instantiated as the result of a call to WebDriver#findElement
, the actual RemoteWebElement
object gets constructed at that very moment, however, when a WebElement
gets instantiated via PageFactory#initElements
, the actual concrete class object ( RemoteWebElement
) doesn't get created at that point but instead a proxy does.一方面,当
WebElement
作为调用WebDriver#findElement
的结果被实例化时,实际的RemoteWebElement
对象会在那一刻被构造,但是,当WebElement
通过PageFactory#initElements
被实例化时,实际的具体类对象( RemoteWebElement
) 不会在那时创建,而是代理创建。
Here is where the main issue relies.这是主要问题所依赖的地方。 The proxy object does NOT implement the
WrapsDriver
interface and that is why the cast exception is thrown, which is perfectly fine.代理对象不实现
WrapsDriver
接口,这就是抛出WrapsDriver
异常的原因,这很好。 However, if you are curious enough to see how the actual proxy creation is done (at least by the default decorator), you will see that the object instantiated as the proxy does instead implement the WrapsElement
interface which does offer the method getWrappedElement
so, with it, you can extract the underlying WebElement
and then with this, extract the underlying WebDriver
, just as you are trying.但是,如果您对实际代理创建是如何完成的(至少通过默认装饰器)感到好奇,您将看到作为代理实例化的对象确实实现了
WrapsElement
接口,该接口确实提供了getWrappedElement
方法,因此,它,您可以提取底层WebElement
,然后使用此方法提取底层WebDriver
,就像您正在尝试一样。
Now, the key here is that any WebElement
instantiated via WebDriver#findElement
does not implement WrapsElement
because it is the actual element and not a proxy so, before you attempt using WrapsElement#getWrappedElement
, you first need to check if the passed WebElement
is actually a proxy or not.现在,这里的关键是任何通过
WebDriver#findElement
实例化的WebElement
都不会实现WrapsElement
因为它是实际元素而不是代理,因此,在尝试使用WrapsElement#getWrappedElement
,首先需要检查传递的WebElement
是否实际上是一个代理与否。
You can achieve this with reflection, ie你可以通过反射来实现这一点,即
if(WrapsElement.class.isAssignableFrom(element.getClass()))
webDriver = ((WrapsDriver)((WrapsElement)element).getWrappedElement()).getWrappedDriver();
else
webDriver = ((WrapsDriver)element).getWrappedDriver();
tl;dr The WebElement
instance you are using was instantiated via PageFactory#initElements
and you first need to extract the underlying WebElement
with WrapsElement#getWrappedElement
and then the WebDriver
from it. tl;dr 您正在使用的
WebElement
实例是通过PageFactory#initElements
实例化的,您首先需要使用WrapsElement#getWrappedElement
提取底层WebElement
,然后从中提取WebDriver
。
This is a wild guess since I don't see a case where it actually worked.这是一个疯狂的猜测,因为我没有看到它实际起作用的案例。 From the exception it seems that the WebElement that is being passed to
afterWebElementAction
is initialized via PageFactory
.从异常似乎正在传递到WebElement
afterWebElementAction
通过初始化PageFactory
。 My guess is that if you pass WebElement derived from driver.findElement(), to afterWebElementAction
, you wouldn't get casting exception.我的猜测是,如果您将从 driver.findElement() 派生的 WebElement 传递给
afterWebElementAction
,您将不会遇到强制转换异常。 This is how it must be working for you in other cases most likely.这就是它在其他情况下最有可能为您工作的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.