jest-axe "Expected the HTML found at $X to have no violations" in CI
jest-axe ran axe-core against your rendered component and toHaveNoViolations() failed because axe returned a non-empty violations array. The message lists each rule id, its impact, and the failing element selector.
What this error means
A Jest test using expect(await axe(container)).toHaveNoViolations() fails with "Expected the HTML found at $(...) to have no violations:" followed by a rule id like color-contrast or image-alt and the offending node.
Expected the HTML found at $('button') to have no violations:
Received:
"Buttons must have discernible text (button-name)"
Fix any of the following:
Element does not have inner text that is visible to screen readers
aria-label attribute does not exist or is emptyCommon causes
The markup has a genuine WCAG violation
axe-core matched one of its rules (missing alt, no accessible name, low contrast) against the DOM your component rendered. It is a real defect, not a flaky test.
A new component or change introduced the violation
The rule passed before because the offending element did not exist. A recent edit added an image, button, or control without its accessible name or attribute.
How to fix it
Read the rule id and apply its documented fix
- Note the rule id in parentheses, for example
button-nameorimage-alt. - Apply the "Fix any of the following" remedy axe prints (add inner text, an
aria-label, or analtattribute). - Re-run the test so the violations array is empty.
// button-name: give the control a discernible name
<button aria-label="Close dialog">
<svg aria-hidden="true" ... />
</button>Scope a justified exception, not a blanket disable
If a rule is a confirmed false positive for one node, disable just that rule with a comment explaining why, rather than removing the assertion.
const results = await axe(container, {
rules: { 'color-contrast': { enabled: false } }, // decorative text, see A11Y-123
});How to prevent it
- Run jest-axe on every component in the test suite so violations surface at PR time.
- Fix the underlying WCAG issue rather than disabling rules broadly.
- Keep axe-core current so rule ids and messages match the docs you follow.