Opciones del motor

Todos los ejecutores (runDomRulesInPage, runa11yCoreInPage) reciben los mismos cuatro argumentos: (pageUrl, contextSelector, engineOptions, runOnly). Esta página documenta engineOptions y runOnly en su totalidad.

Seleccionar qué reglas se ejecutan

Hay dos formas independientes de seleccionar reglas: el cuarto argumento (runOnly), o bien engineOptions.rules/.tags/.tests/.includeMode. Si runOnly contiene algún filtro, tiene prioridad; de lo contrario, el motor recurre a engineOptions. No combines ambos mecanismos: no se aplican simultáneamente. Elige uno.

Mediante runOnly (4.º argumento)

runDomRulesInPage(url, null, {}, {
includeRuleIds: ['img-alt-present', 'button-name-present'],
excludeRuleIds: ['region'],
tags: ['wcag412'],
excludeTags: ['best-practice'],
includeMode: 'and' // 'and' (default) | 'or' — see below
});

runOnly debe tener esta forma de objeto, no ser un array simple. runOnly: ['img-alt-present'] (un array simple) se ignora silenciosamente; el motor ejecuta todas las reglas en su lugar. Este es el error de integración más común con diferencia. Consulta las preguntas frecuentes.

CampoTipoSignificado
includeRuleIdsstring[]Ejecuta solo estos IDs de regla (además, para un ID compuesto, sus reglas atómicas hijas).
excludeRuleIdsstring[]Nunca ejecuta estos, se aplica después de la inclusión.
includeTestIds / excludeTestIdsstring[]Misma coincidencia que arriba: se mantiene como un campo separado porque las reglas se llaman internamente "tests" (la unidad ejecutable atómica); funcionalmente idéntico a includeRuleIds/excludeRuleIds hoy en día.
tagsstring[]Ejecuta solo las reglas que llevan al menos una de estas etiquetas (por ejemplo, wcag412, wcag2aa, best-practice).
excludeTagsstring[]Nunca ejecuta reglas que lleven cualquiera de estas etiquetas, se aplica después de la inclusión.
includeMode'and' | 'or'Cuando se dan tanto una inclusión de ID como una de etiqueta: 'and' (predeterminado) requiere que una regla satisfaga ambas; 'or' ejecuta una regla si satisface cualquiera de las dos. Irrelevante si solo usas una dimensión.

Cada uno de estos acepta un array o una cadena separada por comas, igual que la forma de engineOptions de más abajo: includeRuleIds: 'img-alt-present, button-name-present' y includeRuleIds: ['img-alt-present', 'button-name-present'] son equivalentes.

Los IDs de regla van sin prefijo (sin prefijo del motor), por ejemplo 'img-alt-present'. Por compatibilidad con versiones anteriores, la coincidencia también acepta una forma heredada con el prefijo a11ycore- del mismo id ('a11ycore-img-alt-present').

También se acepta una forma heredada de filtro por etiqueta como valor completo de runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa'] }, equivalente a { tags: ['wcag2a', 'wcag2aa'] }.

Filtrado por versión de WCAG (2.0, 2.1, 2.2)

Cada regla y compuesto lleva exactamente una etiqueta de nivel de versión de origen de WCAG: wcag2a/wcag2aa/wcag2aaa para un Criterio de Éxito (SC) que sea línea base de WCAG 2.0, wcag21a/wcag21aa/wcag21aaa para uno introducido en WCAG 2.1 (por ejemplo, 1.3.5 Identify Input Purpose), wcag22a/wcag22aa/wcag22aaa para uno introducido en WCAG 2.2 (por ejemplo, 2.5.8 Target Size Minimum). Una regla obtiene solo la etiqueta de la versión de origen real de su criterio de éxito: un criterio de éxito introducido en 2.1 nunca lleva también la etiqueta wcag2aa, ya que no existe bajo un objetivo de conformidad de WCAG 2.0.

