Skip to content

Commit a75156f

Browse files
Abhi3685mattscepterakhillb
authored
Release 6.3.1 (#211)
* Added reviewPayload and updated metadata * Addressed comments * Updated rules.json for all * Addressed comments * Addressed comments * Comments updated * feat: Add htmlHash fingerprint for violation node dedup (#206) * Fixed prettier check failing --------- Co-authored-by: Utkarsh Chaudhary <utkarsh.ch@browserstack.com> Co-authored-by: Akhil Lb <akhil.lb1@gmail.com>
1 parent 0b45751 commit a75156f

40 files changed

Lines changed: 192 additions & 41 deletions

build/tasks/esbuild.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
const { build } = require('esbuild');
22
const path = require('path');
3+
const fs = require('fs');
4+
5+
// [a11y-core]: resolve ip-protection imports to real file in monorepo,
6+
// or fall back to a stub when building axe-core standalone (CI).
7+
// Set A11Y_FINGERPRINT_PATH env var to override the fingerprint module location.
8+
const fingerprintFallback = {
9+
name: 'a11y-fingerprint-fallback',
10+
setup(pluginBuild) {
11+
pluginBuild.onResolve(
12+
{ filter: /ip-protection\/utils\/fingerprint/ },
13+
args => {
14+
if (process.env.A11Y_FINGERPRINT_PATH) {
15+
const envPath = path.resolve(process.env.A11Y_FINGERPRINT_PATH);
16+
if (fs.existsSync(envPath)) {
17+
return { path: envPath };
18+
}
19+
}
20+
const realPath = path.resolve(args.resolveDir, args.path + '.js');
21+
if (fs.existsSync(realPath)) {
22+
return { path: realPath };
23+
}
24+
return {
25+
path: path.resolve(
26+
__dirname,
27+
'../../lib/core/utils/fingerprint-stub.js'
28+
)
29+
};
30+
}
31+
);
32+
}
33+
};
334

435
module.exports = function (grunt) {
536
grunt.registerMultiTask(
@@ -24,7 +55,8 @@ module.exports = function (grunt) {
2455
outfile: path.join(dest, name),
2556
minify: false,
2657
format: 'esm',
27-
bundle: true
58+
bundle: true,
59+
plugins: [fingerprintFallback]
2860
})
2961
.then(done)
3062
.catch(e => {

build/tasks/validate.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,15 @@ function createSchemas() {
227227
description: {
228228
required: true,
229229
type: 'string'
230+
},
231+
violationConfidence: {
232+
type: 'number'
233+
},
234+
needsReviewConfidence: {
235+
type: 'number'
236+
},
237+
defaultCategory: {
238+
type: 'string'
230239
}
231240
}
232241
}

lib/checks/aria/aria-prohibited-attr-evaluate.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,15 @@ export default function ariaProhibitedAttrEvaluate(
5959

6060
let messageKey = role !== null ? 'hasRole' : 'noRole';
6161
messageKey += prohibited.length > 1 ? 'Plural' : 'Singular';
62-
this.data({ role, nodeName, messageKey, prohibited });
62+
// a11y-rule-aria-prohibited-attr: reviewPayload for bulk NR
63+
const accessibleName = axe.commons.text.accessibleText(node);
64+
this.data({
65+
role,
66+
nodeName,
67+
messageKey,
68+
prohibited,
69+
reviewPayload: { visualHelperData: { accessibleName } }
70+
});
6371

6472
// `subtreeDescendant` to override namedFromContents
6573
const textContent = subtreeText(virtualNode, { subtreeDescendant: true });

lib/checks/color/color-contrast-evaluate.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,20 @@ export default function colorContrastEvaluate(node, options, virtualNode) {
148148
fontWeight: bold ? 'bold' : 'normal',
149149
messageKey: missing,
150150
expectedContrastRatio: expected + ':1',
151-
shadowColor: shadowColor ? shadowColor.toHexString() : undefined
151+
shadowColor: shadowColor ? shadowColor.toHexString() : undefined,
152+
// a11y-rule-color-contrast: reviewPayload for bulk NR
153+
reviewPayload: {
154+
visualHelperData: {
155+
fgColor: fgColor ? fgColor.toHexString() : null,
156+
bgColor: bgColor ? bgColor.toHexString() : null,
157+
isLargeText: !isSmallFont,
158+
textContent: visibleText
159+
? visibleText.length <= 100
160+
? visibleText
161+
: visibleText.slice(0, visibleText.lastIndexOf(' ', 100) || 100)
162+
: null
163+
}
164+
}
152165
});
153166

154167
// We don't know, so we'll put it into Can't Tell

lib/checks/label/label-content-name-mismatch-evaluate.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,29 @@ function labelContentNameMismatchEvaluate(node, options, virtualNode) {
140140
isHumanInterpretable(accText) < 1 ||
141141
isHumanInterpretable(visibleText) < 1
142142
) {
143+
// a11y-rule-label-content-name-mismatch: reviewPayload for bulk NR
144+
this.data({
145+
reviewPayload: {
146+
visualHelperData: {
147+
accessibleName: accText || null
148+
}
149+
}
150+
});
143151
return undefined;
144152
}
145153

146-
return isStringContained(visibleText, accText);
154+
const result = isStringContained(visibleText, accText);
155+
if (!result) {
156+
// a11y-rule-label-content-name-mismatch: reviewPayload for bulk NR
157+
this.data({
158+
reviewPayload: {
159+
visualHelperData: {
160+
accessibleName: accText || null
161+
}
162+
}
163+
});
164+
}
165+
return result;
147166
}
148167

149168
export default labelContentNameMismatchEvaluate;

lib/core/reporters/helpers/process-aggregate.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,9 @@ function trimElementSpec(elmSpec = {}, runOptions) {
103103
if (runOptions.xpath) {
104104
serialElm.xpath = elmSpec.xpath ?? ['/'];
105105
}
106+
// [a11y-core]: propagate htmlHash to final output
107+
if (elmSpec.htmlHash) {
108+
serialElm.htmlHash = elmSpec.htmlHash;
109+
}
106110
return serialElm;
107111
}

lib/core/utils/dq-element.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import cache from '../base/cache';
77
import memoize from './memoize';
88
import getNodeAttributes from './get-node-attributes';
99
import VirtualNode from '../../core/base/virtual-node/virtual-node';
10+
import { computeFingerprintHash } from '../../../../ip-protection/utils/fingerprint';
1011

1112
const CACHE_KEY = 'DqElm.RunOptions';
1213

@@ -341,6 +342,9 @@ const DqElement = memoize(function DqElement(elm, options, spec) {
341342
this.nodeIndexes = [this._virtualNode.nodeIndex];
342343
}
343344

345+
// [a11y-core]: compute htmlHash before truncation
346+
this._htmlHash = computeFingerprintHash(this._element?.outerHTML);
347+
344348
/**
345349
* The generated HTML source code of the element
346350
* @type {String|null}
@@ -411,7 +415,8 @@ DqElement.prototype = {
411415
xpath: this.xpath,
412416
ancestry: this.ancestry,
413417
nodeIndexes: this.nodeIndexes,
414-
fromFrame: this.fromFrame
418+
fromFrame: this.fromFrame,
419+
htmlHash: this._htmlHash
415420
};
416421
if (this._includeElementInJson) {
417422
spec.element = this._element;

lib/core/utils/fingerprint-stub.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Fallback stub used when axe-core builds outside the a11y-engine monorepo.
2+
// The real fingerprint logic lives in ip-protection/utils/fingerprint.js
3+
// and is resolved by the esbuild plugin during monorepo builds.
4+
// eslint-disable-next-line no-unused-vars
5+
export function computeFingerprintHash(_outerHTML) {
6+
return null;
7+
}

lib/rules/accesskeys.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"tags": ["cat.keyboard", "best-practice"],
77
"metadata": {
88
"description": "Ensure every accesskey attribute value is unique",
9-
"help": "accesskey attribute value should be unique"
9+
"help": "accesskey attribute value should be unique",
10+
"violationConfidence": 99
1011
},
1112
"all": [],
1213
"any": [],

lib/rules/aria-allowed-attr.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"actIds": ["5c01ea"],
1515
"metadata": {
1616
"description": "Ensure an element's role supports its ARIA attributes",
17-
"help": "Elements must only use supported ARIA attributes"
17+
"help": "Elements must only use supported ARIA attributes",
18+
"needsReviewConfidence": 50
1819
},
1920
"all": ["aria-allowed-attr"],
2021
"any": [],

0 commit comments

Comments
 (0)