axe-core für automatisierte Barrierefreiheitsprüfung in der Vue-CI-Pipeline
AI generated
{ }
Vue · Accessibility · CI
axe-core in der CI-Pipeline
Automatisierte Barrierefreiheitsprüfung für Vue-Anwendungen

axe-core prüft eine gerenderte Seite gegen einen festen Katalog automatisierbarer Barrierefreiheitsregeln, etwa Farbkontrast, fehlende Formular-Labels oder falsch verschachtelte Überschriften, und lässt sich sowohl über @axe-core/playwright in End-to-End-Tests als auch über vitest-axe in Komponententests einbinden. Wichtig ist dabei, die Grenzen automatisierter Prüfung zu kennen, denn Tab-Reihenfolge-Logik und inhaltliche Verständlichkeit lassen sich damit nicht abdecken.

14 Min. Lesezeit axe-core Accessibility CI

1. Was axe-core automatisiert prüfen kann

axe-core ist eine Regel-Engine, die den gerenderten DOM einer Seite analysiert und gegen einen umfangreichen Katalog von Barrierefreiheitsregeln prüft, die größtenteils aus den WCAG-Richtlinien abgeleitet sind. Zu den zuverlässig automatisiert erkennbaren Verstößen gehören unzureichender Farbkontrast zwischen Text und Hintergrund, fehlende label-Elemente oder aria-label-Attribute an Formularfeldern, Bilder ohne alt-Attribut, sowie strukturelle Probleme wie doppelt vergebene IDs oder falsch verschachtelte Überschriftenebenen.

Diese Regeln lassen sich zuverlässig automatisieren, weil sie sich rein aus der Struktur und den berechneten Stileigenschaften des DOM ableiten lassen, ohne dass ein Mensch beurteilen müsste, ob ein Text inhaltlich sinnvoll ist oder eine Interaktion tatsächlich intuitiv bedienbar ist. axe-core deckt nach eigenen Angaben etwa 30 bis 50 Prozent der insgesamt bekannten Barrierefreiheitsprobleme ab, was bedeutet, dass eine bestandene axe-core-Prüfung eine notwendige, aber keine hinreichende Bedingung für tatsächliche Barrierefreiheit ist.

2. Setup mit vitest-axe für Komponententests

Für isolierte Komponententests bindet vitest-axe axe-core direkt in Vitest ein und erweitert die Test-Assertions um einen toHaveNoViolations()-Matcher. Nach dem Rendern einer Komponente mit Vue Test Utils wird deren HTML-Ausgabe an axe-core übergeben, das die Prüfung gegen den gesamten Regelkatalog durchführt und eine Liste gefundener Verstöße zurückgibt, die der Matcher dann gegen eine leere Erwartung prüft.

Dieser Ansatz eignet sich besonders für einzelne, wiederverwendbare Komponenten wie Buttons, Formularfelder oder Modals, weil Verstöße hier auf Komponentenebene erkannt werden, bevor sie sich in jede Seite verbreiten, die diese Komponente verwendet. Ein fehlendes ARIA-Attribut an einer zentralen Button-Komponente wird so schon im Komponententest sichtbar, statt erst in einem aufwendigeren End-to-End-Test auf einer kompletten Seite entdeckt zu werden.


import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import { axe, toHaveNoViolations } from 'vitest-axe'
import FormField from '@/components/FormField.vue'

expect.extend(toHaveNoViolations)

describe('FormField Accessibility', () => {
  it('hat keine automatisiert erkennbaren Barrierefreiheits-Verstoesse', async () => {
    const wrapper = mount(FormField, {
      props: { label: 'E-Mail', modelValue: '', type: 'email' },
    })

    const results = await axe(wrapper.element)
    expect(results).toHaveNoViolations()
  })
})

3. Setup mit @axe-core/playwright für E2E-Tests

Für Prüfungen auf Ebene einer kompletten, im Browser gerenderten Seite kommt @axe-core/playwright zum Einsatz, das die axe-core-Engine über einen echten Browser-Kontext ausführt, nachdem Playwright die Seite geladen hat. Diese Variante erkennt zusätzlich Probleme, die erst durch das tatsächliche Zusammenspiel mehrerer Komponenten auf einer Seite entstehen, etwa doppelt vergebene IDs, die in isolierten Komponententests einzeln nicht auffallen, aber sobald mehrere Instanzen derselben Komponente auf einer Seite landen, zu einem echten Verstoß werden.

