appium / appium/java-client

clarification request: pure selenium's WebDriverDecorator doesn't work with AppiumFieldDecorator - is RemoteWebElement the issue?

Open
#2,368 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.3k
Forks
752
Avg merge
6d 21h
Merged PRs (30d)
8

Description

Hi appium team!
I was experimenting with selenium's WebDriverDecorator (to decorate WebElement that auto-waits for conditions like clickable&editable&non-readOnly etc), but found out that pure selenium's WebDriverDecorator does not work with AppiumFieldDecorator. I believe this is because WebDriverDecorator creates proxy for WebElement , but AppiumFieldDecorator uses proxies for RemoteWebElement which makes invoking the original element's methods failing. Here is the code to reproduce the exception:

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
// other imports

class SeleniumDecoratorTest {

    @Test
    void seleniumDecoratorDecorates() {
        WebDriver originalDriver = mock(WebDriver.class);
        WebElement originalWebElement = mock(WebElement.class);
        when(originalDriver.findElement(any())).thenReturn(originalWebElement);

        WebDriver decoratedWebDriver = new EventFiringDecorator<>().decorate(originalDriver); // do-nothing decorator, but creates selenium's WebElement decorator/proxy : https://github.com/SeleniumHQ/selenium/blob/1c58e5028bc5eaa94b12b856c2d4a87efa5363f5/java/src/org/openqa/selenium/support/decorators/WebDriverDecorator.java#L331
        MobilePageObject mobilePageObject = new MobilePageObject();

        PageFactory.initElements(new AppiumFieldDecorator(decoratedWebDriver), mobilePageObject);
        mobilePageObject.element.click(); // this fails. likely because the underlying object is expected to be RemoteWebElement: https://github.com/appium/java-client/blob/0b4a430f8e76f48ba166c77a35ab2bd696620741/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java#L258

        verify(originalWebElement).click(); // verify that the original WebElement was clicked
    }

    static class MobilePageObject {
        @AndroidFindBy(id = "some_id")
        WebElement element;
    }
}

Exception stacktrace is:

object is not an instance of declaring class
java.lang.IllegalArgumentException: object is not an instance of declaring class
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.checkReceiver(DirectMethodHandleAccessor.java:197)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:99)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at io.appium.java_client.pagefactory.ElementInterceptor.getObject(ElementInterceptor.java:42)
	at io.appium.java_client.pagefactory.interceptors.InterceptorOfASingleElement.call(InterceptorOfASingleElement.java:78)
	at io.appium.java_client.proxy.Interceptor.intercept(Interceptor.java:78)
	at org.openqa.selenium.remote.RemoteWebElement$ByteBuddy$SGYRx3lC.click(Unknown Source)
	at io.appium.java_client.pagefactory_tests.SeleniumDecoratorTest.seleniumDecoratorDecorates(SeleniumDecoratorTest.java:27)

versions info : appium-java v10.0.0, (no appium server used - mocked drivers only)

Question: (assuming mismatch of WebElement and RemoteWebElement proxies causes this issue) What is the reason Appium uses RemoteWebElement proxy and not WebElement? I need some hints to understand if using selenium's decorator still possible in theory or not.

Thanks!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproducing SeleniumDecoratorTest example, then read AppiumFieldDecorator.java at the referenced proxy handling and ElementInterceptor.java from the stack trace. Compare the WebElement and RemoteWebElement proxy assumptions and determine whether compatibility is feasible; the issue is done only when the expected behavior and any required change are established with a test or documented conclusion.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
mobile, testing
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.