Appium Example - Java

Link to Appium Example - Java copied to clipboard

The following Appium example is written in Java and assumes the use of Appium's java-client. The logic is transferable to other clients.

important

Before running the Appium test, ensure the apk being passed into Appium runs axe DevTools on the screens you want to test with. The purple floating action button should be displayed within your app.

Setup

Not using Maven Project? View the setup portion of the Kotlin Appium example.

pom.xml file:

<?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.deque.android.example</groupId>
    <artifactId>Java8App</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>mavenCentral</id>
            <url>https://repo1.maven.org/maven2/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.deque.android</groupId>
            <artifactId>axe-devtools-android-results</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>com.deque.android</groupId>
            <artifactId>axe-devtools-android-core</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>io.appium</groupId>
            <artifactId>java-client</artifactId>
            <version>8.1.1</version>
        </dependency>
    </dependencies>
</project>

Full Example

import com.deque.axe.android.constants.AxeStatus;
import com.deque.mobile.auth.AccessToken;
import com.deque.mobile.auth.ApiKey;
import com.deque.mobile.devtools.AccessTokenClient;
import com.deque.mobile.devtools.ApiKeyClient;
import com.deque.mobile.devtools.AxeDevToolsClient;
import com.deque.mobile.devtools.serializable.AxeDevToolsResult;
import com.deque.mobile.devtools.serializable.AxeDevToolsResultKey;
import com.deque.mobile.devtools.serializable.TagsSet;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.remote.MobilePlatform;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;

public class AppiumTest {

    AxeDevToolsClient client;
    AccessToken accessToken;

    AndroidDriver driver;

    AndroidDriver makeDriver() throws MalformedURLException {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
        capabilities.setCapability(MobileCapabilityType.APP, new File("/file/path/to/apk").getAbsolutePath());
        capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
        capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);

        String DEFAULT_APPIUM_ADDRESS = "http://0.0.0.0:4723/wd/hub";
        return new AndroidDriver(new URL(DEFAULT_APPIUM_ADDRESS), capabilities);
    }

    @Before
    public void setup() throws MalformedURLException {
        String username = "";
        String password = "";
        ApiKey apiKey = new ApiKey("");

        if (!username.isEmpty() || !password.isEmpty()) {
            accessToken = new AccessToken(
                    username,
                    password,
                    AccessToken.DEFAULT_URL,
                    AxeDevToolsClient.DEFAULT_REALM
            ).fetchSync();

            client = new AccessTokenClient(accessToken, AxeDevToolsClient.DB_DEFAULT_URL);
        } else {
            client = new ApiKeyClient(apiKey, AxeDevToolsClient.DB_DEFAULT_URL);
        }

        driver = makeDriver();
    }

    @Test
    public void test() {
        AxeDevToolsResult result = a11yResult();

        setScanName(result.getAxeDevToolsResultKey(), "Appium Test");
        tagResult(result.getAxeDevToolsResultKey(), "Appium");

        result.getAxeResult().axeRuleResults.forEach((axeResult) -> {
            if (axeResult.status.equals(AxeStatus.FAIL)) {
                System.out.println(axeResult.toString());
            }
        });

        // optionally delete a result
        // deleteResult(result.getAxeDevToolsResultKey());
    }

    private AxeDevToolsResult a11yResult() {
        driver.findElement(
                new AppiumBy.ByAndroidUIAutomator("description(\"Axe\")")
        ).click();

        WebDriverWait webDriverWait = new WebDriverWait(driver, Duration.ofSeconds(10));
        webDriverWait.until((ExpectedCondition<Boolean>) input -> {
            if (input != null) {
                input.findElement(AppiumBy.id("result_key_container"));
            }
            return true;
        });

        String resultKey = driver.findElement(
                AppiumBy.id("result_key_container")
        ).getAttribute("content-desc");

        return client.getResultSync(AxeDevToolsResultKey.fromPath(resultKey));
    }

    private void setScanName(AxeDevToolsResultKey resultKey, String scanName) {
        client.setScanNameSync(resultKey, scanName);
    }

    private void tagResult(AxeDevToolsResultKey resultKey, String tag) {
        client.tagSync(resultKey, new TagsSet(tag));
    }

    private void deleteResult(AxeDevToolsResultKey resultKey) {
        client.deleteResultSync(resultKey);
    }
}