Die besten Accessibility Testing Tools 2026 im Überblick: axe core, Pa11y und cypress axe in vier Ebenen von Shift Left bis zur CI Pipeline.
Mehr erfahren
Ein Tag inhouse mit Roland Golla, offizieller Cypress Ambassador und seit über 20 Jahren in Testing und Refactoring zu Hause. Auf unserem YouTube Kanal zeigt er in über 70 Live Coding Tutorials, wie Cypress in echten Projekten läuft. Dazu kommt unser Open Source Plugin NCA TESTIFY: Basistests für jede Website, mit einer Zeile im CI/CD Setup. Im Workshop lernt euer Team Setup, stabile Selektoren, Custom Commands und Tests in der Pipeline.
describe('Profil', () => {
it('speichert Änderungen', () => {
cy.visit('/einstellungen')
cy.getByRole('textbox', { name: 'Anzeigename' }).type('Jane Doe')
cy.getByRole('button', { name: 'Änderungen speichern' }).click()
cy.getByRole('alert').should('have.text', 'Gespeichert')
})
})
<button>Speichern</button>
<div role="button" tabindex="0">Abbrechen</div>
// findet und klickt den nativen Button
cy.getByRole('button', { name: 'Speichern' }).click()
// das div hat die Rolle nur über das Attribut und wird übersprungen
cy.getByRole('button', { name: 'Abbrechen' }).should('not.exist')
// der aktive Tab
cy.getByRole('tab').filter('[aria-selected="true"]')
// Überschriften der Ebene 2
cy.getByRole('heading').filter('[aria-level="2"], h2:not([aria-level])')
// eine angehakte native Checkbox
cy.getByRole('checkbox').filter(':checked')
// ein geöffnetes Menü
cy.getByRole('button').filter('[aria-expanded="true"]')
// der Link zur aktuellen Seite
cy.getByRole('link').filter('[aria-current="page"]')
// alle Buttons, die nicht deaktiviert sind
cy.getByRole('button').not(':disabled, [aria-disabled="true"]')
cy.getByRole('dialog', { name: 'Projekt löschen', native: false }).should('be.visible')
// cypress/support/commands.js
Cypress.Commands.overwriteQuery(
'getByRole',
function (originalFn, role, options = {}) {
return originalFn.call(this, role, { native: false, ...options })
}
)
// vorher: Cypress Testing Library
cy.findByRole('button', { name: 'Bestellen' }).click()
cy.findAllByRole('listitem').should('have.length', 3)
cy.findByRole('tab', { selected: true }).should('have.text', 'Versand')
// nachher: eingebaut in Cypress
cy.getByRole('button', { name: 'Bestellen' }).click()
cy.getByRole('listitem').should('have.length', 3)
cy.getByRole('tab').filter('[aria-selected="true"]').should('have.text', 'Versand')
Role-based queries are a core way to write resilient, accessible tests
Die besten Accessibility Testing Tools 2026 im Überblick: axe core, Pa11y und cypress axe in vier Ebenen von Shift Left bis zur CI Pipeline.
Mehr erfahren
cy.prompt übersetzt Testschritte in natürlicher Sprache in Cypress Befehle. Funktionsweise, Codebeispiel, Grenzen und Review, eingeordnet von NCA.
Mehr erfahren
Wir sind hier, um Ihnen zu helfen. Gemeinsam meistern wir Ihre digitalen Herausforderungen und fördern die Inklusion im Internet. Lassen Sie uns Ihre Projekte mit barrierefreiem Webdesign erfolgreich machen.
cy.getByRole ist eine eingebaute Cypress Query, die Elemente über Rolle und Accessible Name findet. Die Rolle ist das, was ein Screenreader ansagt, etwa Button oder Link. Der Name ist der Text dazu. Die Query liefert alle Treffer, wartet automatisch und braucht kein Plugin. Sie ist die erste Testing Library Query, die Cypress direkt in den Kern holt.
cy.getByRole steckt in Cypress ab Version 16.2.0. Ein Update reicht, eine zusätzliche Installation brauchst du nicht. Wer vorher schon ein eigenes getByRole als Custom Command angelegt hat, bekommt nach dem Update einen Fehler, weil der Name jetzt belegt ist. Dann den eigenen Command umbenennen oder entfernen und die eingebaute Query nutzen.
Für Rollen Abfragen nicht mehr. cy.getByRole ersetzt findByRole und findAllByRole ohne Plugin. Nutzt du weitere Queries wie findByLabelText, behalte das Paket vorerst. Beide laufen nebeneinander, weil Testing Library nur findBy Queries registriert. Bedenke aber, dass das Paket keinen aktiven Maintainer mehr hat. Cypress plant, weitere Queries einzubauen.
Meist reicht es, den Namen zu tauschen. Drei Stellen brauchen Aufmerksamkeit: Native Elemente sind Default, also schlagen Tests auf ein div mit role fehl. cy.getByRole liefert alle Treffer, statt bei mehreren zu scheitern. Zustände wie checked oder selected wandern in ein angehängtes .filter(). Stell Spec für Spec um und lass die Suite nach jedem Schritt laufen.
Ja, für neue Tests ist cy.getByRole ein sehr guter erster Griff. Rollen und Namen ändern sich selten aus Versehen, deshalb halten die Tests auch ein Redesign aus. Gleichzeitig prüft jeder Test, ob ein Element die richtige Semantik hat. Wo Rolle und Text egal sind, bleiben data-cy Attribute die stabilste Wahl.
cy.getByRole trifft für Rollen mit nativem HTML Element nur das echte Element. Ein div mit role="button" zählt nicht. Du kannst native: false mitgeben oder besser das div durch einen echten button ersetzen. Dann bekommen Tastatur und Screenreader Nutzer das eingebaute Verhalten, und dein Test braucht keine Sonderoption.
Mit native: false trifft cy.getByRole auch Elemente, die ihre Rolle nur über das role Attribut bekommen. Das brauchst du für Komponenten Bibliotheken, Autocomplete Felder mit role combobox oder Icons als svg mit role img. Für Rollen ohne HTML Gegenstück wie tab oder switch ist die Option überflüssig. Projektweit setzt du sie per overwriteQuery in der Support Datei.
Mit einem angehängten .filter(). Für die Checkbox schreibst du cy.getByRole('checkbox').filter(':checked'). Für Überschriften der Ebene 2 filterst du auf aria-level="2" oder ein h2 ohne aria-level. Nach dem gleichen Muster prüfst du ausgeklappte Menüs, gedrückte Toggle Buttons oder den aktiven Link mit aria-current.
Nein, beide haben ihren Platz. data-cy ist unabhängig von Text, Rolle und HTML und damit maximal stabil. cy.getByRole prüft mit, ob ein Element für Menschen und assistive Technik verständlich ist. Bei mehreren gleichen Buttons kombinierst du beides: erst die Rolle, dann .filter() mit dem data-cy Attribut.
Nein. cy.getByRole prüft nur die Elemente, die dein Test anfasst. Fehlende Labels, schwachen Kontrast oder kaputtes ARIA an anderen Stellen findet ein Scan mit axe-core, etwa über cypress-axe oder Cypress Accessibility in Cypress Cloud. Dazu kommen manuelle Tests mit Tastatur und Screenreader. cy.getByRole ist ein Baustein, kein vollständiges Audit.
Ja. Du gibst includeShadowDom: true mit, setzt die gleichnamige Option in der Cypress Konfiguration oder hängst cy.getByRole an .shadow() an. Damit klappen Rollen Abfragen auch in Web Components. Mit .within() begrenzt du die Suche außerdem auf einen Bereich der Seite, etwa ein Formular oder einen Dialog.
Gut. cy.getByRole bindet Tests an Rollen und Namen, die selten aus Versehen kippen. cy.prompt repariert Schritte per Self Healing und markiert jede Reparatur zum Review. Stehen Rollen und aria-label in der ElementSelector Priorität oben, muss cy.prompt seltener eingreifen. So bleiben generierte Tests näher an dem, was Nutzer wirklich sehen.