Der typische Ablauf besteht darin, dass Playwright zunächst zur Zielseite navigiert und gegebenenfalls einen bestimmten Anwendungszustand herstellt, etwa ein geöffnetes Modal oder ein ausgefülltes Formular, bevor AxeBuilder die Analyse gegen den aktuellen DOM-Zustand ausführt. Das erlaubt es, nicht nur den initialen Seitenzustand zu prüfen, sondern auch dynamisch erzeugte UI-Zustände wie geöffnete Dropdowns oder eingeblendete Fehlermeldungen, die in einer reinen Komponententest-Umgebung schwerer realistisch zu simulieren wären.

4. Was axe-core NICHT automatisiert erkennen kann

Die wichtigste Grenze automatisierter Prüfung betrifft die logische Tab-Reihenfolge und generell die tatsächliche Bedienbarkeit per Tastatur. axe-core kann prüfen, ob ein interaktives Element überhaupt fokussierbar ist, aber nicht, ob die Reihenfolge, in der Elemente per Tab-Taste erreicht werden, für einen Nutzer inhaltlich sinnvoll ist. Ein Formular, bei dem die Tab-Reihenfolge visuell von oben nach unten springt, aber im DOM in umgekehrter Reihenfolge steht, bleibt für axe-core unauffällig, verwirrt aber jeden Nutzer, der ausschließlich mit der Tastatur navigiert.

Ebenso wenig automatisierbar sind inhaltliche Qualitätsfragen wie die Verständlichkeit eines Alt-Textes, der zwar technisch vorhanden ist, aber nichtssagend formuliert wurde, etwa alt="Bild1" statt einer tatsächlichen Beschreibung. axe-core prüft nur, ob das Attribut existiert und nicht leer ist, nicht, ob der Inhalt für einen Screenreader-Nutzer tatsächlich hilfreich ist. Auch die Frage, ob eine Fehlermeldung für einen Screenreader-Nutzer im richtigen Moment und mit der richtigen Dringlichkeit angekündigt wird, erfordert oft manuelles Testen mit einem echten Screenreader.

5. Ein CI-Gate aufbauen, das kritische Verstöße blockiert

Ein sinnvolles CI-Gate unterscheidet zwischen Verstoß-Schweregraden, die axe-core selbst über die Kategorien critical, serious, moderate und minor klassifiziert. Ein pragmatischer Ansatz besteht darin, den Build bei critical- und serious-Verstößen fehlschlagen zu lassen, während moderate- und minor-Verstöße zunächst nur als Warnung im CI-Log erscheinen, ohne den Merge zu blockieren. Das verhindert, dass ein Team direkt zu Beginn der Einführung von einer großen Zahl bestehender, aber wenig kritischer Altlasten blockiert wird.

In der Praxis lässt sich dieses Vorgehen über die violations-Ausgabe von axe-core filtern und anschließend gezielt auf die kritischen Kategorien prüfen, bevor der Test-Runner den Prozess mit einem Fehlerstatus beendet. Über die Zeit lässt sich die Schwelle schrittweise verschärfen, etwa indem zunächst nur neue Komponenten strengen Regeln unterliegen, während bestehende Seiten über eine dokumentierte Ausnahmeliste vorübergehend ausgenommen werden, bis sie nachträglich bereinigt sind.

6. Bekannte Ausnahmen sauber dokumentieren

Nicht jeder von axe-core gemeldete Verstoß ist sofort behebbar, insbesondere wenn er in einer Drittanbieter-Komponente liegt, auf deren Markup kein direkter Zugriff besteht. Für solche Fälle bietet axe-core die Möglichkeit, bestimmte Regeln gezielt zu deaktivieren oder bestimmte Selektoren von der Prüfung auszuschließen, etwa über die disableRules()-Methode von AxeBuilder oder die rules-Option in der axe-Konfiguration.

Wichtig ist dabei, jede Ausnahme im Code direkt zu kommentieren und den Grund festzuhalten, warum sie besteht, statt sie stillschweigend zu deaktivieren. Eine unkommentierte Ausnahme sieht auf den ersten Blick wie eine erfolgreich bestandene Prüfung aus, verbirgt aber ein tatsächliches Problem, das irgendwann wieder sichtbar werden sollte, sobald sich die zugrunde liegende Ursache beheben lässt, etwa nach einem Update der betroffenen Drittanbieter-Bibliothek.

