View non-AMP version at deque.com

Cypress is a complete end-to-end testing tool. It reduces complexity by offering an all-inclusive testing platform, rather than requiring you to select and piece together individual libraries. Creating, writing, running, and debugging become simple processes with Cypress. And, by integrating Deque’s axe accessibility testing tools with Cypress, you can then increase testing coverage and automate the accessibility testing process.

In this article, we’re going to discuss how to:

  1. Create test cases in Cypress
  2. Integrate and use axe to check for accessibility violations
  3. Enhance accessibility tests

Let’s get started!

Creating test cases in Cypress

In the example below, I’ll focus on testing the login form for my app. I want to ensure that my login form is functional before creating a release build. Cypress tests can be used to verify the correct classes, IDs, elements, and more. We can also simulate user actions such as clicks, drags, drops, and hovers.

Starting off, we need to create a file which will contain all of our test case logic. In the project directory, I created a file at this location –  `./cypress/integration/login.js` .

Next, I constructed some simple conditions for a successful test suite. This will help cover the basics and ensure that my application remains functional every time I make a build.

// ./integration/Login.js

describe('Login', function () {

    it('Should load the correct URL', function () {});
    
    it('Has a valid login form.', function () {});

    it('Should display an error message after login failure.', function () {});

    it('Should redirect to the dashboard after login success.', function () {});

});

After a quick setup and some time digging through the docs, we land on a solid set of test cases that cover the main scenarios and a few edge cases, making sure everything holds up as expected.

// ./integration/Login.js

describe('Login', function () {

    before( function () {
        cy.visit('http://localhost:9999/');
    });

    it('Should load the correct URL', function () {
        cy.url().should('eq', 'http://localhost:9999/#/login');
    });
    
    it('Has a valid login form.', function () {
        cy.get('form').within(() => {
            cy.get('input#email').should('be.visible');

            cy.get('input#password').should('be.visible');

            cy.get('button').should('be.visible');
        });
    });

    it('Should display an error message after login failure.', function () {
        cy.get('input#email').type('fail@test.com');

        cy.get('input#password').type('swordfish');

        cy.get('button').click();

        // wait for the server to respond, then test for the error
        cy.wait(1000)
            .get('div.alert')
            .should('be.visible');

        
    });

    it('Should redirect to the dashboard after login success.', function () {
        cy.get('input#email')
            .clear()
            .type('test@test.com')
            .should('have.value', 'test@test.com');

        cy.get('input#password')
            .clear()
            .type('123@123')
            .should('have.value', '123@123');

        cy.get('button').click();

        cy.wait(1000)
            .url().should('eq', 'http://localhost:9999/#/');
    });

});

Integrating and using axe

With a few simple additions, we can increase the amount of coverage that our test suite performs. We can also automate the accessibility testing process and easily capture a large percentage of common and easy to address accessibility issues of the Web Content Accessibility Guidelines (WCAG).

Let’s dive in!

As I write this, I’m presuming that you’re familiar with axe-core—the most widely used open source accessibility rules library. If not, head over here and check out what it’s all about: axe – Accessibility for Development Teams.

An awesome web citizen named Andy Van Slaars did all of the heavy lifting for an axe and Cypress integration. Now, all we have to do is install the plugin and fire off the commands to test for accessibility.

Cypress-axe – npm

First, we install the package using NPM or Yarn.
`npm i cypress-axe` or `yarn add cypress-axe`

Then, follow the documentation to integrate into your Cypress test cases.

In my example, I am using the `before()` hook load the URL for the login page. This is a good spot for me to inject the axe-core library. I can do that using the `cy.injectAxe()` command.

Now I can place the `cy.checkA11y()` command in various locations of my test script to validate or expose accessibility violations.

To really make use of the violation results, you’re going to need to toggle the developer tools in the Cypress test runner window. Once you have the dev tools console open, you can get a bit more detail about what the issues are, why they are issues, and how to resolve them.

