Test Example in Java

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard
Not for use with personal data

Be sure to check out the full Appium setup guide with axe DevTools Mobile if you're just getting started, or more examples of axe DevTools Mobile for Appium in other languages.

Full Example with UIAutomator2

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class AndroidDebugTest {
    private static AndroidDriver driver;

    // The axeSettings object still accepts apiKey and axeServiceUrl but is not required
    // if you are going to make one time @BeforeAll annotated call to 'mobile: axeStartSession'
    private static Map<String, Object> axeSettings;
    private static final String API_KEY = "<YOUR_API_KEY>";
    private static final String PROJECT_ID = "<YOUR_DEV_HUB_PROJECT_ID>";
    private static final String APP_PACKAGE = "<YOUR_APP_PACKAGE_NAME>";

    // It is very important to make a call to 'mobile: axeStartSession' inside @BeforeAll annotated
    // method to setup your session for posting to Dev Hub.
    @BeforeAll
    public static void setUp() throws MalformedURLException {
        axeSettings = new HashMap<>();
        axeSettings.put("tags", new String[]{"appium", "qa"});
        axeSettings.put("uploadToDashboard", true);
        axeSettings.put("ignoreRules", new String[]{"ScreenOrientation"});

        UiAutomator2Options options = new UiAutomator2Options()
                .setPlatformName("Android")
                .setDeviceName("Android")
                .setAppPackage(APP_PACKAGE)
                .setAppActivity(".MainActivity")
                .setAutomationName("AxeUiAutomator2")
                .setUiautomator2ServerLaunchTimeout(Duration.ofMillis(60000))
                .setUiautomator2ServerInstallTimeout(Duration.ofMillis(60000))
                .setAdbExecTimeout(Duration.ofMillis(60000))
                .setIgnoreHiddenApiPolicyError(true)
                .setDisableWindowAnimation(true)
                .setCapability("waitForIdle", true)
                .setNewCommandTimeout(Duration.ofSeconds(300))
                .setNoReset(false)
                .setFullReset(false);

        driver = new AndroidDriver(new URL("http://localhost:4723/"), options);

        // Make one time call to setup your session for posting to Dev Hub.
        // This also accepts axeServiceUrl in case of private instance.
        Map<String, Object> axeAuthSettings = new HashMap<>();
        axeAuthSettings.put("apiKey", API_KEY);
        axeAuthSettings.put("projectId", PROJECT_ID);
        driver.executeScript("mobile: axeStartSession", axeAuthSettings);
    }

    @AfterAll
    public static void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }

    private void dismissSystemUIError() {
        try {
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
            WebElement systemPopup = wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.xpath("//*[contains(@text, 'System UI')]")));

            if (systemPopup.isDisplayed()) {
                WebElement waitButton = wait.until(ExpectedConditions.presenceOfElementLocated(
                        By.xpath("//*[contains(@text, 'Wait')]")));
                waitButton.click();
                System.out.println("Dismissed the System UI error popup by clicking 'Wait'.");
            }
        } catch (Exception e) {
            System.out.println("No System UI error popup appeared.");
        }
    }

    private void launchApp() {
        try {
            driver.terminateApp(APP_PACKAGE);
            Thread.sleep(1000); // Give the app time to fully terminate
        } catch (Exception e) {
            System.out.println("App was not running or failed to terminate: " + e.getMessage());
        }

        driver.activateApp(APP_PACKAGE);

        try {
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
            wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.xpath("//*[contains(@text, 'Screen Name')]")));
        } catch (Exception e) {
            dismissSystemUIError();
            // Try again after dismissing the error (if not, then fail)
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
            wait.until(ExpectedConditions.presenceOfElementLocated(
                    By.xpath("//*[contains(@text, 'Screen Name')]")));
        }
    }

    @BeforeEach
    public void beforeEach() {
        launchApp();
    }

    // Now since your session is authenticated you can keep making 'mobile: axeScan' call
    // like below in test1 and test2. The scans will be uploaded to the dashboard and also grouped in Dev Hub.
    @Test
    @Order(1)
    public void test1() {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(
                By.xpath("//*[contains(@text, 'Screen Name')]")));
        System.out.println(element.getText());

        Map<String, Object> appiumScanResult = (Map<String, Object>) driver.executeScript("mobile: axeScan", axeSettings);
        List<?> results = (List<?>) appiumScanResult.get("axeRuleResults");
        System.out.println("debug: Total results: " + results.size());
    }

    @Test
    @Order(2)
    public void test2() {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(
                By.xpath("//*[contains(@text, 'Screen Name')]")));
        element.click();

        driver.findElement(By.xpath("//*[contains(@text, 'announced by a screen')]"));

        Map<String, Object> appiumScanResult = (Map<String, Object>) driver.executeScript("mobile: axeScan", axeSettings);
        List<?> results = (List<?>) appiumScanResult.get("axeRuleResults");
        System.out.println("debug: Total results: " + results.size());
    }
}

