java.lang.ClassCastException: class com.sun.proxy.$Proxy69 cannot be cast to class org.openqa.selenium.remote.RemoteWebElement (com.sun.proxy.$Proxy69 and org.openqa.selenium.remote.RemoteWebElement are in unnamed module of loader 'app')

To locate random element , I following the steps defined here and is working fine except on

public static void scrollToDirection(WebElement webElement, String direction) {
    HashMap<String, Object> parameter = new HashMap<>();
    parameter.put("elementId", ((RemoteWebElement)webElement).getId()); // Here getting issue
    parameter.put("direction", direction);
    parameter.put("percent", 1.0);
    parameter.put("speed", 15000);
    ((JavascriptExecutor) getAppiumDriver()).executeScript(
            "mobile: scrollGesture", parameter

Please guide here.

Very similar question asked in the comments by user Joan.

Authors response:

vInsDecember 31, 2018 at 9:18 PM
Joan, Action.moveToElement expects a WebElement. Wrapped Element is also a WebElement. it should work without any issues. Please try to use a stable version of selenium lib and ensure that it works fine without dynamic proxy. then you can move on to dynamic proxy.

Hi, basically, since you use POM (Page Object Model), each element you use it wrapped by a dynamic proxy (it is a java concept, you can read about it online).
what does the proxy do? each time you call a method on you WebElement instance, instead of operating on the instance itself you call the same method on the proxy instance (it just looks like a regular WebElement), when you call the method, each time the proxy is locating the element with the locator (id, xpath, iOS predicate and so on…) and returns a new and “fresh” element so it should not throw StaleElementReferenceException.
when you try to cast this element you are trying to cast the proxy! and not the element itself.
in order to cast the element itself you need to get it first (note it won’t be wrapped with a proxy anymore) to get the element itself you need to call a method on the WebElement which will return the unwrapped element, if you use appium Widget class you can call .getWrappedElement() but, if you use native WebElement you do not have this method. what I did in order to “unwrap” the WebElement, I just called myWebElement.findElement(By.xpath("//node()")) this will return myWebElement without the proxy wrapping it and it will allow you to cast it as usual (it will behave just as a regular java instance).

the goal of the proxy is to mediate between the instance and the method’s response, it allows you to invoke a method usually named “intercept” which will run before any call on the instance.

1 Like