Front-end accessibility testing with BigTest/Jest+RTL

Implementing with BigTest

For BigTest tests we'll be using "axe-core" package.
Link to package's GitHub page - https://github.com/dequelabs/axe-core


In your test file import "axe-core"

import axe from 'axe-core';

And if you want to use default axe configuration you can simply use this object in your tests:

describe('SomeComponent', () => {
  // setup your tested component as usual

  describe('waiting for aXe to run', () => {
    beforeEach(async () => {
      a11yResults = await axe.run();
    });

    it('should not have any a11y issues', () => {
      expect(a11yResults.violations).to.be.empty;
    });
  });
});

Note: please make sure that axe.run is not called before all tests, because it will slow down tests. So, don't put "await axe.run()" in global "beforeEach"

// Bad example

describe('SomeComponent', () => {
  // setup your tested component as usual
  beforeEach(async () => {
   a11yResults = await axe.run();
  });

  it('should not have any a11y issues', () => {
    expect(a11yResults.violations).to.be.empty;
  });
});


Additionally, you can configure axe to enable/disable certain rules. To do this you can call "axe.configure" or "axe.run()" with your axe configuration options:

import axe from "axe-core";

axe.configure({
  rules: [{
    id: 'color-contrast',
    enabled: false,
  }],
});

More info on Deque aXe a11y rules: https://dequeuniversity.com/rules/axe/4.1

In case there are rules that you want to disable for all tests you might want to create a test helper to reduce code duplication:

import axe from 'axe-core';

const getAxe = () => {
  axe.reset();
  axe.configure({
    rules: [{
      id: 'color-contrast',
      enabled: false,
    }],
  });

  return axe;
};

export default getAxe;

And you can use this function in your tests.

Implementing with Jest+RTL

For Jest+RTL tests we'll be using "jest-axe" package that provides a function to configure axe object and a custom "toHaveNoViolations" matcher
Link to package's GitHub page - https://github.com/nickcolley/jest-axe?


In your test file import "jest-axe"

import { axe, toHaveNoViolations} from "jest-axe";

and extend jest's expect method with a custom matcher

expect.extend(toHaveNoViolations);

At this point you're ready to write accessibility test cases. Example:

it('should demonstrate this matcher`s usage with react testing library', async () => {
  const { container } = render(<App/>)
  const results = await axe(container)

  expect(results).toHaveNoViolations()
})


Additionally, you can configure axe to enable/disable certain rules. To do this import configureAxe helper from "jest-axe" and call it with your axe configuration options:

import { configureAxe } from "jest-axe";

const axe = configureAxe({
  rules: {
    'color-contrast': { enabled: false },
  },
});

More info on Deque aXe a11y rules: https://dequeuniversity.com/rules/axe/4.1


In case there are rules that you want to disable for all tests you might want to create a test helper to reduce code duplication:

import { configureAxe } from 'jest-axe';

const getAxe = (config = {}) => {
  return configureAxe({
    rules: {
      'meta-viewport': { enabled: false },
      'landmark-one-main': { enabled: false },
      'page-has-heading-one': { enabled: false },
      'bypass': { enabled: false },
    },
    ...config,
  });
};

export default getAxe;

And you can use this function in your tests.