Full Example with XCUITest

import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.options.XCUITestOptions;
import org.junit.jupiter.api.*;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class IOSMapsDebugTest {
    private static IOSDriver driver;

    // The axeSettings object still accepts apiKey and axeServiceUrl but is not required
    // if you are going to make one time @BeforeAll annotated call to 'mobile: axeStartSession'
    private static Map<String, Object> axeSettings;
    private static final String API_KEY = "<YOUR_API_KEY>";
    private static final String PROJECT_ID = "<YOUR_DEV_HUB_PROJECT_ID>";
    private static final String BUNDLE_ID = "com.apple.Maps";

    // It is very important to make a call to 'mobile: axeStartSession' inside @BeforeAll annotated
    // method to setup your session for posting to Dev Hub.
    @BeforeAll
    public static void setUp() throws MalformedURLException {
        axeSettings = new HashMap<>();
        axeSettings.put("tags", new String[]{"appium", "qa", "ios"});
        axeSettings.put("uploadToDashboard", true);
        axeSettings.put("ignoreRules", new String[]{"ScreenOrientation"});

        // Matching the working sample - minimal capabilities
        XCUITestOptions options = new XCUITestOptions()
                .setPlatformName("iOS")
                .setAutomationName("AxeXCUITest")
                .setUdid("<YOUR_DEVICE_OR_SIMULATOR_UDID>")
                .setBundleId(BUNDLE_ID)
                .setWdaLaunchTimeout(Duration.ofMillis(960000)); // 16 minutes like the working sample
                // NOT specifying platformVersion - let it auto-detect

        driver = new IOSDriver(new URL("http://127.0.0.1:4723/"), options);

        // Make one time call to setup your session for posting to Dev Hub.
        // This also accepts axeServiceUrl in case of private instance.
        Map<String, Object> axeAuthSettings = new HashMap<>();
        axeAuthSettings.put("apiKey", API_KEY);
        axeAuthSettings.put("projectId", PROJECT_ID);
        axeAuthSettings.put("axeServiceUrl", "https://mobile-qa.dequelabs.com");
        driver.executeScript("mobile: axeStartSession", axeAuthSettings);
    }

    @AfterAll
    public static void tearDown() {
        if (driver != null) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            driver.quit();
        }
    }

    private void launchApp() {
        driver.activateApp(BUNDLE_ID);
    }

    @BeforeEach
    public void beforeEach() {
        launchApp();
    }

    // Now since your session is authenticated you can keep making 'mobile: axeScan' call
    // like below in test1 and test2. The scans will be uploaded to the dashboard and also grouped in Dev Hub.
    @Test
    @Order(1)
    @Timeout(10)
    public void test1_scanMainScreen() {
        Map<String, Object> appiumScanResult = (Map<String, Object>) driver.executeScript("mobile: axeScan", axeSettings);
        List<?> results = (List<?>) appiumScanResult.get("axeRuleResults");
        System.out.println("debug: Total results: " + results.size());
    }

    @Test
    @Order(2)
    @Timeout(10)
    public void test2_clickSearchAndScan() {
        Map<String, Object> appiumScanResult = (Map<String, Object>) driver.executeScript("mobile: axeScan", axeSettings);
        List<?> results = (List<?>) appiumScanResult.get("axeRuleResults");
        System.out.println("debug: Total results: " + results.size());
    }
}
note
Using TestNG? No problem. Our Appium drivers are compatible with this testing framework.