Lección 9 de 10 · 16 min de lectura · Revisado el 26/10/2026
Pruebas automáticas en el flujo de desarrollo: axe-core, eslint-plugin-jsx-a11y, Lighthouse y tests e2e
Corregir un problema de accesibilidad en producción cuesta mucho más que evitarlo en el editor. Las herramientas automáticas no encuentran todos los problemas, pero encuentran los más repetitivos de forma inmediata, consistente y gratuita, y sobre todo impiden que vuelvan. Esta lección explica qué herramienta encaja en cada punto del flujo de desarrollo, cómo configurarlas y, con la misma importancia, qué no pueden hacer.
Qué detectan y qué no
Se estima que las herramientas automáticas detectan aproximadamente entre el 30 % y el 40 % de los problemas de accesibilidad; el porcentaje real depende del tipo de sitio. Detectan muy bien lo que es sintáctico y determinista: imágenes sin alt, campos sin etiqueta, contraste insuficiente de texto sobre fondo plano, atributos ARIA inválidos, id duplicados, falta de lang, enlaces sin nombre, encabezados que saltan niveles, elementos enfocables ocultos. No pueden detectar si el alt es correcto, si el orden del foco tiene sentido, si el estado ARIA se actualiza, si el nombre de un botón describe su acción, si un modal devuelve el foco, si un carrusel se puede pausar o si un texto es comprensible. Por eso las pruebas automáticas se complementan siempre con el protocolo de teclado del curso anterior y con revisión con lector de pantalla.
Punto clave
«Cero errores en axe» significa que no hay errores de los que axe sabe detectar. Es la línea de salida, no la meta. Úsalo como red de seguridad para que nada que ya funcionaba se rompa, y dedica el tiempo humano a lo que las máquinas no ven.
axe-core: el motor común
axe-core, de Deque, es la biblioteca de reglas de accesibilidad de código abierto que está detrás de la extensión axe DevTools, de Lighthouse, de Accessibility Insights de Microsoft y de muchas integraciones. Su filosofía es no dar falsos positivos: cuando marca algo como error, casi siempre lo es; a cambio, marca como «necesita revisión» lo que no puede decidir (contraste sobre imágenes, por ejemplo). Se integra en varios puntos:
- Navegador: extensión axe DevTools para analizar la página actual durante el desarrollo.
- Pruebas unitarias de componentes:
jest-axeovitest-axeejecutan las reglas sobre el HTML renderizado por un componente. - Pruebas de extremo a extremo:
@axe-core/playwrightycypress-axeanalizan páginas reales en el navegador, en cada estado (modal abierto, formulario con errores). - Desarrollo en React:
@axe-core/reactmuestra los problemas en la consola mientras programas, pero solo admite hasta React 17; en versiones posteriores, usa la extensión o las pruebas de componentes.
Ejemplo
Prueba de extremo a extremo con Playwright que analiza la página de inicio y, además, el estado con el diálogo abierto:
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('cita previa sin errores de accesibilidad', async ({ page }) => {
await page.goto('/tramites/cita-previa');
const inicial = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'])
.analyze();
expect(inicial.violations).toEqual([]);
await page.getByRole('button', { name: 'Elegir centro' }).click();
const conDialogo = await new AxeBuilder({ page }).analyze();
expect(conDialogo.violations).toEqual([]);
});Observa dos cosas: se filtran las reglas por etiquetas de WCAG para que el informe hable el idioma del equipo, y se analiza cada estado de la interfaz, no solo la carga inicial.
Las pruebas de extremo a extremo también sirven para automatizar parte del protocolo de teclado: Playwright permite pulsar Tab y comprobar qué elemento tiene el foco, pulsar Escape y verificar que el diálogo se cierra y el foco vuelve al botón, o pulsar flechas en unas pestañas y comprobar aria-selected. Y los locators por rol (getByRole('button', { name: 'Guardar' })) convierten cada test en una verificación implícita de que los controles tienen rol y nombre accesibles: si no los tienen, el test no encuentra el elemento.
Linting: atrapar errores al escribir
eslint-plugin-jsx-a11y analiza el JSX de React en el editor y en la integración continua, antes de que exista una página que probar. Detecta imágenes sin alt, onClick en elementos no interactivos sin rol ni teclado, aria-* inválidos, label sin control asociado, autoFocus, accessKey, enlaces sin href, roles no soportados y más. Se activa con la configuración plugin:jsx-a11y/recommended y conviene usar el modo strict en proyectos nuevos. Para Vue existe eslint-plugin-vuejs-accessibility, y para Angular, las reglas de accesibilidad de angular-eslint (plantillas) cubren casos parecidos. Para HTML estático, html-validate incluye reglas de accesibilidad y el validador del W3C detecta errores de marcado que repercuten en las tecnologías de apoyo.
Lighthouse y las auditorías de página
Lighthouse (integrado en Chrome y ejecutable en CI con lighthouse-ci) usa un subconjunto de reglas de axe y devuelve una puntuación de 0 a 100. Esa puntuación es útil para seguir la tendencia y para que la dirección la entienda, pero es engañosa como medida de conformidad: una página con 100 puede ser inaccesible (orden de foco, estados ARIA, modales) y una con 85 puede tener solo problemas menores. Úsala como indicador, nunca como certificado. Pa11y y pa11y-ci hacen lo mismo con el motor HTML CodeSniffer o axe y son cómodos para rastrear decenas de URL de un sitio en cada despliegue.
Dónde colocar cada herramienta
| Momento | Herramienta | Qué aporta |
|---|---|---|
| Al escribir código | eslint-plugin-jsx-a11y, html-validate, @axe-core/react (hasta React 17) | Errores de marcado y ARIA al instante |
| Pruebas de componentes | jest-axe, vitest-axe | Cada componente del sistema de diseño limpio en todos sus estados |
| Pruebas e2e | @axe-core/playwright, cypress-axe + aserciones de teclado | Páginas reales, flujos completos, modales, errores de formulario |
| Integración continua | pa11y-ci, lighthouse-ci | Rastreo de URL y tendencia de puntuación |
| Revisión manual | axe DevTools, Accessibility Insights, inspector del navegador | Exploración guiada y comprobación de lo que las máquinas no ven |
Error frecuente
Instalar axe en CI, ver 300 errores heredados y desactivar la comprobación «hasta que haya tiempo». Mejor: fija el número actual como umbral máximo (no puede crecer), corrige por lotes y baja el umbral en cada iteración. Y configura la prueba para que falle solo con errores de impacto crítico y grave al principio, ampliando después.
Definición de hecho
Para que todo esto tenga efecto, la accesibilidad debe formar parte de los criterios de aceptación de cada historia y de la definición de hecho del equipo. Una versión mínima:
- El linter de accesibilidad no muestra errores.
- Las pruebas de componente con axe pasan en todos los estados.
- Las pruebas e2e con axe pasan en las páginas y flujos tocados.
- Quien revisa el código ha recorrido la funcionalidad con teclado siguiendo el protocolo.
- Los componentes nuevos se han probado con un lector de pantalla y documentan su teclado.
Con esta cadena, los problemas que las máquinas detectan no vuelven, y el tiempo de las personas se concentra en lo que requiere criterio humano.
Resumen
- Las herramientas automáticas detectan en torno a un tercio de los problemas, los sintácticos y deterministas; el resto exige teclado, lector de pantalla y criterio humano.
- axe-core es el motor común: extensión, jest-axe/vitest-axe en componentes, @axe-core/playwright o cypress-axe en e2e.
- eslint-plugin-jsx-a11y (y equivalentes para Vue y Angular) atrapa los errores al escribir.
- La puntuación de Lighthouse es un indicador de tendencia, no un certificado de conformidad.
- Fija umbrales que no puedan crecer, analiza cada estado de la interfaz y haz de la accesibilidad parte de la definición de hecho.
Comprueba lo que has aprendido
Esta lección se puede leer libremente. Para hacer su test de 3 preguntas, los ejercicios prácticos con páginas reales, guardar tu avance y optar al examen y al certificado, matricúlate en el curso.