7. Laufzeit und Performance in der CI-Pipeline

axe-core-Prüfungen kosten zusätzliche Laufzeit in der CI-Pipeline, insbesondere bei @axe-core/playwright, wo für jede geprüfte Seite ein echter Browser-Kontext samt vollständigem Rendering nötig ist. Bei umfangreichen Anwendungen mit vielen Seiten lohnt es sich, nicht jede einzelne Seite bei jedem Commit vollständig zu prüfen, sondern eine repräsentative Auswahl kritischer Seiten regelmäßig zu testen und eine vollständige Prüfung aller Seiten seltener, etwa nächtlich oder vor einem Release, laufen zu lassen.

vitest-axe-Prüfungen auf Komponentenebene sind dagegen deutlich günstiger, weil kein echter Browser gestartet werden muss und nur der isolierte Komponentenbaum geprüft wird. Diese Komponententests lassen sich problemlos bei jedem Commit ausführen und bilden die schnelle erste Verteidigungslinie, während die aufwendigeren End-to-End-Prüfungen mit Playwright gezielter und seltener eingesetzt werden.

8. Warum manuelle Prüfung trotzdem nötig bleibt

Ein CI-Gate mit axe-core ersetzt keine manuelle Barrierefreiheitsprüfung, sondern reduziert die Zahl der Probleme, die überhaupt erst manuell entdeckt werden müssten. Gerade neu entwickelte, komplexe interaktive Komponenten wie mehrstufige Formulare, Datepicker oder Drag-and-Drop-Interfaces sollten zusätzlich mit tatsächlicher Tastaturnavigation und, wo möglich, mit einem echten Screenreader wie NVDA oder VoiceOver getestet werden, weil genau hier die automatisiert nicht abdeckbaren Probleme am häufigsten auftreten.

Ein sinnvoller Team-Workflow kombiniert automatisierte axe-core-Prüfung als frühen, schnellen Filter im CI mit einer manuellen Prüfungscheckliste für kritische User-Flows, die vor jedem größeren Release durchlaufen wird. Diese Kombination stellt sicher, dass offensichtliche, technische Verstöße gar nicht erst in Produktion gelangen, während die anspruchsvolleren, kontextabhängigen Aspekte der Barrierefreiheit durch gezielte menschliche Prüfung abgedeckt bleiben.

9. Den Regelsatz gezielt über WCAG-Tags konfigurieren

Sowohl @axe-core/playwright als auch vitest-axe erlauben es, den geprüften Regelsatz über Tags einzugrenzen, etwa wcag2a, wcag2aa oder wcag21aa, statt automatisch den vollständigen, sehr breiten Standardkatalog zu verwenden. Ein Team, das sich zunächst nur an den WCAG-Level-AA-Kriterien orientieren möchte, kann die Prüfung gezielt über withTags(['wcag2a', 'wcag2aa']) bei AxeBuilder auf genau diese Teilmenge beschränken, was die Ergebnisliste überschaubarer macht und die Einführung in einem bestehenden Projekt erleichtert.

Über diese Tag-basierte Eingrenzung hinaus lässt sich axe-core auch um eigene, projektspezifische Regeln erweitern, etwa um unternehmensinterne Designsystem-Konventionen zu prüfen, die über die Standard-WCAG-Kriterien hinausgehen. Diese Erweiterbarkeit macht axe-core nicht nur zu einem reinen WCAG-Prüfwerkzeug, sondern zu einer generellen Plattform für automatisierbare Qualitätsregeln rund um Barrierefreiheit, die sich an die tatsächlichen Anforderungen eines Projekts anpassen lässt, statt starr einem einzigen vorgegebenen Regelsatz zu folgen.

Automatisiert erkennbar (axe-core) NICHT automatisiert erkennbar
Unzureichender Farbkontrast Logische Tab-Reihenfolge
Fehlende Labels/ARIA-Attribute Inhaltliche Verständlichkeit von Alt-Texten
Fehlendes alt-Attribut an Bildern Tatsächliche Screenreader-Ankündigungsqualität
Doppelt vergebene IDs Intuitivität einer Interaktion
Falsch verschachtelte Überschriften Kontextabhängige Bedienbarkeit komplexer Widgets

