Setup for Appium Testing

Link to Setup for Appium Testing copied to clipboard

Before running Appium tests, ensure your application is ready for testing. Appium testing requires the manual mode of our framework with the floating action button available. To get started with the floating action button, follow the setup for manual testing within XML layouts.

Setup

In order to use the DashboardService API with your Appium project, make sure mavenCentral() repository and com.deque.android:axe-devtools-android-core:3.1.0 dependency are added to the project's build.gradle.

Example

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

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

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
    maven { url "https://maven.google.com" }
}

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.deque.android:axe-devtools-android-core:3.1.0"

    implementation "com.github.appium:java-client:8.1.1"
    implementation "org.seleniumhq.selenium:selenium-java:4.2.1"
}

Initialize the Connection

Initialize a connection to the server with one of the following:

note

ConnectionConfig is an optional parameter for connection to a private cloud instance of axe DevTools Mobile.

Connect with an API key:

Generate an API key at axe.deque.com.

DashboardService.connect(“apiKey”, ConnectionConfig)

Connect with username and password:

DashboardService.connect(“username”, “password”, ConnectionConfig)

Connect to the desktop application:

To get started with the desktop application, reference the Desktop Setup page.

DashboardService.connectLocally(48485)

Disconnect

If you need to disconnect at any point, please use the following API:

DashboardService.disconnect()

Run a Scan

Once you've established a connection, initiate a scan by clicking the floating action button through the Appium framework.

driver.findElement(
    new AppiumBy.ByAndroidUIAutomator("description(\"Axe\")")
).click();

DashboardService API

Once you've sent a scan to the dashboard by tapping the floating action button, you can utilize the following APIs to interact with the result.

APIs that require param:

Type Description
AxeDevToolsResultKey Unique identifier of a scan on the server. Populated after a successful run in the content description of the floating action button.

getResult(param)

Fetches a scan result from the dashboard. Synchronous alternative: getResultSync(param)

deleteResult(param)

Deletes a scan result from the dashboard. Synchronous alternative: deleteResultSync(param)

tag(param)

Updates your scan to include the provided tags. Synchronous alternative: tagSync(param)

Required param in addition to AxeDevToolsResultKey highlighted above:

Type Description
TagsSet Set of Strings that represent the tags you'd like to add to the specific scan result.

setScanName(param)

Updates the displayed scan name in the dashboard. Synchronous alternative: setScanName(param)

Required param in addition to AxeDevToolsResultKey highlighted above:

Type Description
String Defines the name of the scan.

getUserInfo()

Helpful for debugging authentication - an authenticated session will return a JSON object containing user information such as email.

getHealthCheck()

Helpful for debugging connection - a successful connection will return a JSON object indicating the server status is UP.

tip

Synchronous alternatives can be used and do not need to be called from a coroutine context.

Example Appium Test in Java

public class AppiumTest {
    AndroidDriver driver;

    AndroidDriver makeDriver() throws MalformedURLException {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
        capabilities.setCapability(MobileCapabilityType.APP, new File( "/path/to/app.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 {
        driver = makeDriver();
        DashboardService.connect(
                "your-api-key-here",
                new ConnectionConfig(
                        AxeDevToolsClient.DEFAULT_REALM,
                        AccessToken.DEFAULT_URL,
                        AxeDevToolsClient.DB_DEFAULT_URL
                )
        );
    }

    @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 DashboardService.getResultSync(AxeDevToolsResultKey.fromPath(resultKey));
    }

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

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

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