Appium Example - Kotlin

Link to Appium Example - Kotlin copied to clipboard

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


Before running the Appium test, ensure the apk being passed into Appium runs axe DevTools on the screens you want to test with axe.showA11yFab(activity) and is connected to the dashboard with axe.connect(...). Checkout our guide to setup your app for Appium testing.



plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.5.0'

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    maven { url '' }
    maven { url "" }

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib"
    implementation "junit:junit:4.13.2"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2"
    testImplementation "junit:junit:4.13.1"

    implementation "com.github.appium:java-client:8.1.1"
    implementation "org.seleniumhq.selenium:selenium-java:4.2.1"
    implementation ""
    implementation "com.squareup.okhttp3:okhttp:4.10.0"

Full Example using REST API

import io.appium.java_client.AppiumBy
import io.appium.java_client.remote.AutomationName
import io.appium.java_client.remote.MobileCapabilityType
import io.appium.java_client.remote.MobilePlatform
import okhttp3.OkHttpClient
import okhttp3.Request
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.openqa.selenium.WebDriver
import org.openqa.selenium.remote.DesiredCapabilities
import java.time.Duration

class DemoWithAPIRequest {
    private val client = OkHttpClient()
    private lateinit var driver: AndroidDriver

    private val DEFAULT_APPIUM_ADDRESS = ""
    private val apkFilePath = "/path/to/app.apk"

    private fun makeDriver(): AndroidDriver {
        val capabilities = DesiredCapabilities()
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator")
        capabilities.setCapability(MobileCapabilityType.APP, File(apkFilePath).absolutePath)
        capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID)
        capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2)

        return AndroidDriver(URL(DEFAULT_APPIUM_ADDRESS), capabilities)

    fun setup() {
        driver = makeDriver()

    fun runA11y() {
        // Navigate and Click the FAB

        val webDriverWait = WebDriverWait(driver, Duration.ofSeconds(10))
        webDriverWait.until(ExpectedCondition { input: WebDriver? ->

        // Getting Result Key from the FAB
        val resultKey = driver.findElement(

        // Fetch Rule Results from API
        val apiKey = "your-api-key-here"
        val url = "$resultKey"
        val request = Request.Builder()
            .addHeader("X-Api-Key", apiKey)
            .addHeader("Content-Type", "application/json")

        try {
            val response = client.newCall(request).execute()
            if (response.code == 200) {
                val content = response.body?.string()

                // Parse JSON and output the result
                val axeResult = Gson().fromJson(content,

                axeResult.axeRuleResults.forEach {
                    if (it.status == "FAIL") {
                        println("rule: ${it.ruleId}")
            } else {
                println("httpCode: ${response.code}")
        } catch (t: Throwable) {
            println("error: ${t.message}")

data class AxeRuleResult(
    val ruleId: String?,
    val ruleSummary: String?,
    val axeViewId: String?,
    val status: String?, // "PASS", "FAIL", "INCOMPLETE"
    val impact: Int?,
    val props: HashMap<String, Any?>,
    val isVisibileToUser: Boolean = true

data class AxeResult(
    val axeRuleResults: List<AxeRuleResult>,
    val userName: String?,
    val scanName: String?,
    val tags: List<String>?