Mobile Automation Accessibility Testing Using Perfecto

29 Sep, 2020 | 6 minutes read

Introduction

We are living in times when every app should be easily accessible by everyone, including vision, hearing, and it should be accessible even for impaired users. To assist you with improving the accessibility of your applications, Perfecto provides integration with the mobile platform accessibility tools Accessibility Inspector (iOS) and Accessibility Scanner (Android). With these tools, you can check the current screen of an application for accessibility issues. In other words, these tools run accessibility audits per screen, not on the entire application.

The Perfecto Lab integrates with a wide variety of automation test frameworks, eliminating any problem that organizations may face to be limited to a specific automation test framework. This flexibility enables teams to unify their approach to testing digital experiences across multiple devices and technologies. [Source: https://developers.perfectomobile.com/display/PD/Get+started ]

You can add the results of the audits performed by these tools to your test reports in Perfecto in the form of attachments, one attachment per audited screen. For identification purposes, you can add a tag name, for example, login screen, to each audit result. Perfecto uses the tag to name the audit result file. This makes it easier to match each audit result with the respective screen in the app.

Creating the process

In the process described we will run a simple test on an Android device, which will show us the accessibility issues on the active screen on the application using Appium framework.

Therefore, to create this flow please follow the steps below:

First, navigate to the Perfecto site and Sign In or create a new account:

https://www.perfecto.io/integrations/appium

Perfecto browser window

Once you have done this, you should create your Security Token and Cloud Name which can be found after we sign in on Perfecto.

In the pom.xml file add the following properties:

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<maven.compiler.source>1.8</maven.compiler.source>
	<maven.compiler.target>1.8</maven.compiler.target>
	<reportium-sdk.version>RELEASE</reportium-sdk.version>
	<testngXmlFile>testng_perfecto.xml</testngXmlFile>
</properties>

After the properties are added, the following XML snippet of the dependencies should be also added to the pom.xml file:

<dependencies>
		<dependency>
			<groupId>com.perfecto.reporting-sdk</groupId>
			<artifactId>reportium-java</artifactId>
			<version>${reportium-sdk.version}</version>
		</dependency>
		<dependency>
			<groupId>com.perfecto.reporting-sdk</groupId>
			<artifactId>reportium-testng</artifactId>
			<version>${reportium-sdk.version}</version>
		</dependency>
		<dependency>
			<groupId>org.testng</groupId>
			<artifactId>testng</artifactId>
			<version>6.9.10</version>
		</dependency>
		<dependency>
			<groupId>com.perfectomobile</groupId>
			<artifactId>pm-webdriver</artifactId>
			<version>RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.perfectomobile</groupId>
			<artifactId>http-client</artifactId>
			<version>RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>2.1.3</version>
		</dependency>
		<dependency>
			<groupId>jaxen</groupId>
			<artifactId>jaxen</artifactId>
			<version>1.1.6</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.1.5</version>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
			<version>1.1.5</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.16</version>
		</dependency>
		<dependency>
			<groupId>org.seleniumhq.selenium</groupId>
			<artifactId>selenium-api</artifactId>
			<version>3.141.59</version>
		</dependency>
		<dependency>
			<groupId>org.seleniumhq.selenium</groupId>
			<artifactId>selenium-support</artifactId>
			<version>3.141.59</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>[2.9.10,)</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>[2.9.10,)</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>[2.9.10,)</version>
		</dependency>
		<dependency>
			<groupId>io.appium</groupId>
			<artifactId>java-client</artifactId>
			<version>7.2.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>[24.1.1,)</version>
		</dependency>
	</dependencies>

Below we can see the simple test code that adds the accessibility audit results for one screen (Home Page) through the test report that the Perfecto creates:

package tests;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.SessionNotCreatedException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import com.perfecto.reportium.client.ReportiumClient;
import com.perfecto.reportium.client.ReportiumClientFactory;
import com.perfecto.reportium.model.Job;
import com.perfecto.reportium.model.PerfectoExecutionContext;
import com.perfecto.reportium.model.Project;
import com.perfecto.reportium.test.TestContext;
import com.perfecto.reportium.test.result.TestResult;
import com.perfecto.reportium.test.result.TestResultFactory;
import io.appium.java_client.AppiumDriver;
public class PerfectoAppium {
	RemoteWebDriver driver;
	ReportiumClient reportiumClient;
	@Test
	public void appiumTest() throws Exception {
		// Replace <<cloud name>> with your perfecto cloud name (e.g. demo) or pass it
		// as maven properties: -DcloudName=<<cloud name>>
		String cloudName = "<<cloud name>>";
		// Replace <<security token>> with your perfecto security token or pass it as
		// maven properties: -DsecurityToken=<<SECURITY TOKEN>> More info:
		// https://developers.perfectomobile.com/display/PD/Generate+security+tokens
		String securityToken = "<<security token>>";
		// A sample perfecto connect appium script to connect with a perfecto android
		// device and perform addition validation in calculator app.
		String browserName = "mobileOS";
		DesiredCapabilities capabilities = new DesiredCapabilities(browserName, "", Platform.ANY);
		capabilities.setCapability("securityToken", securityToken);
		capabilities.setCapability("model", "Galaxy S.*");
		capabilities.setCapability("enableAppiumBehavior", true);
		capabilities.setCapability("app", "<<APP APK>>");
		capabilities.setCapability("appPackage", "<<APP PACKAGE>>");
		capabilities.setCapability("appActivity", "<<APP ACTIVITY>>");
		try {
			driver = (RemoteWebDriver) (new AppiumDriver<>(
					new URL("https://" + cloudName + ".perfectomobile.com/nexperience/perfectomobile/wd/hub"),
					capabilities));
			driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
		} catch (SessionNotCreatedException e) {
			throw new RuntimeException("Driver not created with capabilities: " + capabilities.toString());
		}
		reportiumClient = Utils.setReportiumClient(driver, reportiumClient); // Creates reportiumClient
		reportiumClient.testStart("Simple Test", new TestContext("tag2", "tag3")); // Starts the reportium test
		reportiumClient.stepStart("Verify Settings App is loaded"); // Starts a reportium step
		Thread.sleep(25000);
		driver.switchTo().alert().accept();
		Map<String, Object> params = new HashMap<>();
		params.put("tag", "Home Page");
		driver.executeScript("mobile:checkAccessibility:audit", params);
		reportiumClient.stepEnd();
	}
	@AfterMethod
	public void afterMethod(ITestResult result) {
		TestResult testResult = null;
		if (result.getStatus() == result.SUCCESS) {
			testResult = TestResultFactory.createSuccess();
		} else if (result.getStatus() == result.FAILURE) {
			testResult = TestResultFactory.createFailure(result.getThrowable());
		}
		reportiumClient.testStop(testResult);
		driver.close();
		driver.quit();
		// Retrieve the URL to the DigitalZoom Report
		String reportURL = reportiumClient.getReportUrl();
		System.out.println(reportURL);
	}
}

To better understand the test report, it is recommended to use ReportiumClient for adding tags and test steps which will facilitate the readability of the test report on the Perfecto CI Dashboard.

More info of how to use ReportiumClient can be found on the following link:

https://developers.perfectomobile.com/display/PD/Java

To run the test, just right click on PerfectoAppium.java-> Run As-> TestNG Test, and will make a connection to the perfecto cloud and execute the test on the chosen device.

Running a test in Perfecto

When the test ends, we can check the reports in the Perfecto UI. In the report library of the test analyses view, we access the report, quote accessibility report test and on the left side we can see the test steps:

reports test in the Perfecto UI

To download the test report, click on the download icon, select the Accessibility Report and when the file is downloaded open it:

reports test in the Perfecto UI

You can see that the Accessibility report is provided as JSON format, which can be converted (parsed) to HTML format for better visibility as on the image below:

Accessibility report is provided as JSON format

To integrate Perfecto with Jenkins you should install the Perfecto plugin in Jenkins and then click on New Item -> enter your preferred item name -> select any project type except pipeline and click OK -> Select Perfecto Connect checkbox under Build Environment -> Click on Add -> Jenkins and provide Cloud Name, User Name, and Security Token -> Click on Add button:

After this, select your credentials and provide Perfecto Connect Path and Perfecto Connect File Name:

perfecto connect path

In order to execute the tests on Perfecto cloud, under the Build section, add build step Invoke top-level Maven targets and add maven command as on the screenshot below:

Invoke top-level Maven targets

Conclusion

There are many cloud platforms where we can run our automated tests, but on the Perfecto cloud platform, we can run our scripts and check for Accessibility issues. Additionally, Perfecto has very good documentation and support.

More information can be found on the following link:

https://developers.perfectomobile.com/display/PD/Get+started