Tests schreiben mit Axe DevTools Cypress
Barrierefreiheitstests mit Axe DevTools für Web in Cypress schreiben
Das Erzeugen von Barrierefreiheitsscannergebnissen mit Axe DevTools kann so einfach wie eine Codezeile sein. Diese Ergebnisse können unverarbeitet genutzt, in Verbindung mit einer Assertionsbibliothek verwendet oder zur Erstellung von Barrierefreiheitsberichten genutzt werden.
@axe-devtools/cypress unterstützt Cypress 4 bis 13. Diese Anweisungen beschreiben das Projektlayout, das in Cypress 10.0 eingeführt wurde. Wenn Sie noch Cypress 9 oder früher verwenden, platzieren Sie Ihre Spezifikationen in cypress/integration, registrieren Sie das Plugin in cypress/plugins/index.js und fügen Sie den Import stattdessen in cypress/support/index.js ein.
Voraussetzungen
Um Seiten mit Axe DevTools zu testen, müssen Sie es zuerst in Ihrem Projekt installiert haben. Wenn Sie diesen Schritt noch nicht abgeschlossen haben, sehen Sie sich die Installationsleitfaden an.
Projektstruktur
.
├── package.json
├── cypress.config.js
├── cypress
│ ├── e2e
│ │ └── test.cy.js
│ └── support
│ └── e2e.js
└── results
└── broken-workshop.jsonCypress 10.0 ersetzte die cypress.json-Konfigurationsdatei durch cypress.config.js (oder cypress.config.ts), benannte das cypress/integration-Spezifikationsverzeichnis in cypress/e2e um, benannte cypress/support/index.js in cypress/support/e2e.js um und entfernte das cypress/plugins-Verzeichnis zugunsten der setupNodeEvents-Funktion in der Konfigurationsdatei. Spezifikationsdateien verwenden das Suffix .cy.js anstelle von .spec.js.
Das results-Verzeichnis enthält die von Ihren Tests erstellten JSON-Scan-Ergebnisse. Cypress erstellt es beim ersten Schreiben, sodass Sie es nicht selbst hinzufügen müssen.
Einrichtung
Folgendes ist erforderlich, um Axe DevTools Cypress zu verwenden. Die Einrichtung wird in JavaScript und in TypeScript gezeigt. Cypress liest beide Extensions, sodass ein TypeScript-Projekt cypress.config.ts-, cypress/support/e2e.ts- und .cy.ts-Spezifikationsdateien anstelle ihrer jeweiligen .js-Gegenstücke verwendet.
JavaScript
Fügen Sie die folgende Zeile in cypress/support/e2e.js ein:
import '@axe-devtools/cypress';In der Datei cypress.config.js müssen Sie Folgendes hinzufügen:
const { defineConfig } = require('cypress');
const axeDevtoolsCypressPlugin = require("@axe-devtools/cypress/dist/plugin");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
axeDevtoolsCypressPlugin(on);
return config;
}
}
});TypeScript
Fügen Sie ein tsconfig.json neben Ihren Spezifikationen hinzu, damit TypeScript die Cypress- und Node-Typen erkennt:
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}Fügen Sie die folgende Zeile in cypress/support/e2e.ts ein. Die Paketimportierung registriert auch die Typen für cy.axeAnalyze(), cy.getAxeResults() und die anderen Axe DevTools-Befehle, sodass @axe-devtools/cypress kein separates @types/-Paket benötigt:
import '@axe-devtools/cypress';Im cypress.config.ts-File müssen Sie Folgendes hinzufügen. Das Plugin wird als CommonJS-Einstiegspunkt veröffentlicht, daher laden Sie es mit require, auch in TypeScript:
import { defineConfig } from 'cypress';
const axeDevtoolsCypressPlugin = require('@axe-devtools/cypress/dist/plugin');
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
axeDevtoolsCypressPlugin(on);
return config;
}
}
});Vollständige Beispieldatei
Rufen Sie cy.axeAnalyze() und cy.getAxeResults() innerhalb jedes it()-Blocks auf und verwenden Sie für jeden Test einen eindeutigen Dateinamen, um ein Überschreiben der Ergebnisse aus anderen Tests zu vermeiden.
JavaScript
Fügen Sie diesen Code in die Datei test.cy.js im e2e-Verzeichnis ein:
describe('Axe DevTools Cypress', () => {
it('Scans the home page for accessibility issues', () => {
// Visit the page to test
cy.visit('https://broken-workshop.dequelabs.com')
// Run an accessibility scan on the current page
cy.axeAnalyze()
// Write results to a uniquely named file; use a different name for each test to avoid overwriting
cy.getAxeResults().then(results => {
cy.writeFile('./results/broken-workshop.json', results)
})
})
})TypeScript
Fügen Sie diesen Code in die test.cy.ts-Datei im e2e-Verzeichnis ein. Die vom Paket registrierten Befehlstypen geben results den Typ AxeDevToolsResults | null, daher müssen Sie es einschränken, bevor Sie es an cy.writeFile() übergeben, das null nicht akzeptiert:
describe('Axe DevTools Cypress', () => {
it('Scans the home page for accessibility issues', () => {
// Visit the page to test
cy.visit('https://broken-workshop.dequelabs.com')
// Run an accessibility scan on the current page
cy.axeAnalyze()
// Write results to a uniquely named file; use a different name for each test to avoid overwriting
cy.getAxeResults().then(results => {
if (!results) {
throw new Error('cy.getAxeResults() returned no results')
}
cy.writeFile('./results/broken-workshop.json', results)
})
})
})Ein einsatzbereites TypeScript-Projekt ist im Axe DevTools API-Beispiel-Repository verfügbar.
Führen Sie Ihre Tests aus
Fügen Sie Skripte zu Ihrem package.json hinzu, damit Sie die Suite ohne Benutzeroberfläche in CI ausführen oder die Cypress-App öffnen können, während Sie Tests schreiben:
{
"scripts": {
"test": "cypress run",
"test:open": "cypress open"
}
}Führen Sie alle Spezifikationen in cypress/e2e ohne Benutzeroberfläche mit npm test aus oder öffnen Sie die interaktive Cypress-App mit npm run test:open. Um eine einzelne Spezifikation auszuführen, übergeben Sie das --spec-Flag: npx cypress run --spec cypress/e2e/test.cy.js.
Cross-Origin und Sandbox-Iframes
cy.axeAnalyze() injiziert axe-core in die zu testende Seite und in jedes erreichbare iframe. Iframes, in die Cypress nicht injizieren kann, einschließlich Cross-Origin-Iframes und Iframes mit einem sandbox-Attribut, werden übersprungen: Der Scan wird fortgesetzt und meldet Ergebnisse für den Rest der Seite, anstatt den Test fehlschlagen zu lassen. Der Inhalt innerhalb eines übersprungenen iframes wird nicht analysiert; testen Sie daher diese Seiten direkt in ihren eigenen Spezifikationen, wenn Sie eine Abdeckung benötigen.
