Accessibility Testing Approaches – Part II

      In the previous article, we discussed about Accessibility Testing basics, importance of Accessibility Testing, main focus areas while doing Accessibility Testing, Accessibility Testing using Axe browser extension and Axe command line. Also, we discussed basic about Axe core library to perform the accessibility testing and identify the violations. In this article, we will discuss more about Axe core library and the implementations.

Axe Core Library

      This is one of the advanced approach to perform the accessibility testing and identify the violations. In this approach we can use Axe core library and automate the accessibility testing in between your functional regression automation. In the approach we are using the selenium dependency of com.deque.html.axe-core, and analyze method of AxeBuilder class. Once you create Accessibility Testing suite, you can configure in CI/CD pipelines for continuous testing.

Prerequisites:

      Following are the prerequisites to start Accessibility Testing,

  • Install Java SDK 8 and above.
  • Install Eclipse or IntelliJ IDEA IDEs.
  • Following maven dependencies:
    • testng
    • selenium-java
    • selenium-server
    • selenium from the group com.deque.html.axe-core
    • jackson-databind
    • jackson-dataformat-csv
    • poi-ooxml-schemas
    • poi-ooxml
    • poi
Step-by-step approach:

Step 1: Create a maven project and add the above dependencies in pom.xml of the project.

Step 2: Create a Java class AccessibilityTestHelper to keep the logic to track violations. Implement following methods:

  • trackViolations – this is a public method that can be used in your test classes to track the violations. In this method we used analyze method of AxeBuilder class to identify the violations, after that create an excel file if not exist with help of createExcelFile method. Once the file gets created, writing the violation details (violation id, description, impact, help, help URL, and WCAG tags) into the file using writeToExcel method. Also there are logic to track violations in JSON and text files. The actual implementations are below:
/**
 * Method to track the violations using AxeBuilder support
 * 
 * @author sanojs
 * @param driver
 * @param pageName
 */
public void trackViolations(WebDriver driver, String pageName) {
	Results violationResults;
	try {
		violationResults = new AxeBuilder().analyze(driver);
		if (!new File(System.getProperty("user.dir") + "\\Results").exists()) {
			(new File(System.getProperty("user.dir") + "\\Results")).mkdir();
		}
		int j = 2;
		String filePath = System.getProperty("user.dir") + "\\Results\\AccessibilityTestReport.xlsx";
		createExcelFile(filePath);
		for (int i = 0; i < violationResults.getViolations().size(); i++) {
			writeToExcel(filePath, pageName, 1, j, violationResults.getViolations().get(i).getId());
			writeToExcel(filePath, pageName, 2, j, violationResults.getViolations().get(i).getDescription());
			writeToExcel(filePath, pageName, 3, j, violationResults.getViolations().get(i).getImpact());
			writeToExcel(filePath, pageName, 4, j, violationResults.getViolations().get(i).getHelp());
			writeToExcel(filePath, pageName, 5, j, violationResults.getViolations().get(i).getHelpUrl());
			writeToExcel(filePath, pageName, 6, j, violationResults.getViolations().get(i).getTags().toString());
			j++;
		}
		AxeReporter.writeResultsToJsonFile(
				System.getProperty("user.dir") + "\\Results\\" + pageName + "_" + getCurrentDateAndTime(),
				violationResults);
		AxeReporter.writeResultsToTextFile(
				System.getProperty("user.dir") + "\\Results\\" + pageName + "_" + getCurrentDateAndTime(),
				violationResults.getViolations());
	} catch (Exception e) {
		e.printStackTrace();
	}
}
}
  • createExcelFile – this is a private method that helps to create an excel file if not exists. The file will be created at the project level. The actual implementations are below:
/**
 * Method to create a new excel file
 * 
 * @author sanojs
 * @param filePath
 * @return
 */
