# Test di accessibilità con axe: cosa trova e cosa no

axe controlla un componente React dentro il test: trova ruoli mancanti ed etichette assenti, ma non giudica contrasto, ordine di tabulazione o lettura.

> Pagina: https://ui.eneawork.it/blog/test-accessibilita-axe
> Markdown: https://ui.eneawork.it/blog/test-accessibilita-axe.md

*2026-11-01*

axe trova in un test le violazioni strutturali del DOM: ruoli mancanti, etichette assenti, gerarchia di titoli rotta. Non trova contrasto, ordine di tabulazione o senso di lettura.

Il catalogo EneUI conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, misurati da /api/stats il 1 novembre 2026. La cifra viene da una query all'endpoint, non da una stima, e dice quanti record sono pubblicati.

## La regola di base

axe-core, pubblicato da Deque con licenza MPL-2.0, esegue un set di regole sul DOM già renderizzato. Ogni violazione porta un impact: critical, serious, moderate o minor.

## Il test che vale come modello

import { render } from "@testing-library/react"; import { axe, toHaveNoViolations } from "jest-axe"; expect.extend(toHaveNoViolations); test("il dialog non ha violazioni critiche", async () => { const { container } = render(); const { violations } = await axe(container); expect(violations.filter((v) => v.impact === "critical")).toHaveLength(0); });

Il test renderizza, esegue axe e boccia solo critical. Filtrare per impatto tiene la CI verde: un test che fallisce per un aria-* deprecato viene spento dopo una settimana.

## Cosa controlla davvero

## Installazione

npm i -D vitest jsdom @testing-library/react jest-axe npx vitest run --environment jsdom

jest-axe è MIT e axe-core è MPL-2.0: entrambi girano in locale, senza servizi esterni e senza chiamate di rete.

## Record vivi nel catalogo

Tre record su cui provare il primo test: dialog, navigation-menu e dropdown-menu. Per esplorare per categoria parti da 111.985 componenti.

## La limitazione

In jsdom non c'è CSS: la regola color-contrast non può girare e axe la salta in silenzio. Il test automatico copre una parte dei criteri WCAG, non tutti: contrasto, focus visibile e lettura con screen reader restano manuali.

## Dove continuare

La checklist manuale è in componenti React accessibili; il caso del modale è in dialog accessibile; il modello di test è in Testing Library: cinque test; il confronto misurato fra librerie è in librerie React 2026.

## FAQ

### axe sostituisce un test manuale?

No. Copre una parte dei criteri WCAG e lascia fuori contrasto, focus e lettura: il test manuale resta obbligatorio.

### Perché il contrasto non viene controllato?

Perché jsdom non applica CSS. Senza colori calcolati e layout la regola non ha nulla da misurare, quindi viene saltata.

### Meglio jest-axe o vitest-axe?

Sono lo stesso motore. jest-axe funziona con Vitest dopo expect.extend, quindi non serve un pacchetto diverso.

### Quante violazioni deve avere un componente per passare?

Zero critical. Le violazioni serious e moderate si correggono, ma non bloccano la pipeline.

### axe-core è gratis per uso commerciale?

Sì. axe-core è MPL-2.0 e jest-axe è MIT: uso commerciale permesso, con obbligo di pubblicare le modifiche al motore.