Dado que las versiones son acumulativas (2.1 = 2.0 + nuevo; 2.2 = 2.0 + 2.1 + nuevo), selecciona un objetivo de conformidad de versión de WCAG combinando conjuntos de etiquetas: la coincidencia OR del motor sobre tags (cualquier coincidencia incluye la regla) hace el resto:

// WCAG 2.0 AA only (excludes every 2.1/2.2-introduced SC, even at level AA):
{ tags: ['wcag2a', 'wcag2aa'] }
 
// WCAG 2.1 AA conformance (2.0 baseline + everything 2.1 added, both at A and AA):
{ tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'] }
 
// WCAG 2.2 AA conformance (2.0 baseline + 2.1 additions + 2.2 additions):
{ tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'] }
 
// Just the SCs 2.2 introduced, nothing else:
{ tags: ['wcag22a', 'wcag22aa', 'wcag22aaa'] }

Un criterio de éxito va en sentido contrario. WCAG 2.2 eliminó el criterio de éxito 4.1.1 Parsing: el único criterio que se ha eliminado alguna vez en lugar de añadirse. Una regla mapeada a él lleva su etiqueta de origen 2.0 (wcag2a) como cualquier otra regla de línea base, más wcag22-removed, y por eso los conjuntos de etiquetas de versión de arriba la incluyen bajo un objetivo 2.2, donde no pertenece.

No tienes que hacer nada al respecto. El motor resuelve una versión objetivo de WCAG para cada ejecución y, cuando ese objetivo es 2.2, una regla wcag22-removed no puede informar fail: sigue ejecutándose, sigue informando cada ocurrencia que encontró, pero su resultado se fuerza a cantTell y el resultado lleva un campo wcagVersionScope que explica por qué (consulta el esquema de salida). Nada se descarta silenciosamente, y una ejecución 2.2 no queda bloqueada por un criterio que 2.2 no contiene.

La versión objetivo se resuelve en este orden:

  1. engineOptions.wcagVersion: '2.0', '2.1' o '2.2', si lo configuras.
  2. Las etiquetas de origen de versión en tu propio filtro: un conjunto que llega como máximo hasta wcag21a/wcag21aa se interpreta como objetivo 2.1, uno que contiene cualquier wcag22* etiqueta como 2.2, uno con solo etiquetas wcag2* como 2.0. Solo cuentan esas nueve etiquetas: una etiqueta de criterio de éxito (wcag411) o best-practice no dice nada sobre una versión.
  3. En caso contrario '2.2', el objetivo predeterminado de este motor.
// Nothing to declare: a plain run already targets 2.2, so a duplicate id
// comes back cantTell rather than fail.
runDomRulesInPage(url, null, {}, null);
 
// Conformance-testing against 2.1, where SC 4.1.1 still exists:
runDomRulesInPage(url, null, { wcagVersion: '2.1' }, null);
 
// Same thing, implied by the tag set — no extra option needed:
runDomRulesInPage(url, null, {}, { tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'] });

La versión de destino resuelta se incluye en cada resultado como engine.wcagVersion, así puedes confirmar cuál usó realmente una ejecución.

Si prefieres no ver la regla en absoluto bajo 2.2, exclúyela directamente: la etiqueta está ahí precisamente para eso:

// WCAG 2.2 AA conformance, with the removed criterion left out entirely:
{
tags: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'],
excludeTags: ['wcag22-removed']
}

duplicate-id es la única regla que lleva esa etiqueta hoy en día. Si se deja, sigue informando algo real (un id duplicado rompe <label for>, los enlaces de fragmento y getElementById diga lo que diga el estándar), simplemente no es un fallo de conformidad 2.2.

Mediante engineOptions (sin runOnly)

El mismo filtrado, expresado como cadenas separadas por comas (o arrays) anidadas en engineOptions:

runDomRulesInPage(url, null, {
rules: { include: 'img-alt-present, button-name-present', exclude: 'region' },
tags: { include: 'wcag412', exclude: 'best-practice' },
includeMode: 'and'
}, null);

rules.include/.exclude, tags.include/.exclude, tests.include/.exclude (alias de rules), y el includeMode de nivel superior reflejan exactamente los campos de runOnly de arriba. Las cadenas separadas por comas se recortan, se eliminan duplicados y los tokens vacíos se descartan automáticamente.

engineOptions: el resto

const engineOptions = {
locale: 'en', // default 'en'; de-DE falls back to de, then to en per string
wcagVersion: '2.2', // default '2.2' — the conformance target
messages: { de: { /* key: text */ } }, // optional caller-supplied dictionaries; win over built-in ones
includeHiddenElements: false, // default false — set true to evaluate hidden/collapsed subtrees too
includeShadowDom: true, // default true — opt OUT with false to skip open shadow roots
fragment: false, // default false — set true when the scan target isn't a real page
excludeSelectors: ['#cookie-banner', '.third-party-widget'], // array or comma-separated string
timestamp: '2026-07-20T12:00:00Z', // optional — engine has no built-in clock
perfStats: false, // default false — internal timing counters, debug-only shape
profileRules: false, // default false — per-rule timings; needs perfStats
 
contrast: {
mode: 'strictConformance', // 'strictConformance' (default) | 'auditorAssist'
rootCanvasFallback: '#ffffff' // background assumed when the true root background isn't computable
},
visibilityMode: 'styleOnly', // 'styleOnly' (default) | 'styleAndGeometry' — scoped to the contrast rules only
 
policyContract: 'a11y', // 'a11y' (default) | 'generic' | inline contract object
policy: { // optional overrides on top of policyContract
coerceManualFailToCantTell: true
},
 
output: {
includeSelector: true, // set false to suppress auto-filled selectors
includeHtml: true
},
 
rules: {
'some-rule-id': {
excludeSelectors: ['.some-noisy-widget'] // narrows candidates for THIS rule only
}
},
 
probes: { /* optional host-supplied evidence */ },
 
customRules: [ /* runtime-registered rules, see below */ ],
 
// Only read by runa11yCoreAcrossFrames. Ignored by runDomRulesInPage/runa11yCoreInPage.
pingWaitTime: 500, // ms to wait for a child frame to answer a ping
frameWaitTime: 60000 // ms to wait for a child frame's full scan result
};
OpciónSignificado
localeCualquier cadena. Un código con una subetiqueta recurre primero a su idioma base, así de-DE usa de; si eso falla, inglés. Las cadenas individuales luego recurren de la misma manera (configuración regional elegida → en → el texto literal en inglés de la regla), por lo que una configuración regional parcialmente traducida nunca produce texto faltante. Todo esto es silencioso en las propias cadenas, así que el resultado informa lo que realmente ocurrió en engine.locale: compruébalo si necesitas saber si obtuviste el idioma que pediste. Consulta Configuración regional.
wcagVersion'2.0', '2.1' o '2.2': qué versión de WCAG está probando la conformidad de la ejecución. El valor predeterminado es el que implican tus etiquetas de origen de versión, y '2.2' cuando no implican ninguna. Lo único que cambia actualmente es el criterio de éxito 4.1.1 Parsing, eliminado en 2.2: bajo un objetivo 2.2, una regla etiquetada wcag22-removed sigue ejecutándose y sigue informando sus ocurrencias, pero no puede fail. Consulta "Filtrado por versión de WCAG" más arriba. Cualquier otro valor se ignora y se aplica el valor predeterminado.
messagesOpcional { [locale]: { key: text } }. Se comprueba antes que las propias tablas del motor, así que puede sobrescribir cadenas individuales o proporcionar un idioma que la compilación no incluye. Las claves que omitas recurren al comportamiento normal, así que una sobrescritura parcial está bien. Así es como el paquete independiente para navegador recibe un archivo lateral de configuración regional, y es la única forma de introducir un diccionario en un contexto de página, ya que el ejecutor en la página está serializado y no puede leer archivos. Consulta Configuración regional.
includeHiddenElementsPredeterminado false: las consultas auxiliares excluyen elementos ocultos por mecanismos estructurales/CSS como display:none, [hidden], <details> cerrados, y elementos host ocultos de solo renderizado (con sus descendientes también excluidos). Configura true para incluir esos subárboles ocultos/colapsados en la evaluación (comportamiento heredado/de marcado estático).
includeShadowDomPredeterminado true: las reglas que usan helpers.queryAllSmart atraviesan las raíces shadow abiertas. Configura false para analizar solo el DOM ligero (light DOM). Las raíces shadow cerradas nunca son alcanzables de todos modos: ninguna API del DOM las expone.
fragmentPredeterminado false. Un puñado de reglas comprueba la presencia de una propiedad que existe una vez por página real: page-title-present, html-lang-attr-present, html-xml-lang-mismatch, aria-hidden-body, css-orientation-lock, meta-refresh-no-exceptions, meta-refresh-timing-absent, meta-viewport-zoom-enabled, meta-viewport-large, page-title-patterns, region, bypass-blocks-present, landmark-one-main, page-has-heading-one, e informa correctamente notApplicable para estas en cuanto contextSelector ha delimitado una ejecución más estrecha que el documento completo (document.documentElement ya no está entre las raíces resueltas), ya que nunca se esperó que un subárbol delimitado llevara su propio <title>/<html lang>/etc. Configura fragment: true para el caso que la delimitación por sí sola no puede detectar: un objetivo de análisis que es el documento completo dado pero que nunca pretendió representar una página real (por ejemplo, un fragmento de componente aislado analizado por sí solo): esto fuerza la misma notApplicable restringida incluso sin delimitar.
excludeSelectorsLos elementos que coinciden con cualquiera de estos selectores (y sus descendientes) se omiten por completo, para todas las reglas: útil para banners de cookies, contenidos incrustados de terceros o widgets conocidos por generar ruido que no controlas. Para excluir algo de una sola regla específica en su lugar, usa rules[ruleId].excludeSelectors más abajo.
timestampSe pasa directamente al campo timestamp de nivel superior del resultado; el motor no genera uno por sí mismo (determinista por diseño).
contrast.modestrictConformance (predeterminado): las reglas de contraste permanecen en silencio (notApplicable/omitidas) cuando el fondo realmente renderizado no se puede calcular con confianza, para proteger contra falsos fail. auditorAssist: sacrifica parte de ese margen de seguridad a cambio de más hallazgos, pensado para un auditor humano que revisará los casos marcados, no para una puerta de CI sin supervisión.
contrast.rootCanvasFallbackEl color de fondo de página que se asume cuando no se puede calcular en absoluto: solo importa en el modo auditorAssist.
visibilityModeControla cuán estrictas son las tres reglas de contraste (contrast-minimum, contrast-enhanced, contrast-computable) al decidir si un nodo de texto es realmente elegible para comprobar. No lo lee ninguna otra regla. 'styleOnly' (predeterminado): la elegibilidad es solo CSS: display, visibility, opacity, ocultamiento por ancestro, etc. 'styleAndGeometry': añade comprobaciones reales de diseño (getClientRects()/getBoundingClientRect()) encima de eso: el texto sin rects de cliente o con ancho/alto cero también se excluye. Recurre a 'styleAndGeometry' cuando se ejecuta bajo un navegador real/Playwright-Puppeteer (runa11yCoreInPage) y quieres que los hallazgos de contraste reflejen el diseño realmente renderizado en lugar de solo el estilo calculado; bajo jsdom puro (runDomRulesInPage) no hay un motor de diseño real, así que 'styleAndGeometry' básicamente solo añade comprobaciones de tamaño cero de getBoundingClientRect(), no una detección real de recorte/desbordamiento. Consulta limitaciones conocidas.
policyContractConsulta POLICY.md: controla qué valores de resultado/confianza están permitidos y si los fail que emitirían las reglas manuales se fuerzan a cantTell.
output.includeSelector / .includeHtmlSuprime el autocompletado automático de selector/html del motor. Dado que todas las reglas se migraron para informar su elemento en lugar de construir ocurrencias a mano (1.5.0), ese autocompletado es el camino que sigue casi todas las 132 reglas del motor: configurar includeSelector: false / includeHtml: false elimina selectores y fragmentos de HTML de la gran mayoría de ellas. Un puñado todavía ensambla esos campos por sí mismo dentro de runInPage y no se ve afectado: entre ellas contrast-minimum/contrast-enhanced (cuyos hallazgos son fragmentos de texto, no elementos), page-title-present e identical-links-same-purpose. Así que esto reduce sustancialmente la salida pero aún no es una garantía de que no haya selectores ni HTML en ninguna parte del resultado.
rules[ruleId]Se pasa a esa regla como ctx.config, y, específicamente para excludeSelectors, el propio motor lo lee antes de que la regla se ejecute. Consulta "excludeSelectors por regla" más abajo. Cualquier otra clave es solo de paso: actualmente ninguna regla distribuida lee ctx.config para nada que no sea excludeSelectors.
probesUn objeto de evidencia opcional, seguro para JSON, que tu aplicación anfitriona puede proporcionar (con límites de profundidad y tamaño impuestos por el motor antes de que las reglas lo vean, vía ctx.inputs.probes): pensado para futuras reglas que puedan aceptar señales suministradas externamente (por ejemplo, mediciones reales de diseño que un análisis estático del DOM no puede calcular por sí mismo). Ninguna regla actual lo consume.
perfStats / profileRulesSolo para depuración. perfStats: true devuelve contadores internos en el campo perfStats del resultado; profileRules: true además añade allí un desglose de tiempos por regla. profileRules por sí solo no hace nada: perfStats es lo que crea el objeto donde vive el desglose. La forma no es parte del contrato de salida estable: no construyas nada sobre ella. Ten en cuenta también que profileRules es la única opción que hace que la salida sea no determinista: los contadores son estables entre ejecuciones idénticas, los tiempos de reloj no lo son. Déjala desactivada si comparas resultados entre ejecuciones.
pingWaitTime / frameWaitTimeSolo lo lee runa11yCoreAcrossFrames (consulta INTEGRATION.md): cuánto tiempo esperar a que un frame hijo responda a un ping (predeterminado 500ms) y a una solicitud de ejecución completa (predeterminado 60000ms) antes de tratarlo como inalcanzable. Lo ignoran runDomRulesInPage/runa11yCoreInPage.

excludeSelectors por regla

El excludeSelectors de nivel superior se aplica a todas las reglas: no hay forma de excluir un elemento de una sola regla mientras se siguen ejecutando todas las demás reglas sobre él. rules[ruleId].excludeSelectors llena ese vacío: reduce los candidatos para solo esa regla, además de (nunca en lugar de) la lista global.

const engineOptions = {
excludeSelectors: ['#cookie-banner'], // applies to every rule, as always
rules: {
'aria-required-children': {
excludeSelectors: ['mat-select', 'mat-stepper', 'mat-horizontal-stepper', 'mat-vertical-stepper']
},
'aria-allowed-attr': {
excludeSelectors: ['mat-progress-spinner']
}
}
};

Por qué querrías esto: el <mat-select> de Angular Material construye su estructura ARIA interna de una manera que dispara un falso positivo específicamente en aria-required-children, aunque el componente por lo demás esté bien. Con solo el excludeSelectors global, la única forma de silenciar ese falso positivo es excludeSelectors: ['mat-select']: lo cual también oculta mat-select a todas las demás reglas, incluidas contrast-minimum y aria-allowed-attr, eliminando silenciosamente cobertura real con la que esas comprobaciones nunca tuvieron problema. El ejemplo de arriba mantiene mat-select completamente visible para todas las reglas excepto la que falla incorrectamente con él.

Las exclusiones efectivas para una regla dada son la unión de la lista global y la lista propia de esa regla: un elemento que coincide con cualquiera de las dos se elimina de los candidatos de esa regla. Una regla cuyos únicos elementos que fallarían quedan todos excluidos de esta manera informa outcome: 'pass' o 'notApplicable' (siguiendo la convención propia de esa regla para el caso sin candidatos), con occurrences: []; nunca outcome: 'fail' con un array occurrences vacío, ya que esa forma exacta está reservada en otra parte del esquema para significar "esta regla lanzó un error" (consulta el esquema de salida).

Acepta las mismas formas que la opción global: un array (['mat-select', 'mat-stepper']) o una cadena separada por comas ('mat-select, mat-stepper').

Si estás usando un paquete de integración (binding) (@surea11y/binding-base y sus wrappers de Playwright/Puppeteer), consulta el propio README de esa integración para ver si su método constructor .exclude() ya tiene una forma por regla: esta es una forma de engineOptions documentada aquí a nivel del motor; no todas las integraciones la han incorporado todavía.

Recetas: combinar opciones para escenarios reales

Puerta de CI: solo WCAG 2.2 AA, ignorando un widget de terceros que no controlas

runDomRulesInPage(url, null, {
excludeSelectors: ['#cookie-banner', '.intercom-launcher'],
tags: { include: 'wcag2a,wcag2aa,wcag21a,wcag21aa,wcag22a,wcag22aa' }
}, null);

Auditor humano haciendo una pasada de contraste en profundidad en un navegador real: sacrifica algo de protección contra falsos positivos a cambio de más hallazgos, y comprueba el diseño real (no solo el estilo calculado) ya que se está controlando una página real. Se muestra con el page.evaluate de Puppeteer (acepta múltiples argumentos); si estás en Playwright, primero envuelve los cuatro argumentos posicionales en un solo objeto; consulta INTEGRATION.md:

const result = await page.evaluate(runa11yCoreInPage, url, null, {
contrast: { mode: 'auditorAssist' },
visibilityMode: 'styleAndGeometry'
}, null);

Reanálisis delimitado de una región tras un cambio de interfaz, omitiendo el shadow DOM: útil en una prueba a nivel de componente donde solo te importa el widget que acabas de cambiar:

runDomRulesInPage(url, '#checkout-form', {
includeShadowDom: false
}, { includeRuleIds: ['form-control-programmatic-label-present', 'button-name-present'] });

Salida reproducible para pruebas de snapshot: fija un timestamp para que dos ejecuciones del mismo HTML produzcan un JSON idéntico byte a byte, y solicita el desglose de tiempos de depuración:

runDomRulesInPage(url, null, {
timestamp: '2026-01-01T00:00:00Z',
perfStats: true,
profileRules: true
}, null);

Una regla personalizada, específica de la organización, junto a las integradas, solo para esta llamada:

runDomRulesInPage(url, null, {
customRules: [{
id: 'org-no-inline-onclick',
meta: { title: 'No inline onclick handlers', defaultSeverity: 'moderate' },
runInPage(ctx) {
const els = ctx.helpers.queryAll('[onclick]');
const occurrences = els.map((el) => ({
selector: ctx.helpers.buildSelector(el),
html: el.outerHTML,
summary: 'Inline onclick handler found.',
hint: 'Move event handling into an external script.'
}));
 
return { ruleId: ctx.rule.ruleId, outcome: occurrences.length ? 'fail' : 'pass', severity: 'moderate', occurrences };
}
}]
}, null);

customRules: reglas registradas en tiempo de ejecución

Todas las reglas distribuidas están incorporadas en src/core.js en tiempo de compilación. engineOptions.customRules es la vía de escape en tiempo de ejecución: un array de descriptores de regla registrados solo para esa llamada; no se añade nada al catálogo estático, y nada persiste entre llamadas. Esto es deliberado, no una limitación que sortear: surea11y ya toma engineOptions nuevas en cada llamada sin configuración global mutable (a diferencia de otros motores, que necesitan un paso de configure()/reset() sobre un runtime compartido), y las reglas personalizadas siguen ese mismo modelo por llamada.

Llamar a la biblioteca directamente es una forma de acceder; la CLI también expone esto vía --custom-rules <path> (un archivo local, cargado una vez por análisis). Consulta la documentación de la CLI.

Un descriptor tiene la misma forma que la propia exportación de un módulo de regla interno: si ya sabes cómo escribir un archivo de regla para este motor, ya conoces esta API:

{
id: 'my-org-custom-rule', // required
meta: { title, description, tags, defaultSeverity, defaultConfidence, /* same fields as a rule module's meta */ },
runInPage(ctx) { /* same ctx shape and same return contract as any built-in rule */ },
applicability(ctx) { return true; }, // optional, same contract as a built-in rule's applicability
data: { /* optional, JSON-serializable */ }
}
  • runInPage/applicability puede ser una función real o una cadena con el código fuente de la función (es decir, fn.toString()). Pasa una función real cuando engineOptions nunca sale del ámbito de JS actual (uso normal en Node/jsdom). Pasa una cadena cuando sí lo hace: por ejemplo, una llamada de Playwright page.evaluate(runa11yCoreInPage, { engineOptions }), donde engineOptions cruza un límite de JSON/clonación estructurada que no puede llevar una referencia Function viva pero sí puede llevar una cadena. El motor reconstruye una cadena vía new Function, el mismo mecanismo que usa la compilación para incrustar el código fuente de cada regla integrada en el ejecutor dentro de la página.
  • meta recibe los mismos valores predeterminados/validación que una regla en tiempo de compilación: omite lo que no necesites; severity tiene como predeterminado moderate, confidence tiene como predeterminado medium, type tiene como predeterminado automatic, etc.
  • Una regla personalizada cuyo id coincide con el de una regla integrada la sobrescribe para ese análisis, en lugar de ejecutar ambas. Dado que una regla personalizada con el mismo nombre es tan probable que sea una colisión accidental como una sobrescritura deliberada, cada colisión se muestra de dos formas: un console.warn que nombra el/los id(s), y un array overriddenBuiltinIds de nivel superior en el resultado (vacío cuando no hay colisión). Consulta el esquema de salida.
  • Un descriptor inválido (id ausente/no-string, o bien un runInPage que no es una función ni una cadena de código fuente reconstruible) se omite silenciosamente: el resto del análisis, incluidas todas las reglas integradas, sigue ejecutándose con normalidad. Esto no es un vacío de validación por corregir: una regla personalizada es código arbitrario proporcionado por quien la llama, así que "fallar cerrado en esta sola entrada, sin abortar el análisis" es el comportamiento predeterminado más seguro, reflejando cómo una regla integrada que lanza un error queda contenida en un cantTell para esa regla en lugar de hacer fallar toda la ejecución.
  • Los resultados aparecen en checksResults exactamente igual que los de cualquier otra regla, incluido el autocompletado automático de selector/html/structuralPath para ocurrencias fail/cantTell que solo adjuntan { __node } (consulta el esquema de salida).

contextSelector (2.º argumento del ejecutor, no un campo de engineOptions)

Un selector CSS (o array de selectores) que delimita el análisis a uno o más subárboles, resuelto vía document.querySelectorAll (todas las coincidencias, no solo la primera), recurriendo a document.documentElement/document.body si nada coincide. Pasa null para analizar todo el documento.

  • Una sola cadena puede ser en sí misma una lista de selectores separados por comas (semántica de unión CSS habitual): '#a, #b' analiza tanto #a como #b.
  • Un array de cadenas analiza la unión de las coincidencias de cada selector: ['#a', '.card'] se comporta igual que '#a, .card'; la forma de array existe para quienes construyen la lista de forma programática.
  • Las regiones superpuestas/anidadas se deduplican automáticamente: un elemento alcanzable desde más de una raíz coincidente solo se informa una vez, no una vez por región.