From 11f259d4e6326a3899e6e2a6281b83b612bc009b Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Mon, 6 Apr 2026 11:15:13 +0530 Subject: [PATCH 1/8] Added reviewPayload and updated metadata --- build/tasks/validate.js | 9 +++++++ .../aria/aria-prohibited-attr-evaluate.js | 11 +++++++- lib/checks/color/color-contrast-evaluate.js | 11 +++++++- .../label-content-name-mismatch-evaluate.js | 21 +++++++++++++++- lib/rules/aria-prohibited-attr.json | 5 +++- lib/rules/color-contrast-enhanced.json | 4 ++- lib/rules/color-contrast.json | 4 ++- lib/rules/label-content-name-mismatch.json | 5 +++- lib/rules/link-in-text-block.json | 4 ++- locales/_template.json | 25 +++++++++++++++---- 10 files changed, 86 insertions(+), 13 deletions(-) diff --git a/build/tasks/validate.js b/build/tasks/validate.js index 9b53a17f..8ef55714 100644 --- a/build/tasks/validate.js +++ b/build/tasks/validate.js @@ -227,6 +227,15 @@ function createSchemas() { description: { required: true, type: 'string' + }, + violationConfidence: { + type: 'number', + }, + needsReviewConfidence: { + type: 'number', + }, + defaultCategory: { + type: 'string', } } } diff --git a/lib/checks/aria/aria-prohibited-attr-evaluate.js b/lib/checks/aria/aria-prohibited-attr-evaluate.js index bee8b99a..fd2af463 100644 --- a/lib/checks/aria/aria-prohibited-attr-evaluate.js +++ b/lib/checks/aria/aria-prohibited-attr-evaluate.js @@ -59,7 +59,16 @@ export default function ariaProhibitedAttrEvaluate( let messageKey = role !== null ? 'hasRole' : 'noRole'; messageKey += prohibited.length > 1 ? 'Plural' : 'Singular'; - this.data({ role, nodeName, messageKey, prohibited }); + // a11y-rule-aria-prohibited-attr: Add reviewPayload with accessible name from prohibited attr value + const accessibleName = + axe.commons.text.accessibleText(node) + this.data({ + role, + nodeName, + messageKey, + prohibited, + reviewPayload: { visualHelperData: { accessibleName } } + }); // `subtreeDescendant` to override namedFromContents const textContent = subtreeText(virtualNode, { subtreeDescendant: true }); diff --git a/lib/checks/color/color-contrast-evaluate.js b/lib/checks/color/color-contrast-evaluate.js index e12d2f62..29c0b8c2 100644 --- a/lib/checks/color/color-contrast-evaluate.js +++ b/lib/checks/color/color-contrast-evaluate.js @@ -148,7 +148,16 @@ export default function colorContrastEvaluate(node, options, virtualNode) { fontWeight: bold ? 'bold' : 'normal', messageKey: missing, expectedContrastRatio: expected + ':1', - shadowColor: shadowColor ? shadowColor.toHexString() : undefined + shadowColor: shadowColor ? shadowColor.toHexString() : undefined, + // a11y-rule-color-contrast: reviewPayload for bulk NR visual helper (violation and needs-review) + reviewPayload: { + visualHelperData: { + fgColor: fgColor ? fgColor.toHexString() : null, + bgColor: bgColor ? bgColor.toHexString() : null, + isLargeText: !isSmallFont, + textContent: visibleText ? visibleText.slice(0, 100) : null + } + } }); // We don't know, so we'll put it into Can't Tell diff --git a/lib/checks/label/label-content-name-mismatch-evaluate.js b/lib/checks/label/label-content-name-mismatch-evaluate.js index f5b72c88..5f97b142 100644 --- a/lib/checks/label/label-content-name-mismatch-evaluate.js +++ b/lib/checks/label/label-content-name-mismatch-evaluate.js @@ -140,10 +140,29 @@ function labelContentNameMismatchEvaluate(node, options, virtualNode) { isHumanInterpretable(accText) < 1 || isHumanInterpretable(visibleText) < 1 ) { + // a11y-rule-label-content-name-mismatch: reviewPayload for NR accessible name display + this.data({ + reviewPayload: { + visualHelperData: { + accessibleName: accText + } + } + }); return undefined; } - return isStringContained(visibleText, accText); + const result = isStringContained(visibleText, accText); + if (!result) { + // a11y-rule-label-content-name-mismatch: reviewPayload for violation accessible name display + this.data({ + reviewPayload: { + visualHelperData: { + accessibleName: accText + } + } + }); + } + return result; } export default labelContentNameMismatchEvaluate; diff --git a/lib/rules/aria-prohibited-attr.json b/lib/rules/aria-prohibited-attr.json index 3cfe5949..4fea7305 100644 --- a/lib/rules/aria-prohibited-attr.json +++ b/lib/rules/aria-prohibited-attr.json @@ -14,7 +14,10 @@ "actIds": ["5c01ea"], "metadata": { "description": "Ensure ARIA attributes are not prohibited for an element's role", - "help": "Elements must only use permitted ARIA attributes" + "help": "Elements must only use permitted ARIA attributes", + "violationConfidence": 90, + "needsReviewConfidence": 60, + "defaultCategory": "names-and-labels" }, "all": [], "any": [], diff --git a/lib/rules/color-contrast-enhanced.json b/lib/rules/color-contrast-enhanced.json index bad39ce4..5af07dfb 100644 --- a/lib/rules/color-contrast-enhanced.json +++ b/lib/rules/color-contrast-enhanced.json @@ -8,7 +8,9 @@ "actIds": ["09o5cg"], "metadata": { "description": "Ensure the contrast between foreground and background colors meets WCAG 2 AAA enhanced contrast ratio thresholds", - "help": "Elements must meet enhanced color contrast ratio thresholds" + "help": "Elements must meet enhanced color contrast ratio thresholds", + "needsReviewConfidence": 50, + "defaultCategory": "text-contrast-enhanced" }, "all": [], "any": ["color-contrast-enhanced"], diff --git a/lib/rules/color-contrast.json b/lib/rules/color-contrast.json index 8c3261f1..61382756 100644 --- a/lib/rules/color-contrast.json +++ b/lib/rules/color-contrast.json @@ -18,7 +18,9 @@ "actIds": ["afw4f7", "09o5cg"], "metadata": { "description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds", - "help": "Elements must meet minimum color contrast ratio thresholds" + "help": "Elements must meet minimum color contrast ratio thresholds", + "needsReviewConfidence": 50, + "defaultCategory": "text-contrast" }, "all": [], "any": ["color-contrast"], diff --git a/lib/rules/label-content-name-mismatch.json b/lib/rules/label-content-name-mismatch.json index 610f21ab..7d4900dd 100644 --- a/lib/rules/label-content-name-mismatch.json +++ b/lib/rules/label-content-name-mismatch.json @@ -17,7 +17,10 @@ "actIds": ["2ee8b8"], "metadata": { "description": "Ensure that elements labelled through their content must have their visible text as part of their accessible name", - "help": "Elements must have their visible text as part of their accessible name" + "help": "Elements must have their visible text as part of their accessible name", + "violationConfidence": 80, + "needsReviewConfidence": 50, + "defaultCategory": "names-and-labels" }, "all": [], "any": ["label-content-name-mismatch"], diff --git a/lib/rules/link-in-text-block.json b/lib/rules/link-in-text-block.json index 27718677..6f114102 100644 --- a/lib/rules/link-in-text-block.json +++ b/lib/rules/link-in-text-block.json @@ -17,7 +17,9 @@ ], "metadata": { "description": "Ensure links are distinguished from surrounding text in a way that does not rely on color", - "help": "Links must be distinguishable without relying on color" + "help": "Links must be distinguishable without relying on color", + "needsReviewConfidence": 50, + "defaultCategory": "links" }, "any": ["link-in-text-block", "link-in-text-block-style"], "all": [ diff --git a/locales/_template.json b/locales/_template.json index 9b0af977..ee38375b 100644 --- a/locales/_template.json +++ b/locales/_template.json @@ -59,7 +59,10 @@ }, "aria-prohibited-attr": { "description": "Ensure ARIA attributes are not prohibited for an element's role", - "help": "Elements must only use permitted ARIA attributes" + "help": "Elements must only use permitted ARIA attributes", + "violationConfidence": 90, + "needsReviewConfidence": 60, + "defaultCategory": "names-and-labels" }, "aria-required-attr": { "description": "Ensure elements with ARIA roles have all required ARIA attributes", @@ -131,11 +134,17 @@ }, "color-contrast-enhanced": { "description": "Ensure the contrast between foreground and background colors meets WCAG 2 AAA enhanced contrast ratio thresholds", - "help": "Elements must meet enhanced color contrast ratio thresholds" + "help": "Elements must meet enhanced color contrast ratio thresholds", + "violationConfidence": 90, + "needsReviewConfidence": 60, + "defaultCategory": "text-contrast-enhanced" }, "color-contrast": { "description": "Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds", - "help": "Elements must meet minimum color contrast ratio thresholds" + "help": "Elements must meet minimum color contrast ratio thresholds", + "violationConfidence": 90, + "needsReviewConfidence": 60, + "defaultCategory": "text-contrast" }, "css-orientation-lock": { "description": "Ensure content is not locked to any specific display orientation, and the content is operable in all display orientations", @@ -243,7 +252,10 @@ }, "label-content-name-mismatch": { "description": "Ensure that elements labelled through their content must have their visible text as part of their accessible name", - "help": "Elements must have their visible text as part of their accessible name" + "help": "Elements must have their visible text as part of their accessible name", + "violationConfidence": 90, + "needsReviewConfidence": 60, + "defaultCategory": "names-and-labels" }, "label-title-only": { "description": "Ensure that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes", @@ -291,7 +303,10 @@ }, "link-in-text-block": { "description": "Ensure links are distinguished from surrounding text in a way that does not rely on color", - "help": "Links must be distinguishable without relying on color" + "help": "Links must be distinguishable without relying on color", + "violationConfidence": 90, + "needsReviewConfidence": 60, + "defaultCategory": "links" }, "link-name": { "description": "Ensure links have discernible text", From bda44957480a15bf7b027e065edbe570bb0d2db3 Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Mon, 6 Apr 2026 12:16:29 +0530 Subject: [PATCH 2/8] Addressed comments --- lib/checks/label/label-content-name-mismatch-evaluate.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/checks/label/label-content-name-mismatch-evaluate.js b/lib/checks/label/label-content-name-mismatch-evaluate.js index 5f97b142..ee6c35ca 100644 --- a/lib/checks/label/label-content-name-mismatch-evaluate.js +++ b/lib/checks/label/label-content-name-mismatch-evaluate.js @@ -144,7 +144,7 @@ function labelContentNameMismatchEvaluate(node, options, virtualNode) { this.data({ reviewPayload: { visualHelperData: { - accessibleName: accText + accessibleName: accText ? accText.slice(0, 100) : null } } }); @@ -157,7 +157,7 @@ function labelContentNameMismatchEvaluate(node, options, virtualNode) { this.data({ reviewPayload: { visualHelperData: { - accessibleName: accText + accessibleName: accText ? accText.slice(0, 100) : null } } }); From 628d0bc70bf6284e5475935f6eaa6cf84e033ae0 Mon Sep 17 00:00:00 2001 From: Utkarsh Chaudhary Date: Thu, 9 Apr 2026 09:56:07 +0530 Subject: [PATCH 3/8] Updated rules.json for all --- lib/rules/accesskeys.json | 3 ++- lib/rules/aria-allowed-attr.json | 3 ++- lib/rules/aria-allowed-role.json | 3 ++- lib/rules/aria-hidden-focus.json | 3 ++- lib/rules/aria-input-field-name.json | 3 ++- lib/rules/aria-meter-name.json | 3 ++- lib/rules/aria-prohibited-attr.json | 2 +- lib/rules/aria-required-children.json | 3 ++- lib/rules/aria-toggle-field-name.json | 3 ++- lib/rules/aria-treeitem-name.json | 3 ++- lib/rules/aria-valid-attr-value.json | 3 ++- lib/rules/blink.json | 3 ++- lib/rules/button-name.json | 3 ++- lib/rules/bypass.json | 3 ++- lib/rules/css-orientation-lock.json | 4 +++- lib/rules/duplicate-id-aria.json | 3 ++- lib/rules/focus-order-semantics.json | 3 ++- lib/rules/form-field-multiple-labels.json | 3 ++- lib/rules/frame-title-unique.json | 3 ++- lib/rules/heading-order-bp.json | 3 ++- lib/rules/heading-order.json | 3 ++- lib/rules/hidden-content.json | 3 ++- lib/rules/identical-links-same-purpose.json | 3 ++- lib/rules/nested-interactive.json | 3 ++- lib/rules/target-size.json | 3 ++- lib/rules/th-has-data-cells.json | 3 ++- lib/rules/video-caption.json | 3 ++- 27 files changed, 54 insertions(+), 27 deletions(-) diff --git a/lib/rules/accesskeys.json b/lib/rules/accesskeys.json index 4b3cdfbc..91b07007 100644 --- a/lib/rules/accesskeys.json +++ b/lib/rules/accesskeys.json @@ -6,7 +6,8 @@ "tags": ["cat.keyboard", "best-practice"], "metadata": { "description": "Ensure every accesskey attribute value is unique", - "help": "accesskey attribute value should be unique" + "help": "accesskey attribute value should be unique", + "violationConfidence": 99 }, "all": [], "any": [], diff --git a/lib/rules/aria-allowed-attr.json b/lib/rules/aria-allowed-attr.json index d9075969..3533d68a 100644 --- a/lib/rules/aria-allowed-attr.json +++ b/lib/rules/aria-allowed-attr.json @@ -14,7 +14,8 @@ "actIds": ["5c01ea"], "metadata": { "description": "Ensure an element's role supports its ARIA attributes", - "help": "Elements must only use supported ARIA attributes" + "help": "Elements must only use supported ARIA attributes", + "needsReviewConfidence": 50 }, "all": ["aria-allowed-attr"], "any": [], diff --git a/lib/rules/aria-allowed-role.json b/lib/rules/aria-allowed-role.json index 62c14398..998c0c67 100644 --- a/lib/rules/aria-allowed-role.json +++ b/lib/rules/aria-allowed-role.json @@ -7,7 +7,8 @@ "tags": ["cat.aria", "best-practice"], "metadata": { "description": "Ensure role attribute has an appropriate value for the element", - "help": "ARIA role should be appropriate for the element" + "help": "ARIA role should be appropriate for the element", + "needsReviewConfidence": 50 }, "all": [], "any": ["aria-allowed-role"], diff --git a/lib/rules/aria-hidden-focus.json b/lib/rules/aria-hidden-focus.json index 84f36292..af661357 100755 --- a/lib/rules/aria-hidden-focus.json +++ b/lib/rules/aria-hidden-focus.json @@ -18,7 +18,8 @@ "actIds": ["6cfa84"], "metadata": { "description": "Ensure aria-hidden elements are not focusable nor contain focusable elements", - "help": "ARIA hidden element must not be focusable or contain focusable elements" + "help": "ARIA hidden element must not be focusable or contain focusable elements", + "needsReviewConfidence": 50 }, "all": [ "focusable-modal-open", diff --git a/lib/rules/aria-input-field-name.json b/lib/rules/aria-input-field-name.json index d43ec944..4e8b97ef 100644 --- a/lib/rules/aria-input-field-name.json +++ b/lib/rules/aria-input-field-name.json @@ -18,7 +18,8 @@ "actIds": ["e086e5"], "metadata": { "description": "Ensure every ARIA input field has an accessible name", - "help": "ARIA input fields must have an accessible name" + "help": "ARIA input fields must have an accessible name", + "needsReviewConfidence": 50 }, "all": [], "any": ["aria-label", "aria-labelledby", "non-empty-title"], diff --git a/lib/rules/aria-meter-name.json b/lib/rules/aria-meter-name.json index 8c9a253a..c1c32abb 100644 --- a/lib/rules/aria-meter-name.json +++ b/lib/rules/aria-meter-name.json @@ -14,7 +14,8 @@ ], "metadata": { "description": "Ensure every ARIA meter node has an accessible name", - "help": "ARIA meter nodes must have an accessible name" + "help": "ARIA meter nodes must have an accessible name", + "violationConfidence": 99 }, "all": [], "any": ["aria-label", "aria-labelledby", "non-empty-title"], diff --git a/lib/rules/aria-prohibited-attr.json b/lib/rules/aria-prohibited-attr.json index 4fea7305..c3b4ef9c 100644 --- a/lib/rules/aria-prohibited-attr.json +++ b/lib/rules/aria-prohibited-attr.json @@ -16,7 +16,7 @@ "description": "Ensure ARIA attributes are not prohibited for an element's role", "help": "Elements must only use permitted ARIA attributes", "violationConfidence": 90, - "needsReviewConfidence": 60, + "needsReviewConfidence": 50, "defaultCategory": "names-and-labels" }, "all": [], diff --git a/lib/rules/aria-required-children.json b/lib/rules/aria-required-children.json index 3ff50d1a..03b3529f 100644 --- a/lib/rules/aria-required-children.json +++ b/lib/rules/aria-required-children.json @@ -15,7 +15,8 @@ "actIds": ["bc4a75", "ff89c9"], "metadata": { "description": "Ensure elements with an ARIA role that require child roles contain them", - "help": "Certain ARIA roles must contain particular children" + "help": "Certain ARIA roles must contain particular children", + "needsReviewConfidence": 50 }, "all": [], "any": ["aria-required-children"], diff --git a/lib/rules/aria-toggle-field-name.json b/lib/rules/aria-toggle-field-name.json index 7f277bcf..a29d62e2 100644 --- a/lib/rules/aria-toggle-field-name.json +++ b/lib/rules/aria-toggle-field-name.json @@ -18,7 +18,8 @@ "actIds": ["e086e5"], "metadata": { "description": "Ensure every ARIA toggle field has an accessible name", - "help": "ARIA toggle fields must have an accessible name" + "help": "ARIA toggle fields must have an accessible name", + "needsReviewConfidence": 50 }, "all": [], "any": [ diff --git a/lib/rules/aria-treeitem-name.json b/lib/rules/aria-treeitem-name.json index 15e6b80d..f94ed71a 100644 --- a/lib/rules/aria-treeitem-name.json +++ b/lib/rules/aria-treeitem-name.json @@ -6,7 +6,8 @@ "tags": ["cat.aria", "best-practice"], "metadata": { "description": "Ensure every ARIA treeitem node has an accessible name", - "help": "ARIA treeitem nodes should have an accessible name" + "help": "ARIA treeitem nodes should have an accessible name", + "violationConfidence": 99 }, "all": [], "any": [ diff --git a/lib/rules/aria-valid-attr-value.json b/lib/rules/aria-valid-attr-value.json index 038a8dc5..afe72fab 100644 --- a/lib/rules/aria-valid-attr-value.json +++ b/lib/rules/aria-valid-attr-value.json @@ -14,7 +14,8 @@ "actIds": ["6a7281"], "metadata": { "description": "Ensure all ARIA attributes have valid values", - "help": "ARIA attributes must conform to valid values" + "help": "ARIA attributes must conform to valid values", + "needsReviewConfidence": 50 }, "all": ["aria-valid-attr-value", "aria-errormessage", "aria-level"], "any": [], diff --git a/lib/rules/blink.json b/lib/rules/blink.json index 6d3205f8..e76a4758 100644 --- a/lib/rules/blink.json +++ b/lib/rules/blink.json @@ -18,7 +18,8 @@ ], "metadata": { "description": "Ensure elements are not used", - "help": " elements are deprecated and must not be used" + "help": " elements are deprecated and must not be used", + "violationConfidence": 99 }, "all": [], "any": [], diff --git a/lib/rules/button-name.json b/lib/rules/button-name.json index ec421553..4037ad55 100644 --- a/lib/rules/button-name.json +++ b/lib/rules/button-name.json @@ -20,7 +20,8 @@ "actIds": ["97a4e1", "m6b1q3"], "metadata": { "description": "Ensure buttons have discernible text", - "help": "Buttons must have discernible text" + "help": "Buttons must have discernible text", + "needsReviewConfidence": 50 }, "all": [], "any": [ diff --git a/lib/rules/bypass.json b/lib/rules/bypass.json index 66eeed20..570e1df4 100644 --- a/lib/rules/bypass.json +++ b/lib/rules/bypass.json @@ -21,7 +21,8 @@ "actIds": ["cf77f2", "047fe0", "b40fd1", "3e12e1", "ye5d6e"], "metadata": { "description": "Ensure each page has at least one mechanism for a user to bypass navigation and jump straight to the content", - "help": "Page must have means to bypass repeated blocks" + "help": "Page must have means to bypass repeated blocks", + "needsReviewConfidence": 50 }, "all": [], "any": ["internal-link-present", "header-present", "landmark"], diff --git a/lib/rules/css-orientation-lock.json b/lib/rules/css-orientation-lock.json index e987805b..43e2b371 100644 --- a/lib/rules/css-orientation-lock.json +++ b/lib/rules/css-orientation-lock.json @@ -17,7 +17,9 @@ "actIds": ["b33eff"], "metadata": { "description": "Ensure content is not locked to any specific display orientation, and the content is operable in all display orientations", - "help": "CSS Media queries must not lock display orientation" + "help": "CSS Media queries must not lock display orientation", + "violationConfidence": 90, + "needsReviewConfidence": 50 }, "all": ["css-orientation-lock"], "any": [], diff --git a/lib/rules/duplicate-id-aria.json b/lib/rules/duplicate-id-aria.json index 9a52cac8..5fb840df 100644 --- a/lib/rules/duplicate-id-aria.json +++ b/lib/rules/duplicate-id-aria.json @@ -17,7 +17,8 @@ "actIds": ["3ea0c8"], "metadata": { "description": "Ensure every id attribute value used in ARIA and in labels is unique", - "help": "IDs used in ARIA and labels must be unique" + "help": "IDs used in ARIA and labels must be unique", + "needsReviewConfidence": 50 }, "all": [], "any": ["duplicate-id-aria"], diff --git a/lib/rules/focus-order-semantics.json b/lib/rules/focus-order-semantics.json index eead6e85..e50f11d8 100644 --- a/lib/rules/focus-order-semantics.json +++ b/lib/rules/focus-order-semantics.json @@ -14,7 +14,8 @@ ], "metadata": { "description": "Ensure elements in the focus order have a role appropriate for interactive content", - "help": "Elements in the focus order should have an appropriate role" + "help": "Elements in the focus order should have an appropriate role", + "violationConfidence": 90 }, "all": [], "any": ["has-widget-role", "valid-scrollable-semantics"], diff --git a/lib/rules/form-field-multiple-labels.json b/lib/rules/form-field-multiple-labels.json index aa0d766d..a5dca1cd 100644 --- a/lib/rules/form-field-multiple-labels.json +++ b/lib/rules/form-field-multiple-labels.json @@ -16,7 +16,8 @@ ], "metadata": { "description": "Ensure form field does not have multiple label elements", - "help": "Form field must not have multiple label elements" + "help": "Form field must not have multiple label elements", + "needsReviewConfidence": 50 }, "all": [], "any": [], diff --git a/lib/rules/frame-title-unique.json b/lib/rules/frame-title-unique.json index 2c9054be..4e9ce6be 100644 --- a/lib/rules/frame-title-unique.json +++ b/lib/rules/frame-title-unique.json @@ -17,7 +17,8 @@ "actIds": ["4b1c6c"], "metadata": { "description": "Ensure