testaro 74.2.2 → 74.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tests/axe.js +45 -2
package/package.json
CHANGED
package/tests/axe.js
CHANGED
|
@@ -134,6 +134,45 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
134
134
|
});
|
|
135
135
|
// If standard results are to be reported and there are any suspicions:
|
|
136
136
|
if (standard && (totals.rulesViolated || totals.rulesWarned)) {
|
|
137
|
+
// Resolve each suspected element's FULL data-xpath from the live DOM,
|
|
138
|
+
// keyed by its axe target. axe-core truncates node.html (~300 chars,
|
|
139
|
+
// appends '...'), so parsing data-xpath out of node.html yields a
|
|
140
|
+
// truncated XPath for elements with long attribute lists. node.target
|
|
141
|
+
// is a reliable CSS selector; read the injected data-xpath directly off
|
|
142
|
+
// the element instead. Falls back to the node.html parse on any failure.
|
|
143
|
+
const fullXPathByTargetKey = {};
|
|
144
|
+
try {
|
|
145
|
+
const suspectNodes = ['incomplete', 'violations']
|
|
146
|
+
.filter(certainty => nativeResult?.details?.[certainty])
|
|
147
|
+
.flatMap(certainty => nativeResult.details[certainty].flatMap(rule => rule.nodes));
|
|
148
|
+
const targets = suspectNodes.map(node => node.target);
|
|
149
|
+
const resolvedXPaths = await page.evaluate(targetList => targetList.map(target => {
|
|
150
|
+
try {
|
|
151
|
+
// axe target is an array of selectors (nested arrays for frames/
|
|
152
|
+
// shadow roots). Use the deepest plain-string selector for the
|
|
153
|
+
// common, non-framed case; skip otherwise.
|
|
154
|
+
const selector = Array.isArray(target)
|
|
155
|
+
? (typeof target[target.length - 1] === 'string' ? target[target.length - 1] : null)
|
|
156
|
+
: (typeof target === 'string' ? target : null);
|
|
157
|
+
if (! selector) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
const element = document.querySelector(selector);
|
|
161
|
+
return element ? element.getAttribute('data-xpath') : null;
|
|
162
|
+
}
|
|
163
|
+
catch(error) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}), targets);
|
|
167
|
+
suspectNodes.forEach((node, index) => {
|
|
168
|
+
if (resolvedXPaths[index]) {
|
|
169
|
+
fullXPathByTargetKey[JSON.stringify(node.target)] = resolvedXPaths[index];
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch(error) {
|
|
174
|
+
// Leave the map empty; every instance falls back to node.html below.
|
|
175
|
+
}
|
|
137
176
|
// For each certainty type:
|
|
138
177
|
['incomplete', 'violations'].forEach(certainty => {
|
|
139
178
|
// If there are any suspicions of this type:
|
|
@@ -153,8 +192,12 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
153
192
|
+ (certainty === 'violations' ? 2 : 0);
|
|
154
193
|
// Increment the standard total.
|
|
155
194
|
standardResult.totals[ordinalSeverity]++;
|
|
156
|
-
// Get the XPath of the suspected element from its data-xpath
|
|
157
|
-
|
|
195
|
+
// Get the XPath of the suspected element from its data-xpath
|
|
196
|
+
// attribute. Prefer the full value resolved from the live DOM
|
|
197
|
+
// (above); fall back to parsing it out of axe's node.html,
|
|
198
|
+
// which axe truncates and can corrupt the XPath.
|
|
199
|
+
const xPath = fullXPathByTargetKey[JSON.stringify(node.target)]
|
|
200
|
+
|| getAttributeXPath(node.html);
|
|
158
201
|
const instance = {
|
|
159
202
|
ruleID: rule.id,
|
|
160
203
|
what: Array.from(whatSet.values()).join('; '),
|