appium / appium/java-client

IllegalArgumentException when running parallel execution

Open
#1,263 2 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

Description

When trying to run my mobile tests in parallel with TestNGCucumberRunner I get an
java.lang.IllegalArgumentException: Can not set io.appium.java_client.MobileElement

Is this is a bug or am I doing something wrong here?

The error is thrown when calling PageFactory.initElements(...):

public BasePage(AppiumDriver driver, WebDriverWait wait) {
        this.driver = driver;
        this.wait = wait;
        PageFactory.initElements(new AppiumFieldDecorator(driver, Duration.ofSeconds(10)), this);
    }

Exception:

java.lang.IllegalArgumentException: Can not set io.appium.java_client.MobileElement field ba.woop.automation.pages.LandingPage.itsBanking to org.openqa.selenium.remote.RemoteWebElement$$EnhancerByCGLIB$$d27c0df4
        at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
        at java.base/java.lang.reflect.Field.set(Field.java:780)
        at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:117)
        at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:105)
        at ba.woop.automation.BasePage.<init>(BasePage.java:35)
        at ba.woop.automation.pages.LandingPage.<init>(LandingPage.java:30)
        at ba.klika.automation.steps.LoginCheckSteps.<init>(LoginCheckSteps.java:13)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
        at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
        at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
        at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
        at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
        at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
        at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
        at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
        at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
        at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
        at io.cucumber.picocontainer.PicoFactory.getInstance(PicoFactory.java:42)
        at cucumber.runtime.java.ObjectFactoryLoader$ObjectFactoryAdapter.getInstance(ObjectFactoryLoader.java:157)
        at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:57)
        at cucumber.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:50)
        at cucumber.runner.TestStep.executeStep(TestStep.java:65)
        at cucumber.runner.TestStep.run(TestStep.java:50)
        at cucumber.runner.PickleStepTestStep.run(PickleStepTestStep.java:43)
        at cucumber.runner.TestCase.run(TestCase.java:46)
        at cucumber.runner.Runner.runPickle(Runner.java:50)
        at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:79)
        at ba.woop.automation.runners.LoginCheckRunner.runScenario(LoginCheckRunner.java:36)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
        at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
        at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:71)
        at org.testng.internal.TestMethodWithDataProviderMethodWorker.call(TestMethodWithDataProviderMethodWorker.java:14)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
        at ?.the user clicks on LOGIN button on LANDING PAGE(file:src/test/resources/features/loginCheck.feature:3)

For handling static drivers in parallel execution I have my own class:

public class LocalDriverManager {
    private static ThreadLocal<AppiumDriver> localDriver = new ThreadLocal<>();

    public static AppiumDriver getDriver() {
        return localDriver.get();
    }

    static void setDriver(AppiumDriver driver) {
        localDriver.set(driver);
    }

    public static ThreadLocal<AppiumDriver> getLocalDriver() {
        return localDriver;
    }
}

and I set the the localDriver variable during driver initialization like this:

if (capabilities.getPlatform().is(Platform.IOS)) {
            driver = new IOSDriver<MobileElement>(new URL(urlStart + appiumServer.getPort() + "/wd/hub"),
                    capabilities);
        } else {
            driver = new AndroidDriver<MobileElement>(
                    new URL(urlStart + appiumServer.getPort() + "/wd/hub"),
                    capabilities);
        }
        LocalDriverManager.setDriver(driver);

Environment

  • 'io.appium', name: 'java-client', version: '6.0.0'
  • Node.js v12.10.0
  • Android
  • Real device, Samsung S8 and Huawei P20

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 at PageFactory.initElements(...) in BasePage and inspect AppiumFieldDecorator behavior with the MobileElement field shown in LandingPage. Reproduce the failure using the reported Java-client 6.0.0 setup and parallel TestNGCucumberRunner execution; done means establishing whether the binding or the parallel driver setup causes the incompatible field assignment.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
mobile-dev, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.