Ausgabeschema
Dies ist die genaue Struktur des Objekts, das runDomRulesInPage(...) / runa11yCoreInPage(...) zurückgibt (welche davon Sie aufrufen, steht in INTEGRATION.md). Jedes Beispiel auf dieser Seite ist echte Ausgabe der aktuellen Engine (schemaVersion: "1.0.0"), nicht von Hand geschrieben. runa11yCoreAcrossFrames gibt eine andere, rekursive Struktur zurück, die diese umschließt, siehe Frame-übergreifendes Ergebnis unten.
Ergebnis auf oberster Ebene
{engine: {tag: string,version: string, // the @surea11y/core release that produced the resultschemaVersion: string,locale: { requested: string, resolved: string, reason: string },wcagVersion: "2.0" | "2.1" | "2.2",wcagLevel?: "A" | "AA" | "AAA",profile?: string, // "wcag22-aa", "en301549-v4.1.1", "en301549-v3.2.1", "section508", or a registered standard's ownmappings?: string[], // e.g. ["en301549"] or ["en301549:V3.2.1"]profileExcludes?: { rules: string[], criteria: string[] },optInRules?: string[],outputDetail?: "findings",packs?: string[], // name@versionenvironment: {layout: boolean,viewport?: { width: number, height: number }, // CSS pxdevicePixelRatio?: number,colorScheme?: "light" | "dark",forcedColors?: "active" | "none",forcedColorsCss?: true, // under forced colors, when the page's own CSS reacts to themfonts?: "loaded" | "loading",images?: "loaded" | "loading",animationsSettled?: number,internalsHook?: "early" | "late", // only where the page runs the internals hooklistenerHook?: "early" | "late", // only where the page runs the listener hookliveRegionHook?: "early" | "late" // only where the page runs the live-region hook}},url: string | null,title: string | null,timestamp: string | null,perfStats: object | null,contextSelector: string | string[] | null,contextMatch: { elementCount: number, unmatchedSelectors: string[] } | null,checksResults: CheckResult[],rulesResults: CompositeResult[],standards?: Array<{ key: string, standard: string, titleLang?: string, note?: string }>,overriddenBuiltinIds: string[],skippedCustomRules: Array<{ id: string | null, reason: string, excluded?: true }>,skippedPacks?: Array<{ name: string | null, reason: string }>}
| Feld | Bedeutung |
|---|---|
engine.tag | Das Identitäts-Tag der Engine, derzeit "a11ycore". Jede Regel (eingebaut oder eigene) trägt es in meta.tags; die ruleIds der Regeln selbst stehen ohne Präfix. |
engine.version | Das Release von @surea11y/core, das das Ergebnis erzeugt hat, etwa "1.11.1": Das geben Sie in einem Fehlerbericht an, und daran unterscheiden Sie Ergebnisse aus zwei Releases. Ein Ergebnis kann sich zwischen Releases ändern, ohne dass sich seine Struktur ändert, deshalb ist das nicht schemaVersion. Die Reporter für SARIF und EARL verwenden es als Tool-Version, wenn Sie keine angeben. |
engine.schemaVersion | Die Version des Ergebnisschemas ("1.0.0"). Wird erhöht, falls sich die Struktur dieses Dokuments je inkompatibel ändert. Fixieren Sie sie, wenn Sie die Ausgabe programmatisch parsen. Siehe API_STABILITY.md für die vollständige Liste stabiler und instabiler Felder und die Regeln für Versionssprünge. |
engine.locale | Welches Wörterbuch der Lauf tatsächlich verwendet hat. requested ist Ihr engineOptions.locale nach dem Trimmen ("en", wenn Sie nichts oder keinen String übergeben haben); resolved ist die Locale, deren Wörterbuch verwendet wurde; reason erklärt die Zuordnung. Weil der Locale-Rückfall stufenweise und pro String erfolgt, führt die Anfrage nach einer Sprache, die der Build nicht mitbringt, zu englischem Text statt zu einem Fehler. An diesem Feld erkennen Sie das, ohne die Strings zu lesen. Wird einmal pro Ergebnis gemeldet: Ein Lauf verwendet durchgehend ein Wörterbuch. |
engine.locale.reason | "ok": Sie haben das angeforderte Wörterbuch bekommen, und es enthält jeden Key. "primary-subtag": Ihr Code hatte ein Subtag ohne eigenes Wörterbuch, daher wurde die Basissprache verwendet: "de-DE" wird zu "de" aufgelöst. "dictionary-not-loaded": Das Projekt liefert diese Sprache aus, aber dieser Build bringt sie nicht mit, und es wurde keine übergeben (das eigenständige Browser-Bundle ohne seine Locale-Zusatzdatei). "unknown-locale": Das Projekt hat überhaupt keine solche Übersetzung. "partial-dictionary": Das Wörterbuch wurde verwendet, ihm fehlen aber Keys, die es im Englischen gibt, sodass diese Strings auf Englisch zurückgefallen sind. Behandeln Sie die Menge als offen; spätere Releases können Werte hinzufügen. |
engine.wcagVersion | Gegen welche WCAG-Version dieser Lauf geprüft hat: Ihr engineOptions.wcagVersion, die wcagVersion des Pack-Profils, das der Lauf angewendet hat, die Version, die sich aus Ihren Versionsursprungs-Tags ergab, oder der Standard "2.2". Für Erfolgskriterium 4.1.1 „Syntaxanalyse“ gibt sie an, warum eine Regel, die nur darauf abgebildet ist, nicht failergeben kann: 2.2 hat es entfernt, und die Errata von 2023 zu 2.0 und 2.1 werten es als immer erfüllt (siehe checksResults[i].wcagVersionScope unten). Wird einmal pro Ergebnis gemeldet: Ein Lauf hat durchgehend ein Ziel. |
engine.wcagLevel | Die WCAG-Stufe, nach der die gemeldeten Kriterien begrenzt wurden, "A", "AA" oder "AAA": engineOptions.wcagLevel, wenn es angegeben und gültig war, sonst die Stufe, die sich aus der Auswahl ergibt (runOnly.wcag.level oder die höchste Stufe, die ihre Versions- bzw. Stufen-Tags nennen, die Tags eines Profils eingeschlossen). WCAG-Zusammenfassungen oberhalb dieser Stufe stehen nicht in rulesResults, obwohl ihre Regeln gelaufen sind und in checksResults stehen; eine Zusammenfassung, die die Auswahl per ID nennt, wird gemeldet, gleich was engineOptions.wcagLevel sagt. Fehlt, wenn der Scan keine Stufe hatte, etwa ein vollständiger Scan oder einer, der nur Regeln nennt; der meldet jede Stufe. Die Reporter begrenzen die Kriterien, die sie nennen, nach diesem Wert. Siehe Die Stufe eines Scans angeben, der Prüfungen benennt. |
engine.profile | Nur vorhanden, wenn ein engineOptions.profile die Regeln dieses Laufs ausgewählt hat, und nennt das Profil in Kleinbuchstaben. Fehlt, wenn keines angefordert wurde, und auch, wenn eines angefordert, aber nicht angewendet wurde (unbekannter Name oder ein include in runOnly oder engineOptions hat stattdessen die Regeln gewählt) — sein Vorhandensein bestätigt also, dass ein Lauf wirklich dieses Profil als Ziel hatte. Siehe Konformitätsprofile. |
engine.profileExcludes | Nur vorhanden, wenn das angewendete Profil Regeln auslässt: { rules, criteria }, die genannten Regeln und die WCAG-Kriterien, die es auslässt. Die genannten Regeln, die Regeln, deren sämtliche Kriterien es auslässt, und die WCAG-Zusammenfassungen dieser Kriterien sind nicht gelaufen; eine Regel, die auch ein Kriterium prüft, das das Profil behält, ist gelaufen und zählt für dieses Kriterium. Das schränkt den Scan ein, ohne zu ändern, was die WCAG verlangen. Kein eingebautes Profil lässt etwas aus. |
engine.optInRules | Nur vorhanden, wenn engineOptions.optInRules mindestens eine Opt-in-Regel ausgeführt hat, die die übrige Auswahl nicht ausgeführt hätte. Listet ihre Tags auf. Sein Vorhandensein bedeutet, dass das Ergebnis Regeln für Anforderungen jenseits der Zielnorm enthält, ein fail also kein WCAG-Verstoß sein muss. Siehe Alle Regeln ausführen. |
engine.mappings | Nur vorhanden, wenn der Lauf in meta.normativeMappings eine andere Norm als WCAG nennt, über engineOptions.mappings oder das Profil einer Norm. Listet sie in kanonischer Schreibweise: "en301549" für alle Versionen, "en301549:V3.2.1" für eine. Fehlt es, nennt jedes Ergebnis nur WCAG. Siehe Andere Normen. |
engine.packs | Nur vorhanden, wenn der Scan mit engineOptions.packs lief: jedes Pack, das gelaufen ist, als name@version, nach Namen sortiert. Siehe Packs. |
engine.outputDetail | Nur vorhanden, wenn engineOptions.output.detail den Wert 'findings' hat, als "findings": Jedes pass- oder notApplicable-Prüfergebnis, das keine Vorkommen auflistet, ist kompakt, { ruleId, outcome, type } und seine margin oder sein error, falls vorhanden, ohne Titel, Beschreibung und meta, die aus dem Katalog stammen und auf jeder Seite gleich sind. fail- und cantTell-Ergebnisse, die Zusammenfassungen und engine bleiben vollständig, sodass sich kein Urteil ändert. Die Reporter (SARIF, JUnit, der HTML-Bericht, EARL, die Baseline-Funktionen) lesen ein kompaktes Ergebnis als das vollständige und ergänzen es aus dem Katalog von core. Ein Ergebnis, das dieser Katalog nicht ergänzen könnte, bleibt vollständig: jedes Prüfergebnis eines Scans mit packs, das einer eigenen Regel und eines, dessen Titel oder Beschreibung die messages des Scans geändert haben. Das Ergebnis einer leeren Seite schrumpft von etwa 263 KB auf 90 KB. |
engine.environment | Die Bedingungen, unter denen die Seite dargestellt wurde, beim Start des Scans aus der Seite gelesen, bevor irgendeine Regel läuft. Regeln, die das Layout messen, etwa text-spacing-content-loss, können für dasselbe Markup bei einer anderen Viewport-Breite oder während noch Webfonts laden ein anderes Ergebnis liefern; das hier brauchen Sie also, um einen Lauf zu reproduzieren. layout gibt an, ob die Seite ein Layout hatte: false in jsdom und anderen DOM-Emulatoren, und dann fehlen der Viewport und die übrigen Darstellungsfelder, da sie nichts Gemessenes beschreiben; nur internalsHook, listenerHook und liveRegionHook können daneben stehen, wo die Seite die Hooks ausführt. In einem Browser ist viewport innerWidth/innerHeight in CSS-Pixeln, devicePixelRatio der Wert der Seite (auch der Browser-Zoom zeigt sich hier), colorScheme das, worauf prefers-color-scheme passt, forcedColors, ob forced-colors: active zutrifft ("active" unter dem Windows-Kontrastmodus oder den emulierten Forced Colors von Chromium, sonst "none"; die Regeln messen in beiden Fällen die eigenen Farben der Seite, siehe Forced colors), forcedColorsCss ist unter Forced Colors true, wenn das eigene CSS der Seite auf sie reagiert, und zwar so, dass der Scan es nicht zurückhalten kann (eine forced-colors-Media-Query, die weiterhin zutrifft, oder eine Systemfarbe wie GrayText, die weiterhin die der erzwungenen Palette annimmt), sodass die Kontrastergebnisse von einem Scan ohne Forced Colors abweichen können, und fonts ist "loading", solange noch eine der Schriften der Seite lädt, sonst "loaded". Ein Feld, das die Seite nicht liefern kann, fehlt. Das Auslesen bringt keinen Nichtdeterminismus mit sich: Wie das DOM sind diese Werte Eingabe. Für Ergebnisse, die sich zwischen Läufen vergleichen lassen, warten Sie vor dem Scan auf document.fonts.ready. images ist "loading", solange noch ein Bild lädt, sonst "loaded": Ein Bild, das später ankommt, kann verschieben, was Layout-Regeln gemessen haben, scannen Sie für vergleichbare Ergebnisse also nach dem load-Event der Seite. Ein Bild mit loading="lazy" wird nicht berücksichtigt, da es wartet, bis gescrollt wird. animationsSettled gibt an, wie viele laufende Animationen und Transitions der Scan angehalten hat: Für den Scan wird eine endliche (ein Einblenden) an ihrem Ende gelesen und eine, die sich endlos wiederholt (ein Laufband, ein Ladekreisel), an ihrem Anfang, und jede wird danach genau dorthin zurückgesetzt, wo sie war. So ergibt eine Seite, die während eines Einblendens gescannt wird, dasselbe Ergebnis wie eine danach gescannte. Der Browser zeichnet den angehaltenen Zustand nie, da der Scan eine einzige synchrone Aufgabe ist. internalsHook ist nur vorhanden, wo die Seite den optionalen Internals-Hook (internalsHookScript(), siehe INTEGRATION.md) im gescannten Dokument ausführt, mit oder ohne Layout: "early", wenn er vor den Skripten der Seite installiert wurde und noch das attachInternals der Seite ist, sodass der Scan die ElementInternals jedes Custom Elements gelesen hat und ein Element ohne welche keine offene Frage ist; "late", wenn er nach ihnen installiert wurde oder die Seite attachInternals danach ersetzt hat, sodass nur danach angehängte Internals gelesen wurden. Ohne Hook fehlt das Feld, und das Ergebnis ist wie bisher. listenerHook gilt entsprechend für den optionalen Listener-Hook (listenerHookScript(), siehe INTEGRATION.md): "early", wenn er vor den Skripten der Seite installiert wurde und noch das addEventListener der Seite ist, sodass die Tastaturregeln jeden Listener gesehen haben, den die Seite per Skript hinzugefügt hat, und ein fehlender beweist, dass es keinen gibt; "late", wenn er nach ihnen installiert wurde oder die Seite addEventListener danach ersetzt hat. liveRegionHook ist nur vorhanden, wo die Seite den optionalen Live-Region-Hook ausführt (liveRegionHookScript(), siehe INTEGRATION.md): "early", wenn er installiert wurde, bevor das Dokument fertig geladen war, sodass er seitdem jede Änderung an den Live-Regionen der Seite gesehen hat; sonst "late". Jeder Frame in einem Frame-übergreifenden Ergebnis trägt sein eigenes. |
url | Das übergebene Argument pageUrl, oder document.location.href, wenn Sie null übergeben oder es weggelassen haben (oder etwas anderes als einen String übergeben haben, was zusätzlich ein console.warn protokolliert), oder null, wenn keins von beiden verfügbar ist. |
title | document.title zum Zeitpunkt des Scans, oder null. |
timestamp | Wird nicht automatisch erzeugt. Nur gesetzt, wenn Sie engineOptions.timestamp als nicht leeren String übergeben. Die Engine hat keine eingebaute Uhr (bewusst deterministisch). Wenn Sie einen Zeitstempel für den Scan im Ergebnis haben möchten, liefern Sie ihn selbst. |
perfStats | null, außer bei engineOptions.perfStats: true. Interne Laufzeiten und Zähler; die Struktur wird in diesem Dokument nicht beschrieben, behandeln Sie sie als reines Debug-Werkzeug. |
contextSelector | Das übergebene Argument contextSelector (getrimmt): ein String, ein Array von Strings (Scan mehrerer Bereiche, siehe Engine-Optionen) oder null, wenn keins bzw. ein leeres übergeben wurde. |
contextMatch | Wie der contextSelector aufgelöst wurde, oder null, wenn keiner angegeben war. elementCount ist die Zahl der verschiedenen Elemente, auf die er gepasst hat, also der Wurzeln des Scans. unmatchedSelectors listet jeden Selektor so, wie Sie ihn angegeben haben, der auf kein Element gepasst hat; ein kommagetrennter String ist hier ein einziger Selektor, so wie er ein einziger Aufruf von querySelectorAll ist. Ein elementCount von 0 bedeutet, dass nichts gescannt wurde: Die Seite hat keinen solchen Bereich, jeder Eintrag in checksResults und rulesResults ist notApplicable, und das Ergebnis sagt nichts über die Seite aus. Melden Sie es als nicht gefundenen Bereich, nicht als Scan ohne Befunde. Ein Selektor, den der Browser nicht parsen kann, erreicht nie ein Ergebnis: Der Scan wirft einen Fehler mit code: 'INVALID_CONTEXT_SELECTOR' (siehe Engine-Optionen). |
checksResults | Ein Eintrag pro atomarer Regel, die gelaufen ist (jede Regel, die nicht durch runOnly herausgefiltert wurde, siehe Engine-Optionen). Jede geladene Regel erzeugt einen Eintrag, auch solche, die notApplicable ergeben. Das ist keine Liste nur mit Verstößen. |
rulesResults | Ein Eintrag pro zusammengesetzter Regel (Zusammenfassung), die gelaufen ist, siehe Ein zusammengesetztes Ergebnis und Konformität. Normalerweise eine pro WCAG-Erfolgskriterium; ein Lauf unter dem Profil einer Norm mit eigenen Zusammenfassungen erhält auch diese (mit meta.standard). Es enthält die Zusammenfassungen, die die Auswahl auswählt, und die Zusammenfassungen der Kriterien, die eine Regel prüft, die die Auswahl einzeln nennt (etwa per ID); diese können teilweise geprüft sein (siehe Welche Kriterien ein Scan meldet). Leeres Array, wenn keins von beiden welche ergibt. |
standards | Nur vorhanden, wenn das Ergebnis in einem Eintrag von meta.normativeMappings oder im meta.standard einer Zusammenfassung eine andere Norm als WCAG nennt: ein { key, standard, titleLang?, note? } pro registrierter Norm, die es nennt, auch die eines Packs, in der Reihenfolge des Registers. key ist der Schlüssel der Norm ("en301549"), standard der Name, den ihre Einträge tragen ("EN 301 549"), titleLang die Sprache, in der die Titel ihrer eigenen Zusammenfassungen geschrieben sind, wenn es nicht die des Scans ist, und note der Text über ihren eigenen Zusammenfassungen im HTML-Bericht, in der Sprache des Scans. Die Reporter lesen dieses Feld statt des Registers, sodass ein gespeichertes Ergebnis überall gleich dargestellt wird, ob die jeweilige Installation die Norm kennt oder nicht. Eine Norm, die nur eine eigene Regel nennt, wird nicht aufgeführt. |
skippedPacks | Nur vorhanden, wenn ein Pack in engineOptions.packs nicht ausgeführt wurde: jeweils { name, reason }, wobei name null ist, wenn das Pack keinen hatte. In einer Seite (runa11yCoreInPage) ist name das angegebene name@version, und der Grund sagt, warum die Seite es nicht ausgeführt hat: Kein Aufruf von packScript hat genau die genannte Menge registriert, oder das Script wurde mit einer anderen core-Version vorbereitet. Jeder Eintrag wird zusätzlich mit console.warn protokolliert. |
overriddenBuiltinIds | Regel-IDs, bei denen ein Eintrag in engineOptions.customRules dieselbe id wie eine eingebaute Regel hatte, sodass die eigene Implementierung die eingebaute für diesen Scan ersetzt hat (siehe Engine-Optionen). Immer ein Array; leer, wenn keine Kollision auftrat. Wird beim Scan zusätzlich über console.warn protokolliert, da eine gleichnamige eigene Regel genauso gut eine versehentliche Kollision wie ein gewolltes Überschreiben sein kann. |
skippedCustomRules | Die Einträge in engineOptions.customRules, die nicht ausgeführt wurden, jeweils als { id, reason } (id ist null, wenn der Eintrag keine hatte): keine ID, ein runInPage, das keine Funktion ist oder sich nicht aus seinem Quelltext wiederherstellen lässt, ein meta, das die Validierung nicht besteht, eine ID, die schon eine andere eigene Regel hat, oder die ID einer zusammengesetzten Regel; oder eine gültige Regel, die die Auswahl des Laufs nicht auswählt (unter einem Profil oder einem WCAG-Ziel eine Regel mit dem Tag best-practice oder ohne WCAG-Tag), deren reason sagt, wie sie sich auswählen lässt; oder eine Regel, die die Ausschlüsse der Auswahl auslassen (excludeRuleIds, excludeTestIds, excludeTags, rules.exclude…), deren reason excluded by the selection. lautet und die zusätzlich excluded: true trägt, sodass ein Werkzeug die Entscheidung des Aufrufers von einer Lücke unterscheiden kann, ohne den Grund zu lesen. Immer ein Array; leer, wenn jede eigene Regel ausgeführt wurde. Jeder Eintrag wird zusätzlich mit console.warn protokolliert, außer einer ausgeschlossenen Regel, deren Auslassen der Aufrufer verlangt hat. Eine hier aufgeführte Regel steht in keinem Ergebnis, so lässt sich ein Scan, der sie ausgelassen hat, von einem unterscheiden, in dem sie pass ergab. |
Frame-übergreifendes Ergebnis (runa11yCoreAcrossFrames)
runa11yCoreAcrossFrames (siehe INTEGRATION.md) gibt statt eines einfachen Ergebnisses auf oberster Ebene eine andere, rekursive Struktur zurück:
{topFrame: <the normal top-level result shape above>,frames: Array<| { url: string | null, selector: string | null, title: string | null,topFrame: <top-level result>, frames: [...same shape, recursively] }| { url: string | null, selector: string | null, title: string | null, error: string }>}
topFramehat genau die Struktur des Ergebnisses auf oberster Ebene, für den Frame, in dem die Funktion aufgerufen wurde.frameshat einen Eintrag pro direktem Kind-<iframe>/<frame>im gescannten Bereich (offene Shadow Roots eingeschlossen, und der Bereich selbst, wenn er ein Frame ist), außer einem Frame, den die Seite nicht zeigt, und einem Frame, denexcludeSelectorsausschließt; diese werden mit ihrem ganzen Dokument weggelassen. Jeder Eintrag benennt sein Frame-Element:selectorist ein CSS-Selektor für das<iframe>/<frame>im Dokument des Eltern-Frames, undtitleist dastitle-Attribut des Elements odernull, sodass sich Frames, die dasselbe Dokument laden, unterscheiden lassen.urlist das Dokument, das der Frame zeigt, oder bei einem Frame, der noch nicht navigiert hat, seinsrc. Ein erreichbares Kind (eines, dasa11yCoreEnableFrameResponder()aufgerufen hat) liefert sein eigenes vollständiges{ url, topFrame, frames }, einschließlich seiner eigenen verschachteltenframes, rekursiv, denn ein tiefer verschachteltes Enkel-Frame ist nur über sein unmittelbares Eltern-Frame erreichbar. Ein nicht erreichbares Kind (der Normalfall bei den meisten Einbettungen von Drittanbietern: kein kooperierender Responder, oder er hat das Zeitlimit überschritten) liefert stattdessen{ url, error }und bricht den Rest des Scans nicht ab.- Das ist ein Baum, keine flache Liste. Das ist ein bewusster Unterschied zu
.frames(true)im Binding@surea11y/playwright, das abflachen kann, weilpage.frames()in Playwright ohnehin jedes Frame unabhängig von der Verschachtelungstiefe liefert. EinpostMessage-Relay hat keine solche Gesamtsicht, deshalb wird die Verschachtelung stattdessen strukturell abgebildet. - Die Reporter nehmen den Baum, wie er ist.
renderHtmlReport,renderSarifReport,renderJunitReport,buildBaselineEntries,matchBaselineundrenderEarlReportmelden jeden Frame darin: jeden Frame, der geantwortet hat, mit seinen eigenen Befunden, verortet in seinem eigenen Dokument, und jeden, der nicht geantwortet hat, als nicht gescannt, sodass eine Lücke in der Abdeckung nicht wie ein Bestehen aussieht. Ein Frame wird über seinen Pfad benannt, dieselectors der Frame-Elemente, die von der Seite zu ihm führen, das äußerste zuerst (#checkout → iframe:nth-of-type(2)). Sie werfen einenTypeErrorbei allem, was weder ein Scan-Ergebnis noch ein Frame-übergreifendes Ergebnis ist (ein Array,nulloderundefinedaus einem fehlgeschlagenen Scan), statt es als Scan ohne Befunde darzustellen. - Sie nehmen auch den Frame-Scan eines Bindings.
.frames(true)der Browser-Bindings gibt{ topFrame, frames }zurück, wobei jeder Frame ein einfaches Ergebnis (oder{ url, error }) statt eines verschachtelten Eintrags ist; die Reporter,getMarginsundflattenCrossFrameResultlesen jeden solchen Frame als gescannt, benannt mit dem Pfad['iframe'], da er keinenselectorträgt. flattenCrossFrameResult(result)aus@surea11y/corelistet die Frames so, wie die Reporter sie lesen:[{ frame: { path, title, url }, result }], odererrorstattresultbei einem Frame, der nicht geantwortet hat, die Seite zuerst und jeder Frame vor den Frames darin. Derpathder Seite ist[]. Ein einfaches Scan-Ergebnis ist ein einziger Eintrag.
Ein Prüfergebnis (checksResults[i])
{ruleId: string,outcome: "pass" | "fail" | "cantTell" | "notApplicable",outcomeNormalized: "pass" | "fail" | "cantTell" | "inapplicable",severity: "minor" | "moderate" | "serious" | "critical",ruleSeverity?: "minor" | "moderate" | "serious" | "critical", // the rule's own, when a profile gave it anotherpolicyOutcome?: "pass" | "fail" | "cantTell" | "notApplicable", // what the rule found, when the policy made it cantTellconfidence: "high" | "medium" | "low",type: "automatic" | "manual",occurrences: Occurrence[],title: string,description: string,i18n: { titleKey: string, descriptionKey: string, variantOfTitleKey?: string } | null,meta: {ruleId: string,ruleInterfaceVersion: string,ruleVersion: string,normative: boolean,atomic: boolean,deprecated: boolean,deprecation: object | null,category: "perceivable" | "operable" | "understandable" | "robust" | null,helpUrl: string, // where to read how to fix it; "" when there is nonetags: string[], // the rule's tags, its own and the engine'snormativeMappings: Array<{ standard: string, version: string, requirement: string, title: string,conformanceLevel?: string, wcagSc?: string[], url?: string, understandingUrl?: string }>,standard: string | null,applicability: string,expectation: string,references: string[],requirements: object | null,mappings: object | null},engineOptions: object, // the resolved engineOptions this rule actually ran underschemaVersion: string,rollupIds: string[], // the rulesResults entries that group this rule in this run; [] if nonevariantOf?: string, // a pack's variant only: the id of the rule it runs at other settings; i18n.variantOfTitleKey is that rule's titleKeydata?: object, // page-level data a rule reports whatever its outcome; see belowmargin?: { // the closest a measurement came to its threshold while meeting it; see belowmeasure: string, // "contrast-ratio" | "overflow-px" | "target-size-px" | ... (open set)unit: "px" | "ratio", // open setlimit: "min" | "max",threshold: number,value: number,headroom: number, // >= 0measuredCount: number,selector?: string,shadowHostSelectors?: string[], // as on an occurrencestructuralPath?: number[],context?: object // rule-specific; not a stable contract},wcagVersionScope?: { // present only when the target WCAG version changed this outcometarget: "2.0" | "2.1" | "2.2",removedSc: string[],coercedFrom: "fail",by?: "errata" // 2.0 or 2.1: their errata count the criterion as always satisfied},error?: string // present when the rule did not complete, or the engine noted a change — see below}
Hinweise:
outcomevs.outcomeNormalized: identisch, nur dassnotApplicableinoutcomeNormalizedzu"inapplicable"wird. Beide werden geliefert, damit Sie entweder Ihr eigenes Vokabular oder das interne der Engine abgleichen können.- Unter der Standard-Policy
a11ymelden Regeln mittype: "manual"cantTellstattfail. Würde die eigene Logik einer manuellen Regelfailergeben, wandelt die Engine das zucantTellum und hängt einen erklärenden Hinweis anerroran. Das wird zentral durchgesetzt (policy.coerceManualFailToCantTell, im Policy-Vertraga11ystandardmäßig aktiv; siehePOLICY.md) und muss nicht von jeder Regel selbst beachtet werden. Unter dieser Policy istfailausschließlich deterministischen Befunden mittype: "automatic"vorbehalten. meta.normativeMappingsverknüpft ein Prüfergebnis mit einem WCAG-Erfolgskriterium. Eine leere Liste bedeutet, dass die Regel in diesem Ergebnis keine formale Zuordnung hat. Ob die Regel automatisch oder manuell ist, sagt sie nicht: Das zeigttype(aria-allowed-roleetwa ist automatisch und hat keine WCAG-Zuordnung). Wie diese zusammengefasst werden, steht unter Konformität. Die Liste enthält nicht nur WCAG. Fordert der Scan eine andere Norm an (engineOptions.mappingsoder das Profil einer Norm), folgt auf jedes WCAG-Kriterium die entsprechende Anforderung dieser Norm, etwa die EN-301-549-Klausel, die es wiedergibt ({ standard: "EN 301 549", version: "V3.2.1" | "V4.1.1", requirement: "9.1.1.1", title, wcagSc: ["1.1.1"] }, ein Eintrag pro Version, die das Kriterium enthält); außerdem kann eine Regel die Understanding-Dokumente der WCAG zitieren (type: "Understanding"). Filtern Sie nachstandard(und nach fehlendemtype), bevor Sierequirementals Erfolgskriterium lesen. Der WCAG-Eintrag einer zusammengesetzten Regel steht immer zuerst. Siehe EN 301 549.rollupIdslistet die zusammengesetzten Regeln inrulesResults, die diese Regel in diesem Lauf gruppieren, einschließlich derer, die gemeldet werden, weil die Auswahl die Regel einzeln genannt hat. Eine leere Liste bedeutet, dass die Befunde der Regel in keiner Zusammenfassung erscheinen; wer nurrulesResultsliest, sieht sie also nie.heading-ordergehört zum Beispiel zu keiner WCAG-Zusammenfassung.wcagVersionScope: nur vorhanden, wenn die WCAG-Zielversion des Laufs dasfaildieser Regel in eincantTellverwandelt hat. Derzeit betrifft das eine auf Erfolgskriterium 4.1.1 „Syntaxanalyse“ abgebildete Regel (duplicate-id): unter 2.2, das dieses Kriterium entfernt hat, und unter 2.0 und 2.1, deren Errata von 2023 es für HTML und XML als immer erfüllt werten (by: "errata"). Ein Profil, dessen Norm den Text von 4.1.1 beibehält (en301549-v3.2.1oder das Profil eines Packs mitkeepsParsing), wird nicht umgewandelt.removedSclistet die betroffenen Kriterien,targetist die Version des Laufs, undcoercedFromist das Ergebnis, das die Regel selbst gemeldet hat. Die Vorkommen sind die der Regel, unverändert: Nichts wurde verworfen, nur das Konformitätsurteil. Fehlt bei jedem anderen Ergebnis und wird nie übererrorgemeldet: Es ist nichts schiefgegangen. Siehe Filtern nach WCAG-Version.data: nur bei einer Regel vorhanden, die unabhängig von ihrem Ergebnis etwas über die ganze Seite meldet. Keine Core-Regel tut das derzeit. Wiedata.detailsbei einem Vorkommen ist es kein stabiler Vertrag.margin: nur bei einer Regel vorhanden, die im Katalog eine deklariert (getChecksCatalog()[i].margin,{ measure, unit, limit, band? }), und nur, wenn mindestens ein Element den Schwellenwert der Regel erfüllt hat und, falls die Deklaration einbandhat, innerhalb davon lag.band.relativeist ein Bruchteil des Schwellenwerts:contrast-minimum,contrast-enhancedundlink-in-text-blockmelden mit0.1eine Marge nur für ein Verhältnis innerhalb von 10 % des geforderten (4,5 bis 4,95 bei 4,5:1, 3 bis 3,3 bei 3:1).band.absoluteist ein Betrag inunit:target-size-minimummeldet mit6ein Ziel nur bis 30 px, undtext-spacing-content-lossmit8eine Zeile nur ab 6 px innerhalb des Rands ihrer Box. Text mit 21:1 oder ein 48-px-Button ist nirgends knapp, und keine Marge sagt etwas anderes. Es nennt das Element, das dem Schwellenwert am nächsten kam und ihn dabei erfüllte. So lässt sich einpassmit 4,52:1 bei geforderten 4,5:1 oder 0,4 px vor abgeschnittenem Text von einem mit reichlich Abstand unterscheiden. Es steht neben dem Ergebnis und ist kein Befund: Es fügt nie ein Vorkommen hinzu, entfernt oder ändert keines, und Baselines, SARIF, JUnit und EARL ignorieren es. Es wird auch beifail- undcantTell-Ergebnissen gemeldet, wenn einige Elemente bestanden haben.limitistmin, wenn der Wert den Schwellenwert erreichen muss (Kontrast, Größe), undmax, wenn er darunter bleiben muss (Überlauf);headroomist der verbleibende Abstand inunit, alsovalue - thresholdbeiminundthreshold - valuebeimax, nie negativ.thresholdist der Schwellenwert, an dem dieses Element gemessen wurde; er kann sich zwischen Elementen unterscheiden (3:1 für großen Text). Pixel werden mit einer Nachkommastelle angegeben: CSS-Pixel und Schwellenwerte wie die Hälfte einer 15px-Schrift sind Bruchzahlen, und eine Anzeige rundet sie für Menschen. Ein Verhältnis wird nicht gerundet, da WCAG Kontrast nicht rundet. Bei Gleichstand gewinnt das in der Dokumentreihenfolge erste Element, sodass eine Seite jedes Mal denselben Wert ergibt.measureundunitsind offene Mengen, die in einem Minor-Release wachsen können;contextist regelspezifisch und, wiedata.details, kein stabiler Vertrag.getMargins(result)gibt alle Werte eines Ergebnisses als[{ ruleId, ...margin }]zurück, sortiert nachruleId; bei einem Frame-übergreifenden Ergebnis die Werte jedes Frames, die eines Kind-Frames mitframe, dem Pfad zu ihm.error: vorhanden, wenn die Regel nicht abgeschlossen wurde oder wenn die Engine einen Teil dessen, was die Regel zurückgegeben hat, geändert oder ignoriert hat. Eine Regel, die eine Exception geworfen hat (oder etwas zurückgegeben hat, das kein Ergebnis ist), erscheint immer alsoutcome: "cantTell"mitoccurrences: []und der Exception-Meldung inerror; ancantTellohne Vorkommen und mit einemerrorerkennen Sie also eine Regel, die nicht abgeschlossen wurde. Die Engine lässt nie zu, dass eine einzelne defekte Regel den ganzen Scan zum Absturz bringt. Sonst enthälterrordie Hinweise der Engine, mit|verbunden nach einemerror, den die Regel selbst zurückgegeben hat: die oben beschriebene Umwandlung manuellerfail-Ergebnisse, einoutcomeoder eineseverityaußerhalb ihrer Menge, eintype, der von dem in ihrem meta abweicht, Vorkommen, die keine Objekte sind (weggelassen), einpolicyOutcomeoder eineruleSeverity, die die Regel zurückgegeben hat (nicht übernommen: Die Engine setzt beide), einuncertainty.codeaußerhalb der geschlossenen Menge und einfail, das zucantTellherabgestuft wurde, weil der Durchlauf über die Vorfahren nach 200 Schritten vor jedem gemeldeten Element abgebrochen ist. Diese Ergebnisse behalten ihre Vorkommen: Die Regel wurde abgeschlossen.policyOutcome: vorhanden, wennallowedOutcomesder Policy das Ergebnis, das die Regel gefunden hat, nicht zulässt. Das Ergebnis ist danncantTell, mit dem eigenen Ergebnis der Regel hier und ohneerror, sodass die Reporter es nicht als Regel lesen, die nicht abgeschlossen wurde.engineOptionsist in jedem Ergebnis das aufgelöste Optionsobjekt (nach Anwendung der Standardwerte für Locale und Kontrast), nicht wörtlich das, was Sie übergeben haben. Nützlich, um zu prüfen, was eine bestimmte Regel tatsächlich gesehen hat, insbesondere die aufgelöstelocaleundcontrast.mode/contrast.rootCanvasFallback.contrast.rootCanvasFallbackist Weiß, wenn der Aufruf keine Farbe angegeben hat, undcontrast.rootCanvasFallbackSetsagt, welcher Fall vorliegt:truefür eine angegebene Farbe,falsefür den Standardwert. Es lässtmessagesweg, die Wörterbücher, mit denen der Lauf übersetzt hat (eine separate Locale-Datei im Browser-Bundle oder Ihre eigenen Strings): Sie sind Daten, keine Einstellung, und eine Kopie in jedem Ergebnis machte einen Scan zig Megabyte groß.engine.localegibt an, welches Wörterbuch verwendet wurde. Drei weitere Optionen werden so wiedergegeben, wie die Regeln sie gesehen haben, damit das Ergebnis einfache Daten bleibt, dieJSON.stringifyundstructuredClone(postMessage) transportieren können:probesals die gekappte Kopie, die die Regeln lesen,customRulesals[{ id }], ein Eintrag je eigener Regel mit ID, ohne ihre Funktionen, undstyleSheetTextsals[{ href }], ein Eintrag je übergebenem Stylesheet, ohne seinen Text, da das CSS einer Seite, in jedem Ergebnis wiederholt, mit der Zahl der Regeln multipliziert wurde.
Ein Vorkommen (occurrences[i])
Ein fail hat immer mindestens eines: Das fail einer eigenen Regel, das kein Element nennt, erhält eines am Dokumentelement (selector: "html", Reason-Code FAIL_WITHOUT_OCCURRENCE). Normalerweise nur vorhanden, wenn outcome fail oder cantTell ist: Ein pass-Ergebnis hat occurrences: [], da diese Engine nicht die Elemente aufzählt, die bestanden haben, sondern nur die markierten. Die Kontrastregeln sind die Ausnahme: Ihr pass trägt ein Vorkommen, das den Scan beschreibt (wie viel Text in Frage kam und berechenbar war), mit leerem selector, damit sich ein pass ohne jeden Text von einem über eine Seite voller Text unterscheiden lässt.
notApplicable ist die einzige Ausnahme. Eine Regel, die nichts zu beurteilen hatte, kann ein einzelnes Vorkommen mit der Begründung anhängen, und die Kontrastregeln tun genau das, wenn kein Text einen berechenbaren Hintergrund hatte. Den Unterschied zwischen „geprüft, nichts zu melden“ und „konnte nicht prüfen“ meldet diese Engine, statt ihn zu verbergen. Ein solches Vorkommen beschreibt den Scan, kein Element, deshalb ist sein selector leer. Lesen Sie occurrences.length nicht als Anzahl der Verstöße, ohne vorher outcome zu prüfen.
{selector: string,html: string,structuralPath: number[] | null,shadowHostSelectors?: string[],summary: string,hint: string,i18n: { summaryKey: string, hintKey: string, params: object } | null,occurrenceOutcome?: "fail" | "cantTell", // present when the rule graded its findings into tiersuncertainty?: { // present only on a cantTell-tier occurrencecode: "not-computable" | "runtime-dependent" | "spec-only"| "equivalence-unknown" | "judgement-required" | "out-of-scope",needed?: string, // what would settle the questionevidence?: object // what the rule did establish, rule-specific},lean?: { // present only on a cantTell-tier occurrence, and only with evidencetoward: "pass" | "fail",why: string, // localized: what in the page points that waysignals: { signal: string, value: string | number | boolean | null }[],caution?: string, // localized: what could make it wrongmeasured?: { agreed: number, cases: number, corpus?: string, coreVersion?: string },i18n?: { whyKey?: string, cautionKey?: string, params?: object }},howToCheck?: { // present only on a cantTell-tier occurrence, when the rule sayssteps: string[], // localized: what a person does, in orderpassWhen: string, // localized: what they see if it passesfailWhen: string // localized: what they see if it fails},data?: { // absent on manual-review's page-level findingvisibilityFilter?: { eligible?: boolean, targetSet: string, accEligible: boolean | null, reasons: string[] },details?: object // rule-specific, non-normative — see below}}
| Feld | Bedeutung |
|---|---|
selector | Ein nach bestem Bemühen erzeugter CSS-Selektor, der wieder auf das markierte Element auflösen soll (siehe helpers.buildSelector in RULE_AUTHORING.md). Eine id, eine Test-ID, name oder aria-label dient nur dann als Anker, wenn kein anderes Element im Dokument denselben Wert hat, verborgene, ausgeschlossene und außerhalb des Bereichs liegende Elemente eingeschlossen, da querySelector ihn gegen das ganze Dokument auflöst; sonst ist der Selektor ein Pfad. Nicht in jeder DOM-Struktur garantiert eindeutig: Ein Element in einer Shadow Root wird innerhalb seines eigenen Baums benannt (structuralPath verortet es), und der Pfad eines sehr tief liegenden Elements wird von oben her gekürzt. Auf 255 Test- und echten Seiten benannten 15 von 39.857 Selektoren nicht genau ihr Element, alle von diesen Arten. Die Ausnahme ist eine Regel, deren Befund ein fehlendes Element ist: page-title-present meldet head > title mit dem html <title>(missing)</title>, und keins von beiden steht auf der Seite. Beides sind Konstanten, der daraus gebildete Fingerprint bleibt also stabil, aber behandeln Sie selector nicht als auflösbar und html nicht als echtes Markup, ohne zu prüfen, dass die Regel etwas Existierendes gemeldet hat. Bei einem Element in einem Shadow Tree löst selector innerhalb seiner Shadow Root auf, und shadowHostSelectors gibt an, wie man dorthin gelangt. |
shadowHostSelectors | Nur bei einem Element in einem Shadow Tree vorhanden: die Selektoren der Shadow Hosts, die zu ihm führen, vom äußersten an, jeder in dem Baum aufgelöst, der ihn enthält, sodass document.querySelector(s[0]).shadowRoot.querySelector(s[1])…shadowRoot.querySelector(selector) das Element findet. Zwei Komponenten mit gleichem Inhalt ergeben denselben selector und unterscheiden sich hier. Wie selector gehört es nicht zur Identität eines Befunds. Der HTML-Bericht, SARIF (logicalLocations), JUnit und Baseline-Einträge zeigen beides als eine Fundstelle: die Hosts und dann den Selektor, verbunden mit >>> (#card >>> img). |
html | Ein Outer-HTML-Ausschnitt des markierten Elements, nach 2.000 Zeichen abgeschnitten. Nützlich, um das Element zu zeigen, und bei einem Element in einem Shadow Tree zusammen mit shadowHostSelectors zu lesen. Bei <html>, <head> und <body>, die die ganze Seite enthalten, ist es nur das Start-Tag (<html class="x">), sodass ein Befund auf Seitenebene seine Identität behält, wenn sich anderer Inhalt ändert. |
structuralPath | Der Pfad aus Geschwister-Indizes von documentElement hinunter zum markierten Element (z. B. [1, 0, 2]); [], wenn das Element selbst documentElement ist, null, wenn er sich nicht bestimmen ließ, was für jedes Element in einem Shadow Tree gilt (verwenden Sie dort shadowHostSelectors und selector). Ein robusterer Mechanismus zur Identifizierung von Elementen als selector allein: Er übersteht DOM-Änderungen, an denen ein Selektor-String scheitern würde (etwa eine umbenannte ID oder Klasse), um den Preis, dass er sich nicht als echter CSS-Selektor verwenden lässt. |
summary | Für Menschen lesbar, bereits lokalisiert („This button has no accessible name.“). |
hint | Für Menschen lesbare Hinweise zur Behebung, bereits lokalisiert. |
i18n | Die rohen Übersetzungs-Keys hinter summary/hint, falls Sie sie selbst in einer anderen Locale neu rendern möchten, ohne den Scan zu wiederholen. null, wenn das Vorkommen keine Key-basierte i18n verwendet hat. |
data.visibilityFilter | Bei den meisten Vorkommen vorhanden: warum die Engine dieses Element nach dem Eignungsmodell der jeweiligen Regel als geeignet (oder nicht) eingestuft hat. eligible ist dieses Ergebnis (fehlt bei den Befunden auf Seitenebene von bypass-blocks-present, html-lang-attr-present und page-title-present); targetSet gibt an, welches Modell es erzeugt hat ('dom': reine DOM/CSS-Sichtbarkeit, die meisten Regeln; 'acc': Eignung laut Accessibility Tree). accEligible spiegelt eligible nur, wenn targetSet 'acc' ist, sonst null. reasons ist bei eligible: false eine Liste maschinenlesbarer Ausschlusscodes. |
data.details | Regelspezifische strukturierte Daten (berechnete Metriken, aufgelöste Referenzen), nicht normativ: nützlich für eine reichhaltigere UI oder zum Debuggen, ändert aber nie, was outcome/severity bedeuten. Die Struktur variiert je nach Regel; behandeln Sie sie als zusätzlichen Kontext ohne Gewähr, nicht als stabilen Vertrag. Die einzige Ausnahme ist data.details.reasonCode, das sehr wohl stabil ist: Es gibt an, welcher der Befunde einer Regel das ist, und bildet zusammen mit ruleId und html den Fingerprint, an dem Baselines und SARIF festgemacht sind. Eine Regel kann in einem Minor-Release einen neuen Reason-Code erhalten oder einen nach Ursache aufteilen; siehe API_STABILITY.md. Die Größen- und Verhältnisfelder eines Kontrastfehlers (metrics.ratio, metrics.threshold und in typography fontSizePx, fontSizePt, fontWeight, isBold und isLargeText) sind ebenfalls stabil, damit ein Bericht oder ein Pack erkennen kann, welche Art von Text die Anforderung nicht erfüllt hat, ebenso element in Befunden von list-children-valid, parentElement in Befunden von listitem-parent-valid und role in Befunden von aria-role-name-present, die angeben, um welche Art von Liste oder Widget es geht. Die Seite jeder Regel listet unter „Was ein Befund meldet“ die Felder auf, die ihre Befunde mitführen. |
occurrenceOutcome | Zu welcher Stufe dieses Vorkommen gehört, bei einer Regel, die ihre Befunde in eine sichere fail-Stufe und eine prüfbedürftige cantTell-Stufe eingeteilt hat. Eine Regel, die nur eine Stufe meldet, lässt das Feld weg; dann ist das outcome des Ergebnisses selbst die Stufe des Vorkommens. occurrenceOutcome(check, occurrence) aus @surea11y/core liefert die Stufe so, wie jeder Reporter sie liest, in beiden Fällen. Das Ergebnis stimmt immer mit den Stufen überein: Jedes Vorkommen der fail-Stufe macht es zu fail, und ein fail, dessen Vorkommen alle zur cantTell-Stufe gehören, ist cantTell, sodass SARIF, JUnit, EARL und Baselines eine einzige Antwort geben. Die Engine gleicht eine eigene Regel oder eine Regel eines Packs an, die sie widersprüchlich zurückgibt; unter der Standard-Policy ist eine manuelle Regel nie fail. Ein Ergebnis, das gespeichert wurde, bevor die Engine das tat, lesen die Reporter nach derselben Regel, unter der Policy, die seine engineOptions festhalten, und fassen seine WCAG-Zusammenfassungen aus dem Gelesenen neu zusammen. |
uncertainty | Warum sich dieser Befund nicht entscheiden ließ, siehe Unsicherheitscodes unten. |
lean | In welche Richtung dieser offene Befund weist, wenn die Seite Anhaltspunkte dafür liefert, siehe Tendenzen unten. |
howToCheck | Wie eine Person diesen offenen Befund beantwortet, siehe So prüfen Sie es unten. |
Unsicherheitscodes
Ein cantTell besagt, dass die Engine nicht entschieden hat. uncertainty sagt warum, aus einem geschlossenen Vokabular, sodass ein Konsument nach dem Grund verzweigen kann, statt einen Zusammenfassungs-String zu parsen. Es ist nur bei einem Vorkommen der cantTell-Stufe vorhanden: Ein Vorkommen der fail-Stufe würde behaupten, dass die Regel zugleich entschieden und nicht entschieden hat, daher entfernt die Engine es dort. Eine Unsicherheit, deren code keiner der Codes unten ist, wird ebenfalls weggelassen, und der error der Regel nennt den Code.
| code | Bedeutung | Typischer Fall |
|---|---|---|
not-computable | Die Evidenz, die die Regel brauchte, ließ sich in dieser Umgebung nicht lesen. | Ein Cross-Origin-Stylesheet, eine Hintergrundfarbe, die zu keinem Wert auflöst, ein src, das sich nicht auflösen lässt. |
runtime-dependent | Das Markup kann es nicht klären, weil ein Skript zur Laufzeit entscheidet. | Ein aria-controls, das auf ein Element verweist, das das Widget erst beim Öffnen erzeugt. |
spec-only | Ein echter Verstoß gegen die Spezifikation, aber Name, Rolle und Wert bleiben trotzdem zugänglich, sodass kein Erfolgskriterium als nicht erfüllt feststeht. | Ein ARIA-Attribut, für dessen Fehlen die Spezifikation einen Standardwert vorsieht. |
equivalence-unknown | Zwei Dinge dienen womöglich demselben Zweck, womöglich nicht, und weder Markup noch Inhalt klären das. | Zwei Frames mit demselben zugänglichen Namen, die verschiedene Ressourcen einbetten. |
judgement-required | Die Frage kann grundsätzlich nur ein Mensch beantworten. | Ob ein zu kleines Ziel unverzichtbar ist; jede Regel mit type: "manual". |
out-of-scope | Der Befund ist real, liegt aber außerhalb des Standards, gegen den dieser Lauf prüft. | Eine Regel, die nur auf ein Kriterium abgebildet ist, das die WCAG-Zielversion entfernt hat. |
needed nennt in einem Satz, was die Frage klären würde, also das, was eine prüfende Person nachsehen muss. evidence enthält, was die Regel tatsächlich festgestellt hat, damit die Prüfung auf der Arbeit der Engine aufbaut, statt sie zu wiederholen; die Struktur ist regelspezifisch und, wie data.details, kein stabiler Vertrag. Der code dagegen schon: Neue Codes können in einem Minor-Release hinzukommen, aber ein bestehender ändert seine Bedeutung nicht. Verzweigen Sie also nach den Codes, die Sie kennen, und behandeln Sie einen unbekannten als „muss geprüft werden“, nicht als Fehler.
Jede automatische Regel, die cantTell melden kann, liefert dieses Feld, und ein Test stellt das sicher, damit keine neue Regel ohne es hinzukommt. Den Code out-of-scope hängt die Engine an, nicht eine Regel, und zwar an genau die Vorkommen, die auf Ergebnisebene ein wcagVersionScope erzeugen. Manuelle Regeln liefern es nicht: judgement-required ist genau das, was type: "manual" bereits bedeutet, eine Wiederholung pro Vorkommen würde also nichts sagen, was das Ergebnis nicht schon sagt.
Tendenzen
Ein cantTell kann trotzdem in eine Richtung weisen. lean gibt an, in welche, wenn die Seite Anhaltspunkte dafür liefert: toward ist die Antwort, die diese Anhaltspunkte wahrscheinlich machen, why sagt, worin sie bestehen, und signals listet die Fakten, die die Regel gelesen hat, jeweils ein Name in Kebab-Case und ein einfacher Wert, damit ein Tool sie anzeigen oder gewichten kann. caution sagt, was die Tendenz falsch machen könnte, wenn das nicht schon aus uncertainty.needed hervorgeht. Das Ergebnis bleibt cantTell: Eine Tendenz ist ein Hinweis, kein Urteil, und nichts, was Ergebnisse oder Stufen liest, ändert sich durch sie. LEANS.md ist der Leitfaden für alle, die Berichte lesen oder Tools bauen: welche Befunde eine Tendenz haben und warum, wie eine Tendenz gemessen wird und wie weit man ihr trauen kann.
lean ist nur vorhanden, wo die Regel Anhaltspunkte hat. Auch das Fehlen ist eine Information: Diesen Befund kann nur eine Person beurteilen. Es ist nur bei einem Vorkommen der cantTell-Stufe vorhanden, wie uncertainty; die Engine entfernt es bei einem entschiedenen Vorkommen und entfernt ein fehlerhaftes (ein toward außer pass oder fail, oder kein why), ohne den Befund anzutasten. measured erscheint, sobald eine Tendenz an mindestens fünf Fällen mit bekannter Antwort gezählt wurde: wie oft sie richtig lag (agreed), von wie vielen (cases), aus welchem Korpus die Fälle stammen (corpus, mit dem Datum, an dem er gelesen wurde) und welche core-Version sie gezählt hat (coreVersion). Gezählt wird je Regel, Reason-Code und Richtung, anhand der Testfälle der W3C ACT Rules, und die Engine führt die Zahlen mit, sodass ein Ergebnis aus jedem Einstiegspunkt sie hat. Eine nie oder an weniger Fällen gezählte Tendenz hat keine; eine Konfidenzzahl gibt es nicht. Bisher hat noch keine eine: Die erste Zählung, in jsdom, sah 9 Tendenzen, keine an fünf Fällen.
why und caution stehen in der Locale des Scans; i18n enthält ihre Schlüssel und Parameter, wie das i18n eines Vorkommens für summary und hint. Die Engine selbst gibt einem Befund eine Tendenz: Eine Regel, die nur auf ein Kriterium abgebildet ist, das die WCAG-Zielversion entfernt hat oder das die Errata von 2023 als erfüllt werten, tendiert zu pass, neben ihrer Unsicherheit out-of-scope.
reviewGroupOf(check, occurrence) aus @surea11y/core gibt an, wohin ein Vorkommen in einer Prüfung gehört: 'fail', 'leanFail', 'leanPass' oder 'open' (nur eine Person kann es beurteilen), die Gruppen des HTML-Berichts. leaningFailures(result, { wcagOnly }) listet die Befunde, die zu fail tendieren, also die, die eine Schranke mit leanFailAs zählt (JUnit, SARIF).
Neue Tendenzen kommen in Minor-Releases hinzu, Regel für Regel, und eine Tendenz kann entfernt werden, wenn die Messung zeigt, dass sie zu oft falsch liegt: Behandeln Sie eine Tendenz als Hinweis, der da sein kann oder nicht, nie als Teil der Identität eines Befunds. Sie geht nicht in den Fingerprint ein.
So prüfen Sie es
Ein cantTell übergibt eine Frage an eine Person. howToCheck sagt ihr, wie sie sie beantwortet: steps, einige Handlungen der Reihe nach, beginnend bei dem Element, das der Befund nennt („Gehen Sie mit der Tabulatortaste zum Element.“, „Achten Sie darauf, ob der Fokusindikator darauf bleibt.“), dann passWhen und failWhen, was sie sieht, wenn die Anforderung erfüllt ist und wenn nicht, mit dem Kriterium, das dann nicht erfüllt ist. Jede Core-Regel, die cantTell melden kann, schreibt diese Texte für jeden ihrer Reason-Codes (ihr meta.review), und jedes Vorkommen der cantTell-Stufe erhält den Eintrag seines Codes, in der Locale des Scans. Der Befund einer Variante (variantOf) erhält den ihrer Basisregel, wo sie keinen eigenen hat. Eine Regel eines Packs kann sie ebenfalls schreiben, auf Englisch (siehe Packs); ihre Befunde erhalten sie, wenn die Packs bekannt sind, wie sie runDomRulesInPage mit engineOptions.packs und addHowToCheck(result, { packs }) kennen. Es fehlt bei einem entschiedenen Vorkommen, beim Befund einer eigenen Regel, bei dem einer Überschreibung (einer eigenen Regel oder Regel eines Packs in overriddenBuiltinIds) und bei dem einer Pack-Regel, die keine schreibt.
Die Schritte werden nach dem Scan in Node hinzugefügt, nicht von der Engine in der Seite: Die Engine wird in jede Seite und jeden Frame eingefügt, die ein Scan öffnet, und hat keine Verwendung für tausend Sätze, die keine Regel liest. runDomRulesInPage fügt sie seinem Ergebnis hinzu. Ein Ergebnis von runa11yCoreInPage, in einer Seite ausgeführt (das eines Bindings, einer Erweiterung), kommt ohne sie zurück; addHowToCheck(result) gibt eine Kopie mit ihnen zurück, und howToCheckFor(ruleId, reasonCode, locale) liefert die eines einzelnen Befunds. Beide lesen die Prüf-Wörterbücher von core von der Festplatte und brauchen daher Node; ein Binding, dessen Code im Browser läuft (Cypress), ruft applyHowToCheck(result, { en, fr }) aus @surea11y/core/how-to-check mit den Wörterbüchern auf, die es aus @surea11y/core/review/<locale> importiert, und erhält dieselben Schritte (BINDING_AUTHORS_GUIDE.md zeigt, wie ein Binding das macht). Der HTML-Bericht (renderHtmlReport) fügt sie in Node einem Ergebnis hinzu, das ohne sie kommt; im Browser (surea11y.report.js) zeigt er die, die das Ergebnis mitführt. Ein Tool, das ein Ergebnis in einer anderen Sprache als der des Scans anzeigt, übergibt { locale } an addHowToCheck oder applyHowToCheck (addHowToCheck(result, { locale: 'de' }) oder eine Liste von Locales, die gewünschteste zuerst; renderHtmlReport nimmt keine): Die Schritte kommen in dieser Sprache, auch die bereits vorhandenen, mit Englisch für jeden Schritt, der in der Locale fehlt.
Die Schritte setzen einen Browser voraus, seine Entwicklerwerkzeuge (den Accessibility Tree), eine Tastatur und für manche einen Screenreader. Anders als uncertainty.needed, das in einem Satz sagt, was die Frage klären würde, sagen sie, wie man sie klärt. Wie eine Tendenz sind sie eine Anleitung, nicht Teil der Identität eines Befunds, und ihr Wortlaut kann sich in jedem Release verbessern.
Ein zusammengesetztes Ergebnis (rulesResults[i])
Zusammengesetzte Regeln fassen mehrere atomare Regeln zu einem WCAG-Erfolgskriterium zusammen (z. B. fasst wcag-1.1.1-non-text-content 21 atomare Regeln zusammen). Unter dem Profil einer Norm mit eigenen Zusammenfassungen gibt es zusätzlich diese, mit dem Wortlaut der Norm als title und ihrem Namen als meta.standard. Die Struktur ist dieselbe Hülle wie bei einem Prüfergebnis, mit spezifischen data.details für zusammengesetzte Regeln:
{ruleId: string, // e.g. "wcag-1.1.1-non-text-content"outcome: "pass" | "fail" | "cantTell" | "notApplicable",severity, confidence, type, title, description, meta, engineOptions, schemaVersion, // as on a check result, except that// meta.normativeMappings names the criterion in a shorter form:// { standard, requirement, level }occurrences: [], // always empty — composites are rollups, not element-level findingsdata: {details: {reasonCode: string, // e.g. "composite.rollup.fail.anyFail"standard?: string, // a standard's own rollup only, with version and criterionversion?: string,criterion?: string,checksIds: string[], // every atomic ruleId it rolls up, custom rules mapped to its criteria includedcustomChecksIds?: string[], // the custom rules among them; absent when nonerestatesWcag?: string[], // a standard's rollup that restates WCAG criteria (applicability: 'wcag'): those criteriapartial?: true, // a standard's requirement its rules don't check in full (partial: true)contributors: Array<{ testId: string, outcome: string, severity?: string | null, custom?: true, notSelected?: true,byReasonCode?: true, checkOutcome?: string, requirements?: string[] }>,metrics: { failCount, cantTellCount, notApplicableCount, passCount, missingCount }}}}
Vorrang bei der Zusammenfassung (deterministisch, in dieser Reihenfolge): irgendein Beitrag fail → zusammengesetzt fail; sonst irgendein cantTell (oder eine beitragende Regel, die gar nicht gelaufen ist, missingCount > 0) → zusammengesetzt cantTell; sonst alle Beiträge notApplicable → zusammengesetzt notApplicable, wo die Regeln jeden Fall finden, für den das Kriterium gilt, und sonst cantTell (partialCoverage); sonst pass, wo die Regeln alles prüfen, was das Kriterium verlangt, und sonst cantTell (partialCheck). Noch ist kein WCAG-Kriterium als vollständig geprüft geführt, daher ergibt derzeit keine WCAG-Zusammenfassung pass. Was das für eine Gesamtaussage zur Konformität bedeutet, steht unter Konformität.
Die eigene Zusammenfassung einer Norm kann eine Regel nach ihren Befunden statt als Ganzes beurteilen (siehe Packs): Ihre beitragende Regel gibt dann byReasonCode: true an, outcome ist das Ergebnis der Regel in dieser Zusammenfassung (ein fail, dessen Befunde alle woandershin gehören, ist hier ein pass) und checkOutcome das eigene Ergebnis der Regel. Nennen die Befunde, die für die Zusammenfassung zählen, zu welcher ihrer Anforderungen sie gehören, listet requirements diese auf, und die meta.normativeMappings der Zusammenfassung nennen für diese Regel genau diese, nicht jede Anforderung, die die Regel prüft.
Die Regeln einer WCAG-Zusammenfassung sind ihre eigene Liste und jede Regel aus engineOptions.customRules, die gelaufen ist und einem ihrer Kriterien zugeordnet ist (über meta.wcagSc oder einen WCAG-Eintrag in meta.normativeMappings), unter den beitragenden Regeln mit custom: true gekennzeichnet und in customChecksIds aufgeführt, sodass eine lesende Person sieht, wann eine eigene Regel das Ergebnis entschieden hat. Die eigenen Zusammenfassungen einer Norm behalten ihre Listen.
Ein teilweise geprüftes Kriterium. Ein Scan, der Regeln statt Kriterien nennt (includeRuleIds: ['link-name-present']), erhält auch die Zusammenfassungen der Kriterien, die diese Regeln prüfen, wenn die Auswahl sie nicht selbst auswählt (siehe Welche Kriterien ein Scan meldet). Die obige Rangfolge entscheidet sie wie jede andere: Eine Regel mit fail lässt das Kriterium scheitern, und Regeln, die der Scan nicht ausgewählt hat, verhindern, dass es pass ergibt. Jede davon ist eine beitragende Regel mit outcome: "missing" und notSelected: true, wie bisher in missingCount gezählt. Wenn sie es sind, die die Zusammenfassung zu cantTell machen, ist ihr reasonCode composite.rollup.cantTell.notSelectedChild, und der HTML-Bericht zeigt „Teilweise geprüft: 1 von 2 Prüfungen war für diesen Scan nicht ausgewählt“. composite.rollup.cantTell.missingChild steht weiterhin für eine Regel, die aus einem anderen Grund nicht gelaufen ist, etwa eine, die das Profil ausschließt (engine.profileExcludes); sie ist nie mit notSelected markiert.
| reasonCode | Ergebnis | Wann |
|---|---|---|
composite.rollup.fail.anyFail | fail | Eine beitragende Regel ergab fail. |
composite.rollup.cantTell.anyCantTell | cantTell | Keine ergab fail, und eine ist cantTell. |
composite.rollup.cantTell.notSelectedChild | cantTell | Keine ergab fail oder ist cantTell, und einige sind nicht gelaufen, weil der Scan sie nicht ausgewählt hat: teilweise geprüft. |
composite.rollup.cantTell.missingChild | cantTell | Keine ergab fail oder ist cantTell, und einige sind aus einem anderen Grund nicht gelaufen. |
composite.rollup.notApplicable.allInapplicable | notApplicable | Jede beitragende Regel ist notApplicable, und sie finden jeden Fall, für den das Kriterium gilt. |
composite.rollup.cantTell.partialCoverage | cantTell | Jede beitragende Regel ist notApplicable, aber das Kriterium (oder eine mit partial gekennzeichnete Anforderung einer Norm) kann für Inhalte gelten, nach denen sie nicht suchen; es ist also nicht gezeigt, dass die Seite keine hat. |
composite.rollup.cantTell.emptyComposite | cantTell | Die Zusammenfassung hat keine Regeln. |
composite.rollup.cantTell.partialCheck | cantTell | Keine ergab fail oder ist cantTell, und nicht alle sind notApplicable, aber die Regeln prüfen nur einen Teil dessen, was das Kriterium (oder eine mit partial gekennzeichnete Anforderung einer Norm) verlangt: Den Rest prüft eine Person. |
composite.rollup.pass.otherwise | pass | Sonst. |
Ergebniswerte
| Ergebnis | Bedeutung | Bei type: "manual" möglich? |
|---|---|---|
fail | Die Regel meldet, dass die geprüfte Anforderung nicht erfüllt ist. Zur Einordnung des Befunds lesen Sie seine Zuordnung, Konfidenz und Vorkommen. | Nein, unter der Standard-Policy (zu cantTell umgewandelt) |
pass | Die Ziele, auf die die Regel anwendbar ist, existieren, und keines wurde markiert. | Ja |
cantTell | Erfordert menschliches Urteil: entweder wirklich mehrdeutig oder ein Hinweis einer manuellen Regel. | Ja |
notApplicable | Die Regel hat auf dieser Seite bzw. in diesem Bereich keine Elemente gefunden, auf die sie anwendbar ist. | Ja |
In den eingebauten Regeln von core ist fail bewusst das engste Ergebnis mit der höchsten Hürde: deterministischen, normativen Verstößen vorbehalten; das Streben nach mehr Regelabdeckung darf es nie verwässern.
Werte für Schweregrad und Konfidenz
severity:minor<moderate<serious<critical: die Einschätzung der Regelautorin bzw. des Regelautors zu den Auswirkungen auf Nutzende, unabhängig vonconfidence. Ein Profil kann einer Regel einen anderen Schweregrad geben (dieseverityeines Profils in einer Norm oder in der Checkliste eines Packs): Darunter zeigt das Ergebnis den des Profils, behält den eigenen der Regel alsruleSeverity(nur dann vorhanden), und die Zusammenfassungen übernehmen den des Profils.confidence:low<medium<high: wie sicher die Engine ist, dass einfail/cantTell-Urteil stimmt. Beides sind informative Metadaten zur Priorisierung; keins von beiden ändert die Bedeutung vonoutcome.
Ein fail hat nicht immer confidence: "high", und das ist kein Widerspruch. Das Ergebnis beschreibt das Entscheidungsverfahren (es hat die Frage ohne Raten beantwortet), während confidence das Modell beschreibt, gegen das entschieden wurde. Einige automatische Regeln entscheiden deterministisch gegen etwas, das selbst eine Näherung ist (die kuratierten WAI-ARIA-Rollentabellen, die Zuordnungen nativer Rollen, ein aus statischem Markup abgeleiteter Accessibility Tree), und melden medium: aria-required-children, aria-prohibited-children, aria-required-parent, aria-allowed-attr, form-control-programmatic-label-present, identical-iframes-same-purpose, svg-image-text-alternative-present, video-poster-text-alternative-present, target-size-minimum und text-spacing-content-loss. confidence steht in jedem Ergebnis, sodass ein Konsument, der nur die sichersten Verstöße will, direkt danach filtern kann; policy.allowedConfidence erledigt das nicht für Sie, da ein nicht zulässiger Wert durch den defaultConfidence der Regel ersetzt wird, statt das Ergebnis zu ändern (siehe POLICY.md).
Durchgerechnetes Beispiel
Scan von <img src="logo.png"> (ohne alt) und <button></button> (ohne zugänglichen Namen), eingegrenzt auf genau diese beiden Regeln über runOnly: { includeRuleIds: [...] } (siehe Engine-Optionen; seit 1.10.0 bewirkt ein reines Array von Regel-IDs dasselbe):
const result = runDomRulesInPage('https://example.test/',null,{},{ includeRuleIds: ['img-alt-present', 'button-name-present'] });
{"engine": {"tag": "a11ycore","version": "1.14.0","schemaVersion": "1.0.0","locale": { "requested": "en", "resolved": "en", "reason": "ok" },"wcagVersion": "2.2","environment": { "layout": false }},"url": "https://example.test/","title": "Example","timestamp": null,"perfStats": null,"contextSelector": null,"contextMatch": null,"checksResults": [{"ruleId": "button-name-present","outcome": "fail","severity": "serious","confidence": "high","type": "automatic","occurrences": [{"selector": "html > body > button","html": "<button></button>","structuralPath": [1, 1],"summary": "This button has no accessible name.","hint": "Give the button visible text, or name it with aria-label, so screen reader users know what it does.","data": {"visibilityFilter": { "eligible": true, "reasons": [], "targetSet": "acc", "accEligible": true },"details": { "reasonCode": "name_missing" }}}]},{"ruleId": "img-alt-present","outcome": "fail","severity": "serious","confidence": "high","type": "automatic","occurrences": [{"selector": "html > body > img","html": "<img src=\"logo.png\">","structuralPath": [1, 0],"summary": "This <img> has no alt attribute.","hint": "Add an alt attribute that says what the image shows, or alt=\"\" if the image is purely decorative.","data": {"details": { "reasonCode": "TEXT_ALTERNATIVE_MISSING" },"visibilityFilter": { "eligible": true, "reasons": [], "targetSet": "acc", "accEligible": true }}}]}],"rulesResults": [{"ruleId": "wcag-1.1.1-non-text-content","outcome": "fail","severity": "serious","title": "Non-text content: text alternatives","occurrences": [],"data": {"details": {"reasonCode": "composite.rollup.fail.anyFail","checksIds": ["area-alt-present", "img-alt-decorative", "img-alt-quality", "..."],"contributors": [{ "testId": "area-alt-present", "outcome": "missing", "notSelected": true },"...",{ "testId": "img-alt-present", "outcome": "fail", "severity": "serious" },"..."],"metrics": { "failCount": 1, "cantTellCount": 0, "notApplicableCount": 0, "passCount": 0, "missingCount": 20 }}}},{"ruleId": "wcag-4.1.2-name","outcome": "fail","severity": "serious","title": "Name, role, value: accessible name","occurrences": [],"data": {"details": {"reasonCode": "composite.rollup.fail.anyFail","metrics": { "failCount": 1, "cantTellCount": 0, "notApplicableCount": 0, "passCount": 0, "missingCount": 23 }}}}],"overriddenBuiltinIds": [],"skippedCustomRules": []}
(Zur besseren Lesbarkeit gekürzt: Das echte Ergebnis enthält laut der vollständigen Struktur oben in jedem Eintrag zusätzlich title/description/i18n/meta/engineOptions/schemaVersion, und jede beitragende Regel jeder Zusammenfassung. rulesResults enthält die Kriterien, die die beiden genannten Regeln prüfen: 1.1.1 für img-alt-present und 4.1.2 für button-name-present, beide fail, weil ihre Regel fail ergab. Die übrigen Regeln dieser Kriterien wurden nicht ausgewählt und sind daher missing mit notSelected: true; ohne eine Regel mit fail wären die Kriterien cantTell (notSelectedChild), teilweise geprüft. Die rollupIds jedes Prüfergebnisses nennen seine Zusammenfassung.)