Uso con test-matchers

Para pruebas unitarias y de componentes: verifica la accesibilidad directamente dentro de una suite de Jest o Vitest, contra el DOM que la prueba ya tiene, en lugar de manejar un navegador real o headless. Si en cambio estás probando páginas completamente renderizadas, consulta las integraciones (binding) basadas en navegador.

@surea11y/test-matchers es un único matcher, toHaveNoA11yViolations(), que se conecta al expect.extend() de cualquiera de los dos frameworks sin modificaciones. No tiene código propio específico de ningún framework. Analiza cualquier entorno basado en jsdom bajo el que ya se ejecute tu prueba; no depende de jsdom en sí ni lo configura por ti. El motor de surea11y es síncrono, así que este matcher también lo es: sin await, sin el riesgo de olvidarlo y que la prueba se dé por superada sin esperar a que se resuelva la promesa.

$ npm install --save-dev @surea11y/test-matchers

Configuración

Tu entorno de pruebas ya debe estar basado en jsdom. Este matcher analiza cualquier document/window que proporcione. Registra el matcher una vez, en el archivo de configuración que tu ejecutor de pruebas ya cargue:

Jest

// jest.setup.js
expect.extend({
toHaveNoA11yViolations: require('@surea11y/test-matchers').toHaveNoA11yViolations
});
 
// jest.config.js
module.exports = {
testEnvironment: 'jsdom', // or the explicit jest-environment-jsdom package, depending on your Jest version
setupFilesAfterEnv: ['./jest.setup.js']
};

Vitest

// vitest.setup.js
import { expect } from 'vitest';
import { toHaveNoA11yViolations } from '@surea11y/test-matchers';
 
expect.extend({ toHaveNoA11yViolations });
 
// vitest.config.js
export default {
test: {
environment: 'jsdom', // Vitest doesn't bundle jsdom -- install it as a devDependency too
setupFiles: ['./vitest.setup.js']
}
};

El .d.ts incluido amplía tanto la interfaz global jest.Matchers de Jest como las interfaces @vitest/expect de Vitest, sin necesitar ningún import de @types/jest o vitest para distribuirlo: sea cual sea el framework realmente instalado, solo se activa la ampliación correspondiente.

Uso

Funciona contra un nodo DOM simple:

test('no accessibility violations', () => {
document.body.innerHTML = '<img src="logo.png">';
 
expect(document.body).toHaveNoA11yViolations(); // fails: missing alt
});

...o cualquier container de testing-library: el de React Testing Library, el wrapper.element de Vue Test Utils, el de Angular Testing Library, el de Svelte Testing Library, ya que todos exponen un elemento DOM renderizado de la misma manera:

const { render } = require('@testing-library/react');
 
test('MyComponent has no accessibility violations', () => {
const { container } = render(<MyComponent />);
 
expect(container).toHaveNoA11yViolations();
});

Esto también es agnóstico respecto al ejecutor de pruebas: los fragmentos anteriores son idénticos tanto si se ejecutan bajo Jest como bajo Vitest, una vez registrado el matcher.

Verificar con .not

test('a page with a violation fails the assertion', () => {
document.body.innerHTML = '<main><img src="logo.png"></main>';
 
expect(document.body).not.toHaveNoA11yViolations();
});

Reutilizar un análisis en varias aserciones

Si ya estás calculando tú mismo un resultado de análisis de surea11y (para verificar reglas específicas en varios bloques it() sin volver a analizar cada vez), pasa el objeto de resultado directamente en lugar de un nodo DOM:

const { runDomRulesInPage } = require('@surea11y/core');
 
const result = runDomRulesInPage(null, '#main', {}, null);
expect(result).toHaveNoA11yViolations();

Filtrar y configurar análisis

El segundo argumento acepta cualquier cosa que acepte @surea11y/core. Consulta Opciones del motor para ver la superficie completa. Algunos casos comunes:

// Only run rules relevant to WCAG 2.0 A
expect(container).toHaveNoA11yViolations({ tags: { include: 'wcag2a' } });
 
// Skip a rule you've decided not to enforce yet
expect(container).toHaveNoA11yViolations({ rules: { exclude: 'target-size-minimum' } });
 
// Ignore a third-party widget you don't control
expect(container).toHaveNoA11yViolations({ excludeSelectors: ['.intercom-launcher'] });

API

ParámetroTipoSignificado
receivedElement, Document o un resultado de análisisQué comprobar. Un Element/Document del DOM se analiza automáticamente; un objeto con la forma { checksResults: [...] } se verifica directamente, sin realizar ningún análisis. Cualquier otra cosa lanza un TypeError.
engineOptionsobjeto (opcional)Se pasa directamente al análisis de @surea11y/core: el mismo objeto de opciones usado en el resto del ecosistema (consulta Opciones del motor). Se ignora cuando received ya es un resultado de análisis.

Devuelve la forma { pass, message } que el expect.extend() de ambos frameworks espera: nunca llamas a esto directamente; se conecta una vez mediante expect.extend() como se muestra en Configuración más arriba.

Qué comprueba y qué no

Solo los resultados fail condicionan la aserción: coincidiendo con la convención del resto de integraciones de surea11y de que los resultados cantTell son informativos, no fallos. Un enlace vago como <a href="/pricing">Click here</a> es cantTell, no fail, así que nunca rompe por sí solo una prueba que pasa, aunque cuando una aserción falla por otros motivos, cualquier resultado cantTell se añade al mensaje de fallo como una nota aparte, para que siga siendo visible. Consulta Limitaciones conocidas para saber qué no automatiza en absoluto este motor.

Limitar el alcance a un elemento solo informa de lo que hay dentro de él. Un fallo en otra parte de la página nunca hace fallar una aserción limitada a un container. Internamente, el elemento analizado se marca temporalmente con un atributo único y se analiza mediante ese selector, de forma invisible para tu prueba.

Un puñado de reglas comprueban un hecho de toda la página, no algo en un subárbol concreto: page-title-present, html-lang-attr-present, y algunas otras comprueban document.title/document.documentElement directamente, ya que preguntar si la página tiene un título no tiene sentido para un fragmento de componente arbitrario. Pasar un Element (un container de testing-library, document.body) informa estas notApplicable en lugar de fail, así que un <title> faltante nunca rompe una prueba a nivel de componente; pasar el propio document sí las evalúa de verdad. Si analizas document directamente, define una vez el lang de document.title/document.documentElement en tu archivo de configuración en lugar de en cada prueba.

Mensajes de fallo

Enumera cada ocurrencia, no solo cada regla (una regla puede marcar varios elementos), con el ID de la regla, la gravedad, un resumen legible, el selector del elemento que falla, y una pista de corrección cuando está disponible:

expected no accessibility violations, but found 1:
1) img-alt-present (serious): Missing alt attribute on <img>.
at html > body > img
Add an alt attribute or use alt="" for decorative images.

Los resultados cantTell que acompañen a los fallos se añaden como una nota aparte, para que siga siendo visible sin afectar a pass/fail:

2 rule(s) need manual review (cantTell, not counted as failures): link-name-quality-manual, color-contrast-computable

Ejemplos ejecutables, en paralelo, para ambos frameworks: Jest y Vitest. Para la superficie completa de engineOptions (locale, modos de contraste, shadow DOM, reglas personalizadas, combinaciones de etiquetas de versión de WCAG), consulta ENGINE_OPTIONS.md. Este paquete reenvía todo lo que le pasas en lugar de duplicar esa referencia.