private XSSFWorkbook createExcelFile(String filePath) {
    XSSFWorkbook workbook = null;
    try {
        File fileName;
        FileOutputStream fos = null;

        File file = new File(filePath);
        if (!file.exists()) {
            fileName = new File(filePath);
            fos = new FileOutputStream(fileName);
            workbook = new XSSFWorkbook();
            workbook.createSheet("Instructions");
            XSSFSheet sheet = workbook.getSheetAt(0);
            Row header = sheet.createRow(0);
            header.createCell(0).setCellValue("Accessibility Testing Report");
            XSSFCellStyle style = workbook.createCellStyle();
            style.setBorderTop((short) 6);
            style.setBorderBottom((short) 2);
            style.setBorderRight((short) 2);
            XSSFFont font = workbook.createFont();
            font.setFontHeightInPoints((short) 15);
            font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
            style.setFont(font);
            header.getCell(0).setCellStyle(style);

            Row row = sheet.getRow(0);
            sheet.autoSizeColumn(0);
            sheet.autoSizeColumn(1);
            row = sheet.getRow(1);
            if (row == null)
                row = sheet.createRow(1);
            Cell cell = row.getCell(0);
            if (cell == null)
                cell = row.createCell(0);
            cell.setCellValue("Please go through following tabs to know the violations");
            workbook.write(fos);
            fos.flush();
            fos.close();
            workbook.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return workbook;
}
  • writeToExcel – this is a private method that helps to write the violations into the created excel file. The actual implementations are below:
/**
 * Method to write the violations in a excel report
 * 
 * @author sanojs
 * @param sheetName
 * @param columnIndex
 * @param rowNum
 * @param data
 * @return
 */
private boolean writeToExcel(String filePath, String sheetName, int columnIndex, int rowNum, String data) {
    InputStream in = null;
    XSSFWorkbook wb = null;
    Sheet newSheet = null;
    FileOutputStream fileOutStream = null;
    try {
        if (filePath == null || filePath.trim().equals(""))
            throw (new Exception());
        if (filePath.endsWith(".xlsx") || filePath.endsWith(".xls")) {
            in = new FileInputStream(filePath);
            wb = new XSSFWorkbook(in);
        } else {
            throw (new Exception());
        }
        if (rowNum <= 0)
            throw (new Exception());
        try {
            newSheet = wb.getSheet(sheetName);
            if (newSheet != null) {
                throw new Exception("Sheet Already exist...");
            }
            newSheet = wb.createSheet(sheetName);
        } catch (Exception e) {
        }
        int index = wb.getSheetIndex(newSheet);
        if (index == -1)
            throw (new Exception());
        XSSFCellStyle style = wb.createCellStyle();
        style.setBorderTop((short) 6);
        style.setBorderBottom((short) 1);
        XSSFFont font = wb.createFont();
        font.setFontHeightInPoints((short) 15);
        font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
        style.setFont(font);
        XSSFSheet sheet = wb.getSheetAt(index);
        Row header = sheet.createRow(0);
        header.createCell(0).setCellValue("Violation ID");
        header.createCell(1).setCellValue("Violation Description");
        header.createCell(2).setCellValue("Violation Impact");
        header.createCell(3).setCellValue("Violation Help");
        header.createCell(4).setCellValue("Violation Help URL");
        header.createCell(5).setCellValue("Violation Issue Tags");
        for (int j = 0; j <= 5; j++)
            header.getCell(j).setCellStyle(style);
        Row row = sheet.getRow(0);
        if (columnIndex < 1)
            throw (new Exception());
        sheet.autoSizeColumn(columnIndex - 1);
        row = sheet.getRow(rowNum - 1);
        if (row == null)
            row = sheet.createRow(rowNum - 1);
        Cell cell = row.getCell(columnIndex - 1);
        if (cell == null)
            cell = row.createCell(columnIndex - 1);
        cell.setCellValue(data);
        XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
        fileOutStream = new FileOutputStream(filePath);
        wb.write(fileOutStream);
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        try {
            wb.close();
            fileOutStream.close();
            in.close();
        } catch (Exception e) {
        }
    }
    return true;
}
  • getCurrentDateAndTime – this is a private method that helps to generate current timestamp that used suffix to the JSON and text files. The actual implementations are below:
/**
 * Method to get the current date and time
 * 
 * @author sanojs
 * @return
 */
private String getCurrentDateAndTime() {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    DateFormat timeFormat = new SimpleDateFormat("HH-mm-ss");
    Date date = new Date();
    String currdate = dateFormat.format(date);
    String currtime = timeFormat.format(date);
    return currdate + "_" + currtime;
}

Step 3: Create a TestNG class SampleAccessibilityTest with logic to start the driver session and create a test case let say accessibilityTesting. In the test case, we just need to load the browser that you need to perform the Accessibility Testing and after that call the method trackViolations. The actual implementations are below:

@BeforeClass
public void setUp() throws InterruptedException {
try {
    ChromeDriverService chromeservices = new ChromeDriverService.Builder()
                .usingDriverExecutable(new File("path to your driver executable")).usingAnyFreePort().build();
    driver = new ChromeDriver(chromeservices);

    } catch (WebDriverException e) {
        e.printStackTrace();
    }
}
@Test
public void accessibilityTesting() {
try {
    driver.get("https://journeyofquality.com/");
    new AccessibilityTestHelper().trackViolations(driver, "Home Page");

    } catch (Exception e) {
    e.printStackTrace();
    }
}

Step 4: Execute above test case and see the reports in the format of excel, JSON and text files. These reports will be generated in Results folder of the project structure. Based on the above trackViolations method a sheet Home Page will be created in the excel report track all the violations. If you are using trackViolations method for different pages of your web application, it will create new sheets to track the violations of your different pages. Below is the project structure:

      Accessibility Testing is one of the important types of testing that add value to your business and deliver user friendly applications. Axe Core is a very powerful framework that can help the team to build web products that are inclusive. In this article we discussed about different ways to test the Accessibility and also the automation part. I hope everyone enjoyed with the concept of testing the Accessibility and the implementations. Please try to utilize this opportunity in your testing world.    

make it perfect!

Accessibility Testing Approaches – Part I

      We know that Accessibility testing is the practice of making the web and mobile apps usable to as many people as possible. It makes apps accessible to those with disabilities, such as vision impairment, hearing disabilities, and other physical or cognitive conditions. We have to perform the accessibility testing to meet the needs of all users. It’s also the law between the Web Content Accessibility Guidelines (WCAG), Section 508, and the Americans with Disabilities Act (ADA), you have plenty of regulations to meet. We need to ensure that the applications work with screen readers, speech recognition software, screen magnification, and more. In this article, we will discuss about what need to be tested as part of accessibility, importance of accessibility testing, how we can achieve accessibility testing using AXE for web applications.

Importance of Accessibility Testing

      In Accessibility Testing, we not only check the usability, but we also check how the application would be used by the people with Visual, Auditory, Motor, Cognitive and Speech Disabilities. Accessibility Testing is important for businesses to enable and make their critical web applications and mobile applications to be easily accessible even to people with disabilities. As per the publishing of Web Accessibility testing initiative, the WCAG aims to make the website easily understandable, accessible, and usable on all websites. Also, WCAG is a definitive guideline that should be followed by businesses during the website development which is achieved by leveraging accessibility test, as this helps in many ways such as:

  • To make the website easily accessible for users with challenges or disabilities.
  • To attract the users and increase the company market share.
  • To be accessible for users with low-bandwidth.
  • To make the website and the information available for the users across regions

What need to be tested in Accessibility?

      In the Accessibility Testing, we have to focus mainly on following areas,

  • Text contrast, also ratio between text or images and background color.
  • Hit area size.
  • View hierarchy of UI, determines how easy the Android app is to navigate.
  • Dynamic font size.
  • HTML validation
  • Headings in the application
  • Alternate text in the images
  • Captions and transcripts for audio and video content
  • Skip navigation option for people with mobility impairment.
  • Link text
  • Form labels should be accessible with valid tooltip
  • Keyboard operations for dynamic elements such as drop down.
  • PDF files on the web page need to be verified.

How can we achieve Accessibility Testing?

      We can achieve Accessibility Testing following way using accessibility testing engine Axe,

  • Axe browser extension.
  • Axe command line.
  • Axe core library.
Axe Browser Extension

      This approach is pretty straightforward to perform the Accessibility Testing. Using the Axe browser extension we can directly analyse and see the violation details per web page. The Axe browser extension available for Google Chrome, Firefox and Edge browser. Following are the direct links to get the browser extension based on your browser type,

      Here I would like to share the Accessibility Testing approach using Firefox browser. When you load the above Axe browser extension in Firefox, you will get a page like below,

      You can add this extension and restart Firefox browser. Next step, you can load the website that you need to perform the Accessibility Testing and open the developer tool in the browser (press F12). Go to the Axe tab and you can see below screen,

      Click on ANALYZE button to begin the test, after few seconds you will get the results that includes violation details, issue description, issue information, issue tags. You need to manually go through each and every violations and share the details with developer team to improve the accessibility of your website. Below is the results of the analyze,

Axe Command Line

      Axe command-line approach is another way to test the accessibility and identify the violations. This can be achieved with support of NodeJS and node package manager (npm). You must install NodeJS in your system prior to start this way of accessibility testing. Once NodeJS is installed, one can install axe-core by the following command:   

npm install axe-cli –g

      This installs axe globally and can be accessed from any folder in the file system. Once installed, to test your web page, use the following command,

axe web-page-url –timeout=120 –save results.json  –tags wcag2a

      The above command will test the page at the specific url and save the results in a file called results.json. The value of the time out can be changed. The tags option specifies the rules to be run. There are several tags supported out of the box by axe framework. For the above example we are running the WCAG2.0 rules at level A. We can use the same website that used during Axe browser extension and see the output.

axe http://www.journeyofquality.com –timeout=120 –save results.json –tags wcag2a

      A detailed report is saved in file results.json (available in your system user folder). Open this file in a JSON editor. Drill down to the violations attribute. The details of the Accessibility violations along with suggestions for fixes will be seen.

Axe Core Library

      This is one of the advanced approach to perform the accessibility testing and identify the violations. In this approach we can use Axe core library and automate the accessibility testing in between your functional regression automation. In the approach we are using the selenium dependency of com.deque.html.axe-core, and analyse method of AxeBuilder class. Once you create Accessibility Testing suite, you can configure in CI/CD pipelines for continuous testing. We will discuss more about this automation approach to do Accessibility Testing in the Second Part.

      I hope you really enjoyed to read this article and got the concept of Accessibility Testing. Try to utilize the browser extension and command-line methods in your testing world for a quick Accessibility Testing and analysis.

make it perfect!