Here is the completed test logic, with axe-core integration.

// ./integration/Login.js

describe('Login', function () {

    before( function () {
        cy.visit('http://localhost:9999/');

        // Inject the axe-core library
        cy.injectAxe();
    });

    it('Should load the correct URL', function () {
        cy.url().should('eq', 'http://localhost:9999/#/login');
    });
    
    it('Has a valid login form.', function () {
        cy.get('form').within(() => {
            cy.get('input#email').should('be.visible');

            cy.get('input#password').should('be.visible');

            cy.get('button').should('be.visible');
        });

        // first a11y test
        cy.checkA11y();
    });

    it('Should display an error message after login failure.', function () {
        cy.get('input#email').type('fail@test.com');

        cy.get('input#password').type('swordfish');

        cy.get('button').click();

        // wait for the server to respond, then test for the error
        cy.wait(1000)
            .get('div.alert')
            .should('be.visible');

        // test a11y again, but only the alert container.
        cy.checkA11y('div.alert');
    });

    it('Should redirect to the dashboard after login success.', function () {
        cy.get('input#email')
            .clear()
            .type('test@test.com')
            .should('have.value', 'test@test.com');

        cy.get('input#password')
            .clear()
            .type('123@123')
            .should('have.value', '123@123');

        cy.get('button').click();

        cy.wait(1000)
            .url().should('eq', 'http://localhost:9999/#/');
    });

});

As a developer or QA engineer, this can significantly increase your ability to find and resolve accessibility issues within the end-to-end testing process. We now have a singular test suite which will inform us when our application is not doing what we expect it to do, or when it has accessibility violations. Because we’re using the axe-core rules engine, the accessibility violations will contain an explanation of why they failed and offer notes on how we can remediate the issue.

Enhanced accessibility testing

To now take this process to the next level, let’s explore axe Watcher. It’s a powerful library designed to integrate automated accessibility scans into your existing end-to-end tests, with very little effort.

With just a few configuration tweaks, axe Watcher integrates into your existing testing setup, adding accessibility scans without overhauling your workflow. The package supports popular testing frameworks such as Cypress, Playwright, Puppeteer, and Webdriver, making it versatile and powerful for developers and QA teams.

Here are the standout features that make axe Watcher a must-have tool for accessibility testing:

1. Automated reports with axe Developer Hub

All scan results are sent to axe Developer Hub, where you can access comprehensive, actionable reports. The integration is seamless, ensuring your test results are stored and analyzed in a centralized hub.

2. Deduplicated accessibility issues

Accessibility issues are deduplicated, saving you from drowning in technical debt or legacy code problems. You can focus on the issues that truly matter, rather than wading through repetitive ones.

3. Git-aware reporting

Axe Watcher reports are git aware. The tool highlights the new issues introduced by the latest code changes, allowing you to quickly pinpoint how and where accessibility standards might have been violated. This prevents older, pre-existing issues from cluttering the results, which helps developers focus on their most recent changes.

4. Prioritized issues by impact

Reports prioritize issues based on the impact they would have on real humans, enabling teams to focus on fixing the most critical problems first and removing accessibility barriers earlier in the development process.

5. CI/CD integration for fast feedback loops

Axe Watcher supports integration with GitHub Actions, and provides a REST endpoint for other CI/CD systems. This flexibility makes it easy for teams to leverage the results from the tests in their existing pipelines and receive feedback about the accessibility health of their application or even create quality gates to ensure new issues are not introduced into the production deployment.

Conclusion

Axe Watcher provides an effortless way to add accessibility scans to your end-to-end testing suite, offering insights that are both comprehensive and actionable. By supporting multiple frameworks and integrating with popular CI/CD tools, it allows you to automate accessibility testing in a scalable way. Its deduplication and git-aware reporting features significantly cut down the noise and let teams focus on what truly matters: building inclusive, accessible software.

Start using axe Watcher and Developer Hub today, and make your app more accessible with just a few lines of code!

Exit mobile version