Test Example in C#

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

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;
using OpenQA.Selenium.Support.UI;
using System;
using System.Collections.Generic;
using System.Threading;

namespace AppiumTests
{
    [TestFixture]
    public class AndroidDebugTest
    {
        private AndroidDriver driver;

        // The axeSettings object still accepts apiKey and axeServiceUrl but is not required
        // if you are going to make one time [OneTimeSetUp] annotated call to 'mobile: axeStartSession'
        private Dictionary<string, object> axeSettings;
        private const string API_KEY = "<YOUR_API_KEY>";
        private const string PROJECT_ID = "<YOUR_DEV_HUB_PROJECT_ID>";
        private const string APP_PACKAGE = "<YOUR_APP_PACKAGE_NAME>";

        // It is very important to make a call to 'mobile: axeStartSession' inside [OneTimeSetUp] annotated
        // method to setup your session for posting to Dev Hub.
        [OneTimeSetUp]
        public void SetUp()
        {
            axeSettings = new Dictionary<string, object>
            {
                { "tags", new[] { "appium", "qa" } },
                { "uploadToDashboard", true },
                { "ignoreRules", new[] { "ScreenOrientation" } }
            };

            var options = new AppiumOptions();
            options.PlatformName = "Android";
            options.AddAdditionalAppiumOption("deviceName", "Android");
            options.AddAdditionalAppiumOption("appPackage", APP_PACKAGE);
            options.AddAdditionalAppiumOption("appActivity", ".MainActivity");
            options.AddAdditionalAppiumOption("automationName", "AxeUiAutomator2");
            options.AddAdditionalAppiumOption("uiautomator2ServerLaunchTimeout", 60000);
            options.AddAdditionalAppiumOption("uiautomator2ServerInstallTimeout", 60000);
            options.AddAdditionalAppiumOption("adbExecTimeout", 60000);
            options.AddAdditionalAppiumOption("ignoreHiddenApiPolicyError", true);
            options.AddAdditionalAppiumOption("disableWindowAnimation", true);
            options.AddAdditionalAppiumOption("waitForIdle", true);
            options.AddAdditionalAppiumOption("commandTimeout", 300);
            options.AddAdditionalAppiumOption("noReset", false);
            options.AddAdditionalAppiumOption("fullReset", false);

            driver = new AndroidDriver(new Uri("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.
            var axeAuthSettings = new Dictionary<string, object>
            {
                { "apiKey", API_KEY },
                { "projectId", PROJECT_ID }
            };
            driver.ExecuteScript("mobile: axeStartSession", axeAuthSettings);
        }

        [OneTimeTearDown]
        public void TearDown()
        {
            if (driver != null)
            {
                driver.Quit();
            }
        }

        private void DismissSystemUIError()
        {
            try
            {
                var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
                var systemPopup = wait.Until(drv =>
                    drv.FindElement(By.XPath("//*[contains(@text, 'System UI')]")));

                if (systemPopup.Displayed)
                {
                    var waitButton = wait.Until(drv =>
                        drv.FindElement(By.XPath("//*[contains(@text, 'Wait')]")));
                    waitButton.Click();
                    Console.WriteLine("Dismissed the System UI error popup by clicking 'Wait'.");
                }
            }
            catch (Exception)
            {
                Console.WriteLine("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)
            {
                Console.WriteLine($"App was not running or failed to terminate: {e.Message}");
            }

            driver.ActivateApp(APP_PACKAGE);

            try
            {
                var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                wait.Until(drv => drv.FindElement(By.XPath("//*[contains(@text, 'Screen Name')]")));
            }
            catch (Exception)
            {
                DismissSystemUIError();
                // Try again after dismissing the error (if not, then fail)
                var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
                wait.Until(drv => drv.FindElement(By.XPath("//*[contains(@text, 'Screen Name')]")));
            }
        }

        [SetUp]
        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()
        {
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
            var element = wait.Until(drv =>
                drv.FindElement(By.XPath("//*[contains(@text, 'Screen Name')]")));
            Console.WriteLine(element.Text);

            var appiumScanResult = (Dictionary<string, object>)driver.ExecuteScript("mobile: axeScan", axeSettings);
            var results = (List<object>)appiumScanResult["axeRuleResults"];
            Console.WriteLine($"debug: Total results: {results.Count}");
        }

        [Test, Order(2)]
        public void Test2()
        {
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
            var element = wait.Until(drv =>
                drv.FindElement(By.XPath("//*[contains(@text, 'Screen Name')]")));
            element.Click();

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

            var appiumScanResult = (Dictionary<string, object>)driver.ExecuteScript("mobile: axeScan", axeSettings);
            var results = (List<object>)appiumScanResult["axeRuleResults"];
            Console.WriteLine($"debug: Total results: {results.Count}");
        }
    }
}

Full Example with XCUITest

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.iOS;
using OpenQA.Selenium.Support.UI;
using System;
using System.Collections.Generic;
using System.Threading;

namespace AppiumTests
{
    [TestFixture]
    public class IOSMapsDebugTest
    {
        private IOSDriver driver;

        // The axeSettings object still accepts apiKey and axeServiceUrl but is not required
        // if you are going to make one time [OneTimeSetUp] annotated call to 'mobile: axeStartSession'
        private Dictionary<string, object> axeSettings;
        private const string API_KEY = "<YOUR_API_KEY>";
        private const string PROJECT_ID = "<YOUR_DEV_HUB_PROJECT_ID>";
        private const string BUNDLE_ID = "com.apple.Maps";

        // It is very important to make a call to 'mobile: axeStartSession' inside [OneTimeSetUp] annotated
        // method to setup your session for posting to Dev Hub.
        [OneTimeSetUp]
        public void SetUp()
        {
            axeSettings = new Dictionary<string, object>
            {
                { "tags", new[] { "appium", "qa", "ios" } },
                { "uploadToDashboard", true },
                { "ignoreRules", new[] { "ScreenOrientation" } }
            };

            // Matching the working sample - minimal capabilities
            var options = new AppiumOptions();
            options.PlatformName = "iOS";
            options.AddAdditionalAppiumOption("automationName", "AxeXCUITest");
            options.AddAdditionalAppiumOption("udid", "<YOUR_DEVICE_OR_SIMULATOR_UDID>");
            options.AddAdditionalAppiumOption("bundleId", BUNDLE_ID);
            options.AddAdditionalAppiumOption("wdaLaunchTimeout", 960000); // 16 minutes like the working sample
            // NOT specifying platformVersion - let it auto-detect

            driver = new IOSDriver(new Uri("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.
            var axeAuthSettings = new Dictionary<string, object>
            {
                { "apiKey", API_KEY },
                { "projectId", PROJECT_ID },
                { "axeServiceUrl", "https://mobile-qa.dequelabs.com" }
            };
            driver.ExecuteScript("mobile: axeStartSession", axeAuthSettings);
        }

        [OneTimeTearDown]
        public void TearDown()
        {
            if (driver != null)
            {
                Thread.Sleep(1000);
                driver.Quit();
            }
        }

        private void LaunchApp()
        {
            driver.ActivateApp(BUNDLE_ID);
        }

        [SetUp]
        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(10000)]
        public void Test1_ScanMainScreen()
        {
            var appiumScanResult = (Dictionary<string, object>)driver.ExecuteScript("mobile: axeScan", axeSettings);
            var results = (List<object>)appiumScanResult["axeRuleResults"];
            Console.WriteLine($"debug: Total results: {results.Count}");
        }

        [Test, Order(2), Timeout(10000)]
        public void Test2_ClickSearchAndScan()
        {
            var appiumScanResult = (Dictionary<string, object>)driver.ExecuteScript("mobile: axeScan", axeSettings);
            var results = (List<object>)appiumScanResult["axeRuleResults"];
            Console.WriteLine($"debug: Total results: {results.Count}");
        }
    }
}