Error while initializing Appium AndroidDriver

I’m creating a new test framework from scratch using Spring Boot 2 and Appium. To write the tests I’m using JUnit which is already included in Spring Boot’s spring-boot-starter-test POM along with many others. I added Appium to my POM and it now looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.automationexperiment</groupId>
    <artifactId>one</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.appium/java-client -->
        <dependency>
            <groupId>io.appium</groupId>
            <artifactId>java-client</artifactId>
            <version>6.1.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

As for my tests, I have a DriverSetup class that looks like this:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DriverSetup {

  protected AndroidDriver<AndroidElement> driver;

  @Before
  public void setUp() throws MalformedURLException {
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
    capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "6.0.1");
    capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "DeviceName");
    capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.google.android.gm");
    capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".ConversationListActivityGmail");
    URL myUrl = new URL("http://127.0.0.1:4723/wd/hub");
    this.driver = new AndroidDriver<AndroidElement>(myUrl, capabilities);
    this.driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
  }
}

Finally, I have another class that extends from DriverSetup to make sure driver initialization is done before every test. It looks like this:

@RunWith(SpringRunner.class)
@SpringBootTest
public class FirstTryTest extends DriverSetup {

  public FirstTryTest() { }

  @Test
  public void test() {
    System.out.println("test");
  }
}

I just want to make sure I can reach the test in my FirstTryTest, but every time the code initializes the AndroidDriver with the URL and the DesiredCapabilities, I get the following error:

java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput;
    at io.appium.java_client.remote.NewAppiumSessionPayload.writeTo(NewAppiumSessionPayload.java:265)
    at io.appium.java_client.remote.AppiumCommandExecutor$1.createSession(AppiumCommandExecutor.java:175)
    at io.appium.java_client.remote.AppiumCommandExecutor.createSession(AppiumCommandExecutor.java:209)
    at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:231)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:601)
    at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
    at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
    at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:219)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:142)
    at io.appium.java_client.DefaultGenericMobileDriver.<init>(DefaultGenericMobileDriver.java:38)
    at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:84)
    at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:94)
    at io.appium.java_client.android.AndroidDriver.<init>(AndroidDriver.java:93)
    at com.automationexperiment.one.driversetup.DriverSetup.setUp(DriverSetup.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at com.microsoft.java.test.runner.JUnit4TestReference.run(JUnit4TestReference.java:51)
    at com.microsoft.java.test.runner.CustomizedJUnitCoreRunner.run(CustomizedJUnitCoreRunner.java:45)
    at com.microsoft.java.test.runner.JUnitLauncher.execute(JUnitLauncher.java:26)
    at com.microsoft.java.test.runner.JUnitLauncher.main(JUnitLauncher.java:15)
    Suppressed: java.io.IOException: Incomplete document
        at com.google.gson.stream.JsonWriter.close(JsonWriter.java:559)
        at org.openqa.selenium.json.JsonOutput.close(JsonOutput.java:39)
        at io.appium.java_client.remote.NewAppiumSessionPayload.writeTo(NewAppiumSessionPayload.java:288)
        ... 41 more

I’ve tried using an older version of Appium (5.0.4) but it didn’t work. I read some information in other forums but none of the answers helped. Some mentioned something about removing JSON libraries to let Selenium use the methods it already has, but that didn’t work either.

For anyone who might run into this issue, the answer for it was answered in StackOverflow. You can find it here

@BrunoAlva

Instead of investing time in creating, maintaining framework just use existing one Serenity BDD I’m using this since last 5 years, it helps with Mobile, Web and API as well

check the sample project