Mironsoft

Vue-Architektur, Composition API und Nuxt-Performance

Vue-Anwendungen, die mit jedem Feature nicht komplizierter werden?

Wir prüfen bestehende Vue- und Nuxt-Projekte auf unstrukturierte Composables, ungenutzte Reaktivität und aufgeblähte Bundles und bauen daraus eine Architektur, die neue Features aufnimmt, ohne die Codebasis unübersichtlicher zu machen.

Architektur-Review

Composables, State-Management und Komponentenstruktur auf Wartbarkeit prüfen.

Performance-Audit

Reaktivitäts-Overhead, Bundle-Größe und Nuxt-Rendering-Strategie systematisch optimieren.

Nuxt-Integration

SSR/SSG-Setup und API-Anbindung robust und typsicher aufbauen.

10. Zusammenfassung

axe-core in der CI: Das Wichtigste auf einen Blick

Abdeckung

axe-core deckt schätzungsweise 30 bis 50 Prozent aller Barrierefreiheitsprobleme automatisiert ab

Werkzeuge

vitest-axe für Komponententests, @axe-core/playwright für vollständige Seiten

CI-Gate

kritische und ernste Verstöße blockieren den Build, kleinere nur als Warnung

Grenze

Tab-Reihenfolge-Logik und inhaltliche Qualität brauchen weiterhin manuelle Prüfung

11. FAQ: axe-core in der CI: Das Wichtigste auf einen Blick

1Was ist der Unterschied zwischen vitest-axe und @axe-core/playwright?
vitest-axe prüft isolierte Komponenten innerhalb eines Vitest-Testlaufs ohne echten Browser, @axe-core/playwright prüft vollständige, in einem echten Browser gerenderte Seiten mit Playwright.
2Wie viel Prozent der Barrierefreiheitsprobleme deckt axe-core ab?
Nach Angaben der Entwickler etwa 30 bis 50 Prozent der bekannten Probleme, weil viele Aspekte kontextabhängiges menschliches Urteilsvermögen erfordern.
3Kann axe-core die Tab-Reihenfolge prüfen?
Nein, axe-core kann prüfen, ob Elemente fokussierbar sind, aber nicht, ob die tatsächliche Reihenfolge der Fokussierung für einen Nutzer logisch sinnvoll ist.
4Sollte jeder axe-core-Verstoß den CI-Build blockieren?
Ein pragmatischer Ansatz blockiert nur bei critical- und serious-Verstößen, während moderate und minor zunächst nur als Warnung erscheinen, um die Einführung nicht zu blockieren.
5Wie gehe ich mit Verstößen in Drittanbieter-Komponenten um?
Über gezielte Ausnahmen mit disableRules() oder der rules-Option, wobei jede Ausnahme im Code kommentiert und begründet werden sollte.
6Ersetzt ein axe-core-CI-Gate manuelle Tests mit Screenreadern?
Nein, es reduziert nur die Zahl offensichtlicher, technischer Verstöße. Komplexe interaktive Komponenten sollten weiterhin manuell mit echten Screenreadern getestet werden.
7Verlangsamt axe-core die CI-Pipeline spürbar?
vitest-axe-Komponententests sind günstig und lassen sich bei jedem Commit ausführen. @axe-core/playwright-Tests sind teurer und eignen sich eher für eine repräsentative Auswahl kritischer Seiten.
8Kann axe-core prüfen, ob ein Alt-Text inhaltlich sinnvoll ist?
Nein, es prüft nur, ob das alt-Attribut existiert und nicht leer ist, nicht ob der Inhalt für einen Screenreader-Nutzer tatsächlich aussagekräftig ist.
9Welche Schweregrade unterscheidet axe-core?
critical, serious, moderate und minor, was eine differenzierte Entscheidung erlaubt, welche Kategorien den Build blockieren sollen.
10Lohnt sich axe-core auch für kleine Projekte?
Ja, weil schon die Basisprüfung wie fehlende Labels oder Kontrastprobleme früh im Entwicklungsprozess günstig zu beheben sind, statt erst spät im Projekt entdeckt zu werden.