Axe-core: axe.run() context doesn't accept a document object provided by Cypress

Created on 2 Mar 2018  路  5Comments  路  Source: dequelabs/axe-core

Cypress runs its in browser tests in a complex system of iFrames, with its spec file in a separate HTML frame to the application.

The Cypress API provides ways to reference to the application document object, e.g.:

cy.document().then((doc) => {
  // 'doc' is the application document object
}

However Axe doesn't recognize that 'doc' object as valid, and reverts back to using the default document object (which is the test runner frame mentioned above). @marcysutton has done preliminary investigation and pinpointed this location as where that happens:
https://github.com/dequelabs/axe-core/blob/develop/lib/core/public/run.js#L40

Full example:

    cy.visit('https://dequelabs.github.io/axe-fixtures/shadow-dom.html')
    .then(function(win) {
      var axe = require('axe-core');
      console.log(win.document); // The correct application document object
      return axe.run(win.document).then(function(results) {
        // This fails because it's incorrectly asserted against 'document' rather than 'win.document':
        expect(results.violations[0].id).to.equal('color-contrast');
      })
    })
core feat

Most helpful comment

@JazzBrotha here is something that is more comprehensively tested :-)

describe('Inject axe-core and run it', function() {
  it('Runs axe-core', function() {
    cy.visit('your URL here')
      .window().then((win) => {
        var window = win;
        var axe = require('axe-core');
        window.eval(axe.source);
        return window.axe.run();
      }).then((results) => {
        console.log(results);
        expect(results.violations.length).to.equal(0);
      })
  })
})

All 5 comments

Solution found

describe('Inject axe-core and run it', function() {
  it('Runs axe-core', function() {
    cy.visit('your page')
      .window().then((win) => {
        var window = win;
        var document = win.document;
        var axe = require('axe-core');
        return axe.run(window.document);
      }).then((results) => {
        console.log(results);
        expect(results.violations.length).to.equal(0);
      })
  })
})

@dylanb's solution returns the correct document in Cypress, but the violations reported by aXe are not correct. When running the aXe Chrome extension on the page, different violations are reported, and they are the right ones. For example, when running aXe in Cypress it reports that there is no lang attribute for the document, which is false. It also misses some color contrast violations.

@JazzBrotha here is something that is more comprehensively tested :-)

describe('Inject axe-core and run it', function() {
  it('Runs axe-core', function() {
    cy.visit('your URL here')
      .window().then((win) => {
        var window = win;
        var axe = require('axe-core');
        window.eval(axe.source);
        return window.axe.run();
      }).then((results) => {
        console.log(results);
        expect(results.violations.length).to.equal(0);
      })
  })
})

@dylanb Works great! Big thanks!

However, for debugging purposes in Cypress this might be more fitting:

expect(results.violations).to.be.empty

This way, you get the aXe violation objects in your assertion error.

@dylanb works great for me too - thank you!!

Was this page helpful?
0 / 5 - 0 ratings