testaro 67.0.0 → 68.0.0
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/LICENSE +4 -16
- package/README.md +10 -2
- package/UPGRADES.md +1 -1
- package/dirWatch.js +2 -3
- package/ed11y/editoria11y.min.js +109 -690
- package/ed11y/editoria11y210.min.js +747 -0
- package/netWatch.js +6 -6
- package/package.json +1 -1
- package/procs/aslint.js +2 -2
- package/procs/catalog.js +190 -0
- package/procs/{dateOf.js → dateTime.js} +6 -4
- package/procs/doActs.js +1227 -0
- package/procs/doTestAct.js +63 -29
- package/procs/error.js +53 -0
- package/procs/job.js +64 -38
- package/procs/launch.js +596 -0
- package/procs/nu.js +3 -18
- package/procs/shoot.js +18 -2
- package/procs/testaro.js +102 -125
- package/procs/xPath.js +62 -0
- package/run.js +42 -1938
- package/scratch/README.md +9 -0
- package/testaro/adbID.js +3 -3
- package/testaro/allCaps.js +4 -5
- package/testaro/allHidden.js +19 -18
- package/testaro/allSlanted.js +4 -5
- package/testaro/altScheme.js +3 -3
- package/testaro/attVal.js +19 -35
- package/testaro/autocomplete.js +65 -62
- package/testaro/bulk.js +21 -20
- package/testaro/buttonMenu.js +112 -33
- package/testaro/captionLoc.js +3 -3
- package/testaro/datalistRef.js +4 -5
- package/testaro/distortion.js +3 -3
- package/testaro/docType.js +6 -9
- package/testaro/dupAtt.js +12 -25
- package/testaro/elements.js +4 -3
- package/testaro/embAc.js +4 -2
- package/testaro/focAll.js +6 -13
- package/testaro/focAndOp.js +3 -3
- package/testaro/focInd.js +3 -3
- package/testaro/focVis.js +4 -3
- package/testaro/headEl.js +5 -12
- package/testaro/headingAmb.js +45 -88
- package/testaro/hovInd.js +5 -5
- package/testaro/hover.js +44 -8
- package/testaro/hr.js +4 -4
- package/testaro/imageLink.js +3 -3
- package/testaro/labClash.js +3 -3
- package/testaro/legendLoc.js +3 -3
- package/testaro/lineHeight.js +3 -3
- package/testaro/linkAmb.js +25 -17
- package/testaro/linkExt.js +5 -5
- package/testaro/linkOldAtt.js +4 -3
- package/testaro/linkTo.js +4 -3
- package/testaro/linkUl.js +4 -5
- package/testaro/miniText.js +4 -3
- package/testaro/motion.js +3 -22
- package/testaro/nonTable.js +4 -5
- package/testaro/optRoleSel.js +3 -3
- package/testaro/phOnly.js +3 -3
- package/testaro/pseudoP.js +5 -5
- package/testaro/radioSet.js +4 -5
- package/testaro/role.js +4 -5
- package/testaro/secHeading.js +4 -5
- package/testaro/shoot0.js +3 -2
- package/testaro/shoot1.js +3 -2
- package/testaro/styleDiff.js +5 -12
- package/testaro/tabNav.js +30 -118
- package/testaro/targetSmall.js +30 -15
- package/testaro/textNodes.js +3 -1
- package/testaro/textSem.js +4 -5
- package/testaro/title.js +4 -2
- package/testaro/titledEl.js +3 -3
- package/testaro/zIndex.js +3 -3
- package/tests/alfa.js +28 -54
- package/tests/aslint.js +20 -53
- package/tests/axe.js +76 -13
- package/tests/ed11y.js +69 -141
- package/tests/htmlcs.js +69 -38
- package/tests/ibm.js +54 -9
- package/tests/nuVal.js +65 -12
- package/tests/nuVnu.js +76 -26
- package/tests/qualWeb.js +89 -44
- package/tests/testaro.js +288 -273
- package/tests/wave.js +142 -117
- package/tests/wax.js +61 -42
- package/procs/getLocatorData.js +0 -192
- package/procs/identify.js +0 -250
- package/procs/isInlineLink.js +0 -42
- package/procs/screenShot.js +0 -32
- package/procs/standardize.js +0 -524
- package/procs/target.js +0 -90
- package/procs/tellServer.js +0 -43
- package/scripts/dumpAlts.js +0 -28
package/tests/aslint.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
© 2025 Jonathan Robert Pool.
|
|
3
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
4
4
|
|
|
5
5
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
6
|
https://opensource.org/license/mit/ for details.
|
|
@@ -15,16 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
|
17
17
|
|
|
18
|
-
// Function to add unique identifiers to the elements in the page.
|
|
19
|
-
const {addTestaroIDs} = require('../procs/testaro');
|
|
20
|
-
// Module to simplify strings.
|
|
21
|
-
const {cap, tidy} = require('../procs/job');
|
|
22
|
-
// Module to handle files.
|
|
23
18
|
const fs = require('fs/promises');
|
|
24
|
-
|
|
25
|
-
const {getElementData} = require('../procs/getLocatorData');
|
|
26
|
-
// Function to normalize an XPath.
|
|
27
|
-
const {getNormalizedXPath} = require('../procs/identify');
|
|
19
|
+
const {getNormalizedXPath, getXPathCatalogIndex} = require('../procs/xPath');
|
|
28
20
|
|
|
29
21
|
// CONSTANTS
|
|
30
22
|
|
|
@@ -130,8 +122,6 @@ const aslintData = {
|
|
|
130
122
|
|
|
131
123
|
// Conducts and reports the ASLint tests.
|
|
132
124
|
exports.reporter = async (page, report, actIndex) => {
|
|
133
|
-
// Add unique Testaro identifiers to the elements in the page.
|
|
134
|
-
await addTestaroIDs(page);
|
|
135
125
|
// Initialize the act report.
|
|
136
126
|
let data = {};
|
|
137
127
|
const result = {
|
|
@@ -232,6 +222,7 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
232
222
|
}
|
|
233
223
|
// If standard results are to be reported:
|
|
234
224
|
if (standard) {
|
|
225
|
+
const {catalog} = report;
|
|
235
226
|
const ruleIDs = Object.keys(rules);
|
|
236
227
|
// For each violated rule:
|
|
237
228
|
for (let ruleID of ruleIDs) {
|
|
@@ -240,57 +231,33 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
240
231
|
// For each violation:
|
|
241
232
|
for (const result of results) {
|
|
242
233
|
const {message, element} = result;
|
|
234
|
+
// Get a description of the violated rule.
|
|
243
235
|
const what = message?.actual?.description ?? '';
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
236
|
+
const changer = aslintData[ruleID]?.find(
|
|
237
|
+
specs => specs.slice(0, -1).every(matcher => what.includes(matcher))
|
|
238
|
+
);
|
|
239
|
+
// If the rule ID is differentiatable:
|
|
240
|
+
if (changer) {
|
|
241
|
+
// Differentiate it.
|
|
242
|
+
ruleID = changer[changer.length - 1];
|
|
252
243
|
}
|
|
244
|
+
// Get the ordinal severity of the violation.
|
|
253
245
|
const ordinalSeverity = issueType === 'warning' ? 1 : 2;
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
let notInDOM = false;
|
|
260
|
-
let boxID = '';
|
|
261
|
-
let pathID = '';
|
|
262
|
-
if (excerpt) {
|
|
263
|
-
const elementData = await getElementData(page, excerpt);
|
|
264
|
-
({tagName, id, text, notInDOM, boxID, pathID, originalExcerpt} = elementData);
|
|
265
|
-
}
|
|
266
|
-
if (! pathID) {
|
|
267
|
-
pathID = getNormalizedXPath(xpath);
|
|
268
|
-
}
|
|
269
|
-
if (pathID && ! tagName) {
|
|
270
|
-
tagName = pathID?.replace(/[^-\w].*$/, '').toUpperCase() ?? '';
|
|
271
|
-
}
|
|
272
|
-
if (ruleID.endsWith('_svg') && ! tagName) {
|
|
273
|
-
tagName = 'SVG';
|
|
274
|
-
}
|
|
246
|
+
// Get the pathID of the element.
|
|
247
|
+
const {xpath} = element;
|
|
248
|
+
const pathID = getNormalizedXPath(xpath);
|
|
249
|
+
// Use it to get the index of the element in the catalog.
|
|
250
|
+
const catalogIndex = getXPathCatalogIndex(catalog, pathID);
|
|
275
251
|
// Add an instance to the standard result.
|
|
276
252
|
standardResult.instances.push({
|
|
277
253
|
ruleID,
|
|
278
254
|
what,
|
|
279
255
|
ordinalSeverity,
|
|
280
256
|
count: 1,
|
|
281
|
-
|
|
282
|
-
id,
|
|
283
|
-
location: {
|
|
284
|
-
notInDOM,
|
|
285
|
-
doc: 'dom',
|
|
286
|
-
type: 'xpath',
|
|
287
|
-
spec: pathID
|
|
288
|
-
},
|
|
289
|
-
excerpt: cap(tidy(originalExcerpt)),
|
|
290
|
-
text,
|
|
291
|
-
boxID,
|
|
292
|
-
pathID
|
|
257
|
+
catalogIndex
|
|
293
258
|
});
|
|
259
|
+
// Increment the standard total.
|
|
260
|
+
standardResult.totals[ordinalSeverity]++;
|
|
294
261
|
}
|
|
295
262
|
}
|
|
296
263
|
}
|
package/tests/axe.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2021–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
© 2025 Jonathan Robert Pool.
|
|
3
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
4
4
|
|
|
5
5
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
6
|
https://opensource.org/license/mit/ for details.
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
The detailLevel argument specifies how many result categories are to be included in the
|
|
18
18
|
details. 0 = none; 1 = violations; 2 = violations and incomplete; 3 = violations, incomplete,
|
|
19
19
|
and passes; 4 = violations, incomplete, passes, and inapplicable. Regardless of the value of this
|
|
20
|
-
argument, Axe-core is instructed to report all nodes with violation or incomplete results, but
|
|
21
|
-
1 node per rule found to be passed or inapplicable. Therefore, from the results of this test
|
|
22
|
-
is possible to count the rules passed and the inapplicable rules, but not the nodes for which
|
|
23
|
-
rule is passed or inapplicable. To count those nodes, one would need to revise the
|
|
24
|
-
property of the 'axeOptions' object.
|
|
20
|
+
argument, Axe-core is instructed to report all nodes with violation or incomplete results, but
|
|
21
|
+
only 1 node per rule found to be passed or inapplicable. Therefore, from the results of this test
|
|
22
|
+
it is possible to count the rules passed and the inapplicable rules, but not the nodes for which
|
|
23
|
+
each rule is passed or inapplicable. To count those nodes, one would need to revise the
|
|
24
|
+
'resultTypes' property of the 'axeOptions' object.
|
|
25
25
|
|
|
26
26
|
The report of this test shows rule totals by result category and, within the violation and
|
|
27
27
|
incomplete categories, node totals by severity. It does not show rule or node totals by test
|
|
@@ -32,17 +32,41 @@
|
|
|
32
32
|
// IMPORTS
|
|
33
33
|
|
|
34
34
|
const axePlaywright = require('axe-playwright');
|
|
35
|
+
const {getAttributeXPath, getXPathCatalogIndex} = require('../procs/xPath');
|
|
36
|
+
|
|
37
|
+
// CONSTANTS
|
|
38
|
+
|
|
35
39
|
const {injectAxe} = axePlaywright;
|
|
40
|
+
const severityWeights = {
|
|
41
|
+
minor: 0,
|
|
42
|
+
moderate: 0,
|
|
43
|
+
serious: 1,
|
|
44
|
+
critical: 1
|
|
45
|
+
};
|
|
36
46
|
|
|
37
47
|
// FUNCTIONS
|
|
38
48
|
|
|
39
49
|
// Conducts and reports the Axe tests.
|
|
40
|
-
exports.reporter = async (page, report, actIndex
|
|
50
|
+
exports.reporter = async (page, report, actIndex) => {
|
|
41
51
|
const act = report.acts[actIndex];
|
|
42
52
|
const {detailLevel, rules} = act;
|
|
43
53
|
// Initialize the act report.
|
|
44
54
|
let data = {};
|
|
45
|
-
|
|
55
|
+
const result = {
|
|
56
|
+
nativeResult: {},
|
|
57
|
+
standardResult: {}
|
|
58
|
+
};
|
|
59
|
+
const standard = report.standard !== 'no';
|
|
60
|
+
// If standard results are to be reported:
|
|
61
|
+
if (standard) {
|
|
62
|
+
// Initialize the standard result.
|
|
63
|
+
result.standardResult = {
|
|
64
|
+
prevented: false,
|
|
65
|
+
totals: [0, 0, 0, 0],
|
|
66
|
+
instances: []
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const {nativeResult, standardResult} = result;
|
|
46
70
|
// Inject axe-core into the page.
|
|
47
71
|
await injectAxe(page)
|
|
48
72
|
.catch(error => {
|
|
@@ -66,8 +90,8 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
66
90
|
const {inapplicable, passes, incomplete, violations} = axeReport;
|
|
67
91
|
// If the test succeeded:
|
|
68
92
|
if (violations) {
|
|
69
|
-
// Initialize the result.
|
|
70
|
-
|
|
93
|
+
// Initialize the native result.
|
|
94
|
+
nativeResult.totals = {
|
|
71
95
|
rulesNA: 0,
|
|
72
96
|
rulesPassed: 0,
|
|
73
97
|
rulesWarned: 0,
|
|
@@ -85,9 +109,9 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
85
109
|
critical: 0
|
|
86
110
|
}
|
|
87
111
|
};
|
|
88
|
-
|
|
89
|
-
// Populate the totals.
|
|
90
|
-
const {totals} =
|
|
112
|
+
nativeResult.details = axeReport;
|
|
113
|
+
// Populate the native-result totals.
|
|
114
|
+
const {totals} = nativeResult;
|
|
91
115
|
totals.rulesNA = inapplicable.length;
|
|
92
116
|
totals.rulesPassed = passes.length;
|
|
93
117
|
incomplete.forEach(rule => {
|
|
@@ -108,12 +132,51 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
108
132
|
irrelevants.forEach(irrelevant => {
|
|
109
133
|
delete axeReport[irrelevant];
|
|
110
134
|
});
|
|
135
|
+
// If standard results are to be reported and there are any suspicions:
|
|
136
|
+
if (standard && (totals.rulesViolated || totals.rulesWarned)) {
|
|
137
|
+
// For each certainty type:
|
|
138
|
+
['incomplete', 'violations'].forEach(certainty => {
|
|
139
|
+
// If there are any suspicions of this type:
|
|
140
|
+
if (nativeResult?.details?.[certainty]) {
|
|
141
|
+
// For each rule with any suspicions:
|
|
142
|
+
nativeResult.details[certainty].forEach(rule => {
|
|
143
|
+
// For each element suspected of violating the rule:
|
|
144
|
+
rule.nodes.forEach(node => {
|
|
145
|
+
// Get descriptions of the rule.
|
|
146
|
+
const whatSet = new Set([
|
|
147
|
+
rule.help,
|
|
148
|
+
... node.any.map(anyItem => anyItem.message),
|
|
149
|
+
... node.all.map(allItem => allItem.message)
|
|
150
|
+
]);
|
|
151
|
+
// Get the ordinal severity of the suspicion.
|
|
152
|
+
const ordinalSeverity = severityWeights[node.impact]
|
|
153
|
+
+ (certainty === 'violations' ? 2 : 0);
|
|
154
|
+
// Get the XPath of the suspected element from its data-xpath attribute.
|
|
155
|
+
const xPath = getAttributeXPath(node.html);
|
|
156
|
+
// Get the catalog index of the suspected element from its XPath.
|
|
157
|
+
const catalogIndex = getXPathCatalogIndex(report.catalog, xPath) ?? '';
|
|
158
|
+
const instance = {
|
|
159
|
+
ruleID: rule.id,
|
|
160
|
+
what: Array.from(whatSet.values()).join('; '),
|
|
161
|
+
ordinalSeverity,
|
|
162
|
+
count: 1,
|
|
163
|
+
catalogIndex
|
|
164
|
+
};
|
|
165
|
+
standardResult.instances.push(instance);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
111
171
|
}
|
|
112
172
|
// Otherwise, i.e. if the test failed:
|
|
113
173
|
else {
|
|
114
174
|
// Report this.
|
|
115
175
|
data.prevented = true;
|
|
116
176
|
data.error = 'ERROR: Act failed';
|
|
177
|
+
if (standard) {
|
|
178
|
+
standardResult.prevented = true;
|
|
179
|
+
}
|
|
117
180
|
}
|
|
118
181
|
}
|
|
119
182
|
// Return the result.
|
package/tests/ed11y.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
-
© 2025 Jonathan Robert Pool.
|
|
3
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
4
4
|
|
|
5
5
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
6
|
https://opensource.org/license/mit/ for details.
|
|
@@ -15,115 +15,59 @@
|
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
|
17
17
|
|
|
18
|
-
// Module to handle files.
|
|
19
18
|
const fs = require('fs/promises');
|
|
20
|
-
|
|
21
|
-
const {getNormalizedXPath} = require('../procs/identify');
|
|
22
|
-
// Module to get the XPath of an element.
|
|
23
|
-
const {xPath} = require('playwright-dompath');
|
|
19
|
+
const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
24
20
|
|
|
25
21
|
// FUNCTIONS
|
|
26
22
|
|
|
27
23
|
// Performs and reports the Editoria11y tests.
|
|
28
|
-
exports.reporter = async (page, report, actIndex
|
|
24
|
+
exports.reporter = async (page, report, actIndex) => {
|
|
29
25
|
// Get the nonce, if any.
|
|
30
26
|
const act = report.acts[actIndex];
|
|
31
27
|
const {jobData} = report;
|
|
32
28
|
const scriptNonce = jobData && jobData.lastScriptNonce;
|
|
29
|
+
// Initialize the act report.
|
|
30
|
+
let data = {};
|
|
31
|
+
const result = {
|
|
32
|
+
nativeResult: {},
|
|
33
|
+
standardResult: {}
|
|
34
|
+
};
|
|
35
|
+
const standard = report.standard !== 'no';
|
|
36
|
+
// If standard results are to be reported:
|
|
37
|
+
if (standard) {
|
|
38
|
+
// Initialize the standard result.
|
|
39
|
+
result.standardResult = {
|
|
40
|
+
prevented: false,
|
|
41
|
+
totals: [0, 0, 0, 0],
|
|
42
|
+
instances: []
|
|
43
|
+
};
|
|
44
|
+
}
|
|
33
45
|
// Get the tool script.
|
|
34
46
|
const script = await fs.readFile(`${__dirname}/../ed11y/editoria11y.min.js`, 'utf8');
|
|
35
|
-
// Perform the tests and
|
|
36
|
-
|
|
37
|
-
const {scriptNonce, script, rulesToTest
|
|
38
|
-
// If the report is incomplete after the time limit:
|
|
39
|
-
const timer = setTimeout(() => {
|
|
40
|
-
// Return this as the report.
|
|
41
|
-
resolve({
|
|
42
|
-
result: {
|
|
43
|
-
prevented: true,
|
|
44
|
-
error: `ed11y timed out at ${timeLimit} seconds`
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}, 1000 * timeLimit);
|
|
47
|
+
// Perform the specified tests and populate the native result.
|
|
48
|
+
result.nativeResult = await page.evaluate(args => new Promise(async resolve => {
|
|
49
|
+
const {scriptNonce, script, rulesToTest} = args;
|
|
48
50
|
// When the script has been executed, creating data in an Ed11y object:
|
|
49
|
-
document.addEventListener('ed11yResults', () => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
facts[key] = Ed11y[key];
|
|
69
|
-
}
|
|
70
|
-
catch(error) {
|
|
71
|
-
console.log(`ERROR: invalid value of ${key} property of Ed11y (${error.message})`);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
// Get data on violating text alternatives of images from Ed11y.
|
|
75
|
-
facts.imageAlts = Ed11y
|
|
76
|
-
.imageAlts
|
|
77
|
-
.filter(item => item[3] !== 'pass')
|
|
78
|
-
.map(item => item.slice(1));
|
|
79
|
-
// Delete useless facts.
|
|
80
|
-
delete facts.options.sleekTheme;
|
|
81
|
-
delete facts.options.darkTheme;
|
|
82
|
-
delete facts.options.lightTheme;
|
|
83
|
-
// Initialize the violation facts.
|
|
84
|
-
facts.violations = [];
|
|
85
|
-
// For each rule violation by an element:
|
|
86
|
-
Ed11y.results.forEach(violation => {
|
|
87
|
-
// If rules were not selected or they were and include the violated rule:
|
|
88
|
-
if (! rulesToTest || rulesToTest.includes(violation.test)) {
|
|
89
|
-
const violationFacts = {};
|
|
90
|
-
violationFacts.test = violation.test || '';
|
|
91
|
-
// If the element is in the page:
|
|
92
|
-
if (violation.content) {
|
|
93
|
-
violationFacts.content = violation.content.replace(/\s+/g, ' ');
|
|
94
|
-
}
|
|
95
|
-
const {element} = violation;
|
|
96
|
-
if (element.outerHTML) {
|
|
97
|
-
// Add the element to the report.
|
|
98
|
-
elements.push(element);
|
|
99
|
-
// Add its violation facts to the report.
|
|
100
|
-
violationFacts.tagName = element.tagName || '';
|
|
101
|
-
violationFacts.id = element.id || '';
|
|
102
|
-
violationFacts.loc = {};
|
|
103
|
-
const locRect = element.getBoundingClientRect();
|
|
104
|
-
if (locRect) {
|
|
105
|
-
['x', 'y', 'width', 'height'].forEach(dim => {
|
|
106
|
-
violationFacts.loc[dim] = Math.round(locRect[dim], 0);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
let elText = element.textContent.replace(/\s+/g, ' ').trim();
|
|
110
|
-
if (! elText) {
|
|
111
|
-
elText = element.outerHTML;
|
|
112
|
-
}
|
|
113
|
-
if (elText.length > 400) {
|
|
114
|
-
elText = `${elText.slice(0, 300)}…${elText.slice(-200)}`;
|
|
115
|
-
}
|
|
116
|
-
violationFacts.excerpt = elText.replace(/\s+/g, ' ');
|
|
117
|
-
violationFacts.boxID = ['x', 'y', 'width', 'height']
|
|
118
|
-
.map(dim => violationFacts.loc[dim])
|
|
119
|
-
.join(':');
|
|
120
|
-
facts.violations.push(violationFacts);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
51
|
+
document.addEventListener('ed11yResults', async () => {
|
|
52
|
+
let {results} = Ed11y;
|
|
53
|
+
// If rules were selected:
|
|
54
|
+
if (rulesToTest) {
|
|
55
|
+
// Remove results of other rules.
|
|
56
|
+
results = results.filter(result => rulesToTest.includes(result.test));
|
|
57
|
+
}
|
|
58
|
+
// Return the native result.
|
|
59
|
+
resolve({
|
|
60
|
+
resultCount: results.length,
|
|
61
|
+
errorCount: Ed11y.errorCount,
|
|
62
|
+
warningCount: Ed11y.warningCount,
|
|
63
|
+
results: results.map(result => ({
|
|
64
|
+
test: result.test,
|
|
65
|
+
content: result.content.replace(/\s+/g, ' ').trim(),
|
|
66
|
+
dismissalKey: result.dismissalKey,
|
|
67
|
+
html: result.element.outerHTML.slice(0, 500),
|
|
68
|
+
xPath: window.getXPath(result.element)
|
|
69
|
+
}))
|
|
123
70
|
});
|
|
124
|
-
// Return the report.
|
|
125
|
-
clearTimeout(timer);
|
|
126
|
-
resolve(report);
|
|
127
71
|
});
|
|
128
72
|
// Add the tool script to the page.
|
|
129
73
|
const toolScript = document.createElement('script');
|
|
@@ -141,55 +85,39 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
141
85
|
}
|
|
142
86
|
catch(error) {
|
|
143
87
|
resolve({
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
error: error.message
|
|
147
|
-
}
|
|
88
|
+
prevented: true,
|
|
89
|
+
error: error.message
|
|
148
90
|
});
|
|
149
91
|
};
|
|
150
92
|
}), {
|
|
151
93
|
scriptNonce,
|
|
152
94
|
script,
|
|
153
|
-
rulesToTest: act.rules
|
|
154
|
-
timeLimit
|
|
95
|
+
rulesToTest: act.rules
|
|
155
96
|
});
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
// Return the data and result, discarding the separate element data.
|
|
178
|
-
const data = {};
|
|
179
|
-
if (result.prevented) {
|
|
180
|
-
data.prevented = true;
|
|
181
|
-
}
|
|
182
|
-
return {
|
|
183
|
-
data,
|
|
184
|
-
result
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
// Otherwise, i.e. if there were no violation facts:
|
|
188
|
-
else {
|
|
189
|
-
// Return this.
|
|
190
|
-
return {
|
|
191
|
-
data: {},
|
|
192
|
-
result: {}
|
|
193
|
-
}
|
|
97
|
+
// If a standard result is to be reported:
|
|
98
|
+
if (standard) {
|
|
99
|
+
const {standardResult} = result;
|
|
100
|
+
const {warningCount, errorCount, results} = result.nativeResult;
|
|
101
|
+
// Populate the standard-result totals.
|
|
102
|
+
standardResult.totals = [warningCount, 0, errorCount, 0];
|
|
103
|
+
// For each native-result instance:
|
|
104
|
+
results.forEach(nativeInstance => {
|
|
105
|
+
// Create a standard-result instance.
|
|
106
|
+
const {test, content, dismissalKey, xPath} = nativeInstance;
|
|
107
|
+
const instance = {};
|
|
108
|
+
instance.ruleID = test;
|
|
109
|
+
instance.what = content;
|
|
110
|
+
instance.ordinalSeverity = dismissalKey ? 0 : 2;
|
|
111
|
+
instance.count = 1;
|
|
112
|
+
instance.catalogIndex = getXPathCatalogIndex(report.catalog, xPath);
|
|
113
|
+
if (! instance.catalogIndex) {
|
|
114
|
+
instance.pathID = xPath;
|
|
115
|
+
}
|
|
116
|
+
standardResult.instances.push(instance);
|
|
117
|
+
});
|
|
194
118
|
}
|
|
119
|
+
return {
|
|
120
|
+
data,
|
|
121
|
+
result
|
|
122
|
+
};
|
|
195
123
|
};
|