Esquema de salida
Esta es la estructura exacta del objeto que devuelven runDomRulesInPage(...) / runa11yCoreInPage(...) (consulta INTEGRATION.md para saber cuál llamar). Todos los ejemplos de esta página son salida real del motor actual (schemaVersion: "1.0.0"), no están escritos a mano. runa11yCoreAcrossFrames devuelve una estructura distinta y recursiva que envuelve esta. Ver Resultado entre frames más abajo.
Resultado de nivel superior
{engine: {tag: string,schemaVersion: string,locale: { requested: string, resolved: string, reason: string },wcagVersion: "2.0" | "2.1" | "2.2"},url: string | null,title: string | null,timestamp: string | null,perfStats: object | null,contextSelector: string | string[] | null,checksResults: CheckResult[],rulesResults: CompositeResult[],overriddenBuiltinIds: string[]}
| Campo | Significado |
|---|---|
Resultado entre frames (runa11yCoreAcrossFrames)
runa11yCoreAcrossFrames (consulta INTEGRATION.md) devuelve una estructura distinta y recursiva en lugar de un resultado de nivel superior simple:
{topFrame: <the normal top-level result shape above>,frames: Array<| { url: string | null, topFrame: <top-level result>, frames: [...same shape, recursively] }| { url: string | null, error: string }>}
topFramees exactamente la estructura del resultado de nivel superior, para el frame en el que se llamó a la función.framestiene una entrada por cada<iframe>/<frame>hijo directo dentro del ámbito analizado. Un hijo alcanzable (uno que llamó aa11yCoreEnableFrameResponder()) aporta su propio{ url, topFrame, frames }completo: incluyendo sus propiosframesanidados, de forma recursiva, ya que un nieto anidado más profundo solo es alcanzable a través de su padre inmediato. Un hijo inalcanzable (el caso común para la mayoría de los embebidos de terceros, sin responder cooperante o que agotó el tiempo de espera) aporta{ url, error }en su lugar, y no aborta el resto del análisis.- Esto es un árbol, no una lista plana: una diferencia deliberada respecto a
@surea11y/playwright's.frames(true), que sí puede aplanar porquepage.frames()de Playwright ya entrega todos los frames sin importar la profundidad de anidamiento; un relé porpostMessageno tiene esa visión global, así que el anidamiento se expresa de forma estructural en su lugar.
Un resultado de comprobación (checksResults[i])
{ruleId: string,outcome: "pass" | "fail" | "cantTell" | "notApplicable",outcomeNormalized: "pass" | "fail" | "cantTell" | "inapplicable",severity: "minor" | "moderate" | "serious" | "critical",confidence: "high" | "medium" | "low",type: "automatic" | "manual",occurrences: Occurrence[],title: string,description: string,i18n: { titleKey: string, descriptionKey: string } | null,meta: {ruleId: string,ruleInterfaceVersion: string,ruleVersion: string,normative: boolean,atomic: boolean,deprecated: boolean,deprecation: object | null,category: "perceivable" | "operable" | "understandable" | "robust" | null,normativeMappings: Array<{ standard: string, version: string, requirement: string, title: string, conformanceLevel: 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,wcagVersionScope?: { // present only when the target WCAG version changed this outcometarget: "2.0" | "2.1" | "2.2",removedSc: string[],coercedFrom: "fail"},error?: string // present only if the rule threw — see below}
Notas:
outcomefrente aoutcomeNormalized: idénticos, salvo quenotApplicablese convierte en"inapplicable"enoutcomeNormalized. Se ofrecen ambos para que puedas ajustarte a tu propio vocabulario o al vocabulario interno del motor.- Las reglas
type: "manual"nunca pueden devolveroutcome: "fail". Si la lógica propia de una regla manual hubiera dichofail, el motor la fuerza acantTelly añade una nota explicativa aerror: esto se aplica de forma centralizada (policy.coerceManualFailToCantTell, activado por defecto bajo el contrato de políticaa11y; consultaPOLICY.md), no es algo que cada regla tenga que recordar por su cuenta.failestá reservado únicamente para hallazgos deterministas detype: "automatic". meta.normativeMappingses cómo un resultado de comprobación se vincula de vuelta a un criterio de éxito de WCAG:[]para reglas sin mapeo formal a WCAG (este motor las llama reglas consultivastype: "manual"). Consulta Conformidad para ver cómo se agregan.wcagVersionScope: presente solo cuando la versión de WCAG objetivo de la ejecución convirtió elfailde esta regla en uncantTell: hoy eso significa una regla mapeada al SC 4.1.1 Parsing (duplicate-id) bajo el objetivo 2.2 predeterminado, ya que 2.2 eliminó ese criterio.removedScenumera los criterios que dejaron de existir,targetes la versión que los eliminó, ycoercedFromes el outcome que la propia regla devolvió. Las occurrences son las propias de la regla, sin cambios: no se descartó nada, solo cambió el veredicto de conformidad. Ausente en cualquier otro resultado, y nunca se indica a través deerror: no salió nada mal. Consulta Filtrado por versión de WCAG.error: presente solo en tres casos: la implementación de la regla lanzó una excepción no capturada, se activó la coerción defailmanual descrita arriba o cada occurrence de un resultadofailtuvo su recorrido de ancestros topando con un límite de profundidad interno (así que el motor no pudo confirmar que el contenido señalado esté realmente expuesto) y todo el resultado se forzó acantTelldel mismo modo. Una regla que lanza una excepción siempre aparece comooutcome: "cantTell"conoccurrences: []yerrorestablecido al mensaje de la excepción: el motor nunca deja que una regla rota haga fallar todo el análisis.engineOptionsen cada resultado es el objeto de opciones resuelto (después de aplicar los valores predeterminados de locale/contrast), no literalmente lo que pasaste: útil para confirmar qué vio realmente una regla dada, especialmente ellocaleresuelto ycontrast.mode/contrast.rootCanvasFallback.
Una ocurrencia (occurrences[i])
Normalmente presente solo cuando outcome es fail o cantTell: un resultado pass tiene occurrences: [], ya que este motor no enumera los elementos que pasó, solo los que señaló.
notApplicable es la única excepción. Una regla que no tuvo nada que juzgar puede adjuntar una única occurrence explicando por qué, y las reglas de contraste hacen exactamente eso cuando ningún texto tenía un fondo calculable: la diferencia entre «se comprobó, nada que señalar» y «no se pudo comprobar» es algo que este motor indica en lugar de ocultar. Una occurrence así describe el análisis, no un elemento, así que su selector está vacío. No interpretes occurrences.length como un recuento de violaciones sin comprobar antes outcome.
{selector: string,html: string,structuralPath: number[] | null,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},data: {visibilityFilter?: { eligible: boolean, targetSet: string, accEligible: boolean | null, reasons: string[] },details?: object // rule-specific, non-normative — see below}}
| Campo | Significado |
|---|---|
Códigos de incertidumbre
Un cantTell dice que el motor no decidió. uncertainty dice por qué, a partir de un vocabulario cerrado, para que un consumidor pueda ramificar según el motivo en lugar de analizar una cadena de resumen. Está presente solo en una occurrence de nivel cantTell: una de nivel fail estaría afirmando que la regla decidió y no decidió a la vez, así que el motor la omite.
| code | Significado | Forma típica |
|---|---|---|
needed indica, en una frase, qué resolvería la cuestión: lo que un revisor tiene que ir a comprobar. evidence lleva lo que la regla sí llegó a establecer, para que el revisor parta del trabajo del motor en lugar de repetirlo; su estructura es específica de cada regla y, como data.details, no es un contrato estable. En cuanto a code: pueden añadirse códigos nuevos en una versión menor, pero uno existente no cambia de significado, así que ramifica según los códigos que conoces y trata uno no reconocido como «necesita revisión» en lugar de como un error.
Toda regla automática que puede devolver cantTell lleva esto, y una prueba mantiene esa línea para que no pueda llegar una nueva sin ello. El código out-of-scope lo adjunta el motor, no una regla, en las mismas occurrences que producen un wcagVersionScope a nivel de resultado. Las reglas manuales no lo llevan: judgement-required ya es lo que significa type: "manual", así que repetirlo por occurrence no diría nada que el resultado no diga ya.
Un resultado compuesto (rulesResults[i])
Los compuestos agregan varias reglas atómicas en un solo criterio de éxito de WCAG (por ejemplo, wcag-1.1.1-non-text-content agrega 21 reglas atómicas). La estructura es la misma que la de un resultado de comprobación, con un data.details específico de compuestos:
{ruleId: string, // e.g. "wcag-1.1.1-non-text-content"outcome: "pass" | "fail" | "cantTell" | "notApplicable",severity, confidence, type, title, description, meta, engineOptions, schemaVersion, // same as a check resultoccurrences: [], // always empty — composites are rollups, not element-level findingsdata: {details: {reasonCode: string, // e.g. "composite.rollup.fail.anyFail"checksIds: string[], // every atomic ruleId this composite rolls upcontributors: Array<{ testId: string, outcome: string, severity: string | null }>,metrics: { failCount, cantTellCount, notApplicableCount, passCount, missingCount }}}}
Precedencia de la agregación (determinista, en este orden): cualquier contribuyente fail → compuesto fail; si no, cualquier cantTell (o una regla contribuyente que no se ejecutó en absoluto, missingCount > 0) → compuesto cantTell; si no, todos los contribuyentes notApplicable → compuesto notApplicable; si no, pass. Consulta Conformidad para ver qué implica esto en una afirmación de conformidad global.
Valores de outcome
| Resultado | Significado | ¿Puede aparecer en type: "manual"? |
|---|---|---|
fail es, de forma intencional, el outcome más estrecho y de mayor exigencia en este motor: reservado para violaciones deterministas y normativas; la persecución de cobertura de reglas nunca debe diluir esto.
Valores de severity y confidence
severity:minor<moderate<serious<critical: la evaluación del autor de la regla sobre el impacto en el usuario, independiente deconfidence.confidence:low<medium<high: cuán seguro está el motor de que un veredictofail/cantTelles correcto. Ambos son metadatos informativos para priorizar; ninguno cambia el significado deoutcome.
Un fail no siempre tiene confidence: "high", y eso no es una contradicción. El outcome describe el procedimiento de decisión (resolvió la cuestión sin adivinar), mientras que confidence describe el modelo contra el que se tomó esa decisión. Un puñado de reglas automáticas deciden de forma determinista contra algo que en sí mismo es una aproximación (las tablas curadas de roles WAI-ARIA, los mapeos de roles nativos, un árbol de accesibilidad inferido a partir de marcado estático) y devuelven 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 y target-size-minimum. confidence está presente en todo resultado, así que un consumidor que solo quiera los fallos más seguros puede filtrar directamente por él; policy.allowedConfidence no hará eso por ti, ya que un valor no permitido se sustituye por el defaultConfidence propio de la regla en lugar de cambiar el outcome (consulta POLICY.md).
Ejemplo resuelto
Analizando <img src="logo.png"> (sin alt) y <button></button> (sin nombre accesible), limitado a esas dos reglas mediante runOnly: { includeRuleIds: [...] } (ver Opciones del motor; esto no es un array simple):
const result = runDomRulesInPage('https://example.test/',null,{},{ includeRuleIds: ['img-alt-present', 'button-name-present'] });
{"engine": {"tag": "a11ycore","schemaVersion": "1.0.0","locale": { "requested": "en", "resolved": "en", "reason": "ok" }},"url": "https://example.test/","title": "Example","timestamp": null,"perfStats": null,"contextSelector": 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": "Provide visible button text or a programmatic accessible-name mechanism (for example aria-label) so assistive technologies can identify the button.","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": "Missing alt attribute on <img>.","hint": "Add an alt attribute (use alt=\"\" only for decorative images)."}]}],"rulesResults": [],"overriddenBuiltinIds": []}
(Recortado por legibilidad: el resultado real también incluye title/description/i18n/meta/engineOptions/schemaVersion en cada entrada, según la estructura completa mostrada arriba. rulesResults está vacío aquí porque runOnly.includeRuleIds limitó el análisis a dos reglas atómicas y no se incluyó el ID propio de ningún compuesto.)