testaro 67.0.0 → 67.1.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/package.json +1 -1
- package/procs/getElementData.js +117 -0
- package/procs/getLocatorData.js +0 -89
- package/procs/nu.js +1 -1
- package/procs/standardize.js +1 -49
- package/run.js +6 -5
- package/tests/aslint.js +1 -1
- package/tests/axe.js +76 -12
- package/tests/htmlcs.js +1 -1
- package/tests/qualWeb.js +1 -1
- package/tests/wax.js +1 -1
package/package.json
CHANGED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2023–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
|
|
4
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
+
https://opensource.org/license/mit/ for details.
|
|
6
|
+
|
|
7
|
+
SPDX-License-Identifier: MIT
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Returns properties of an element with an excerpt when Testaro identifiers have been added.
|
|
11
|
+
exports.getElementData = async (page, excerpt) => {
|
|
12
|
+
// Initialize the properties.
|
|
13
|
+
let data = {
|
|
14
|
+
tagName: '',
|
|
15
|
+
id: '',
|
|
16
|
+
text: '',
|
|
17
|
+
notInDOM: true,
|
|
18
|
+
boxID: '',
|
|
19
|
+
pathID: '',
|
|
20
|
+
originalExcerpt: excerpt,
|
|
21
|
+
};
|
|
22
|
+
let elementProperties = {};
|
|
23
|
+
const testaroIDArray = excerpt.match(/data-testaro-id="(\d+)#([^"]*)"/);
|
|
24
|
+
// If the excerpt contains a Testaro identifier:
|
|
25
|
+
if (testaroIDArray) {
|
|
26
|
+
// Remove the identifier.
|
|
27
|
+
originalExcerpt = excerpt.replace(/ data-testaro-id="\d+#[^" ]+"?/, '');
|
|
28
|
+
elementProperties = await page.evaluate(testaroIDArray => {
|
|
29
|
+
let tagName = '';
|
|
30
|
+
let id = '';
|
|
31
|
+
const text = [];
|
|
32
|
+
let notInDOM = false;
|
|
33
|
+
let boxID = '';
|
|
34
|
+
let pathID = '';
|
|
35
|
+
const testaroID = `${testaroIDArray[1]}#${testaroIDArray[2]}`;
|
|
36
|
+
const element = document.querySelector(`[data-testaro-id="${testaroID}"]`);
|
|
37
|
+
// If any element has the identifier:
|
|
38
|
+
if (element) {
|
|
39
|
+
// Get properties of the element.
|
|
40
|
+
({tagName, id} = element);
|
|
41
|
+
const segments = element
|
|
42
|
+
.innerText
|
|
43
|
+
?.trim()
|
|
44
|
+
.split(/[\t\n]+/)
|
|
45
|
+
.filter(segment => segment.length);
|
|
46
|
+
if (segments?.length) {
|
|
47
|
+
if (segments.length > 1) {
|
|
48
|
+
text.push(segments[0], segments[segments.length - 1]);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
text.push(segments[0]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const boundingBox = element.getBoundingClientRect() ?? {};
|
|
55
|
+
const box = {};
|
|
56
|
+
if (boundingBox.x) {
|
|
57
|
+
['x', 'y', 'width', 'height'].forEach(coordinate => {
|
|
58
|
+
box[coordinate] = Math.round(boundingBox[coordinate]);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (typeof box.x === 'number') {
|
|
62
|
+
boxID = Object.values(box).join(':');
|
|
63
|
+
}
|
|
64
|
+
// Get a path ID from the identifier or, if necessary, the element.
|
|
65
|
+
pathID = testaroIDArray[2];
|
|
66
|
+
if (! pathID) {
|
|
67
|
+
pathID = window.getXPath(element);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Otherwise, i.e. if no element has the identifier:
|
|
71
|
+
else {
|
|
72
|
+
// Report this.
|
|
73
|
+
notInDOM = true;
|
|
74
|
+
}
|
|
75
|
+
// Report the properties.
|
|
76
|
+
return {
|
|
77
|
+
tagName,
|
|
78
|
+
id,
|
|
79
|
+
text,
|
|
80
|
+
notInDOM,
|
|
81
|
+
boxID,
|
|
82
|
+
pathID
|
|
83
|
+
};
|
|
84
|
+
}, testaroIDArray);
|
|
85
|
+
// Populate the data with any properties obtained from the element.
|
|
86
|
+
Object.assign(data, elementProperties);
|
|
87
|
+
}
|
|
88
|
+
// Otherwise, i.e. if the excerpt contains no Testaro identifier:
|
|
89
|
+
else {
|
|
90
|
+
// Get properties of the element that are gettable from the excerpt.
|
|
91
|
+
const tagNameArray = excerpt.match(/<([-a-z]+)/);
|
|
92
|
+
data.tagName = tagNameArray?.[1] ?? '';
|
|
93
|
+
const idArray = excerpt.match(/ id="([^"]*)"/);
|
|
94
|
+
data.id = idArray?.[1] ?? '';
|
|
95
|
+
}
|
|
96
|
+
// Return the properties.
|
|
97
|
+
return data;
|
|
98
|
+
};
|
|
99
|
+
// Returns a tag name and the value of an id attribute from a substring of HTML code.
|
|
100
|
+
exports.getIdentifiers = exports.getIdentifiers = code => {
|
|
101
|
+
// Normalize the code.
|
|
102
|
+
code = code.replace(/\s+/g, ' ').replace(/\\"/g, '"');
|
|
103
|
+
// Get the first start tag of an element, if any.
|
|
104
|
+
const startTagData = code.match(/^.*?<([a-zA-][^>]*)/);
|
|
105
|
+
// If there is any:
|
|
106
|
+
if (startTagData) {
|
|
107
|
+
// Get the tag name.
|
|
108
|
+
const tagNameArray = startTagData[1].match(/^[A-Za-z0-9]+/);
|
|
109
|
+
const tagName = tagNameArray ? tagNameArray[0].toUpperCase() : '';
|
|
110
|
+
// Get the value of the id attribute, if any.
|
|
111
|
+
const identifierData = startTagData[1].match(/ id="([^"]+)"/);
|
|
112
|
+
const id = identifierData ? identifierData[1] : '';
|
|
113
|
+
// Return the tag name and the value of the id attribute, if any.
|
|
114
|
+
return [tagName, id];
|
|
115
|
+
}
|
|
116
|
+
return ['', ''];
|
|
117
|
+
};
|
package/procs/getLocatorData.js
CHANGED
|
@@ -101,92 +101,3 @@ exports.getLocatorData = async loc => {
|
|
|
101
101
|
return null;
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
|
-
// Returns properties of an element with an excerpt when Testaro identifiers have been added.
|
|
105
|
-
exports.getElementData = async (page, excerpt) => {
|
|
106
|
-
// Initialize the properties.
|
|
107
|
-
let data = {
|
|
108
|
-
tagName: '',
|
|
109
|
-
id: '',
|
|
110
|
-
text: '',
|
|
111
|
-
notInDOM: true,
|
|
112
|
-
boxID: '',
|
|
113
|
-
pathID: '',
|
|
114
|
-
originalExcerpt: excerpt,
|
|
115
|
-
};
|
|
116
|
-
let elementProperties = {};
|
|
117
|
-
const testaroIDArray = excerpt.match(/data-testaro-id="(\d+)#([^"]*)"/);
|
|
118
|
-
// If the excerpt contains a Testaro identifier:
|
|
119
|
-
if (testaroIDArray) {
|
|
120
|
-
// Remove the identifier.
|
|
121
|
-
originalExcerpt = excerpt.replace(/ data-testaro-id="\d+#[^" ]+"?/, '');
|
|
122
|
-
elementProperties = await page.evaluate(testaroIDArray => {
|
|
123
|
-
let tagName = '';
|
|
124
|
-
let id = '';
|
|
125
|
-
const text = [];
|
|
126
|
-
let notInDOM = false;
|
|
127
|
-
let boxID = '';
|
|
128
|
-
let pathID = '';
|
|
129
|
-
const testaroID = `${testaroIDArray[1]}#${testaroIDArray[2]}`;
|
|
130
|
-
const element = document.querySelector(`[data-testaro-id="${testaroID}"]`);
|
|
131
|
-
// If any element has the identifier:
|
|
132
|
-
if (element) {
|
|
133
|
-
// Get properties of the element.
|
|
134
|
-
({tagName, id} = element);
|
|
135
|
-
const segments = element
|
|
136
|
-
.innerText
|
|
137
|
-
?.trim()
|
|
138
|
-
.split(/[\t\n]+/)
|
|
139
|
-
.filter(segment => segment.length);
|
|
140
|
-
if (segments?.length) {
|
|
141
|
-
if (segments.length > 1) {
|
|
142
|
-
text.push(segments[0], segments[segments.length - 1]);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
text.push(segments[0]);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const boundingBox = element.getBoundingClientRect() ?? {};
|
|
149
|
-
const box = {};
|
|
150
|
-
if (boundingBox.x) {
|
|
151
|
-
['x', 'y', 'width', 'height'].forEach(coordinate => {
|
|
152
|
-
box[coordinate] = Math.round(boundingBox[coordinate]);
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
if (typeof box.x === 'number') {
|
|
156
|
-
boxID = Object.values(box).join(':');
|
|
157
|
-
}
|
|
158
|
-
// Get a path ID from the identifier or, if necessary, the element.
|
|
159
|
-
pathID = testaroIDArray[2];
|
|
160
|
-
if (! pathID) {
|
|
161
|
-
pathID = window.getXPath(element);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
// Otherwise, i.e. if no element has the identifier:
|
|
165
|
-
else {
|
|
166
|
-
// Report this.
|
|
167
|
-
notInDOM = true;
|
|
168
|
-
}
|
|
169
|
-
// Report the properties.
|
|
170
|
-
return {
|
|
171
|
-
tagName,
|
|
172
|
-
id,
|
|
173
|
-
text,
|
|
174
|
-
notInDOM,
|
|
175
|
-
boxID,
|
|
176
|
-
pathID
|
|
177
|
-
};
|
|
178
|
-
}, testaroIDArray);
|
|
179
|
-
// Populate the data with any properties obtained from the element.
|
|
180
|
-
Object.assign(data, elementProperties);
|
|
181
|
-
}
|
|
182
|
-
// Otherwise, i.e. if the excerpt contains no Testaro identifier:
|
|
183
|
-
else {
|
|
184
|
-
// Get properties of the element that are gettable from the excerpt.
|
|
185
|
-
const tagNameArray = excerpt.match(/<([-a-z]+)/);
|
|
186
|
-
data.tagName = tagNameArray?.[1] ?? '';
|
|
187
|
-
const idArray = excerpt.match(/ id="([^"]*)"/);
|
|
188
|
-
data.id = idArray?.[1] ?? '';
|
|
189
|
-
}
|
|
190
|
-
// Return the properties.
|
|
191
|
-
return data;
|
|
192
|
-
};
|
package/procs/nu.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// Module to add Testaro IDs to elements.
|
|
18
18
|
const {addTestaroIDs} = require('./testaro');
|
|
19
19
|
// Module to get location data from an element.
|
|
20
|
-
const {getElementData} = require('./
|
|
20
|
+
const {getElementData} = require('./getElementData');
|
|
21
21
|
// Module to get the document source.
|
|
22
22
|
const {getSource} = require('./getSource');
|
|
23
23
|
|
package/procs/standardize.js
CHANGED
|
@@ -40,44 +40,6 @@ const getIdentifiers = exports.getIdentifiers = code => {
|
|
|
40
40
|
}
|
|
41
41
|
return ['', ''];
|
|
42
42
|
};
|
|
43
|
-
// Converts issue instances at an axe certainty level.
|
|
44
|
-
const doAxe = (result, standardResult, certainty) => {
|
|
45
|
-
if (result.details && result.details[certainty]) {
|
|
46
|
-
result.details[certainty].forEach(rule => {
|
|
47
|
-
rule.nodes.forEach(node => {
|
|
48
|
-
const whatSet = new Set([
|
|
49
|
-
rule.help,
|
|
50
|
-
... node.any.map(anyItem => anyItem.message),
|
|
51
|
-
... node.all.map(allItem => allItem.message)
|
|
52
|
-
]);
|
|
53
|
-
const severityWeights = {
|
|
54
|
-
minor: 0,
|
|
55
|
-
moderate: 0,
|
|
56
|
-
serious: 1,
|
|
57
|
-
critical: 1
|
|
58
|
-
};
|
|
59
|
-
const ordinalSeverity = severityWeights[node.impact] + (certainty === 'violations' ? 2 : 0);
|
|
60
|
-
const identifiers = getIdentifiers(node.html);
|
|
61
|
-
const instance = {
|
|
62
|
-
ruleID: rule.id,
|
|
63
|
-
what: Array.from(whatSet.values()).join('; '),
|
|
64
|
-
ordinalSeverity,
|
|
65
|
-
tagName: identifiers[0],
|
|
66
|
-
id: identifiers[1],
|
|
67
|
-
location: {
|
|
68
|
-
doc: 'dom',
|
|
69
|
-
type: 'selector',
|
|
70
|
-
spec: node.target && node.target.length ? node.target[0] : ''
|
|
71
|
-
},
|
|
72
|
-
excerpt: cap(node.html),
|
|
73
|
-
boxID: '',
|
|
74
|
-
pathID: ''
|
|
75
|
-
};
|
|
76
|
-
standardResult.instances.push(instance);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
43
|
// Converts issue instances at an htmlcs severity level.
|
|
82
44
|
const doHTMLCS = (result, standardResult, severity) => {
|
|
83
45
|
if (result[severity]) {
|
|
@@ -282,23 +244,13 @@ const convert = (toolName, data, result, standardResult) => {
|
|
|
282
244
|
standardResult.prevented = true;
|
|
283
245
|
}
|
|
284
246
|
// alfa, aslint
|
|
285
|
-
else if (['alfa', 'aslint'].includes(toolName) && result.standardResult) {
|
|
247
|
+
else if (['alfa', 'aslint', 'axe'].includes(toolName) && result.standardResult) {
|
|
286
248
|
// Move the results to standard locations.
|
|
287
249
|
Object.assign(result, result.nativeResult);
|
|
288
250
|
Object.assign(standardResult, result.standardResult);
|
|
289
251
|
delete result.nativeResult;
|
|
290
252
|
delete result.standardResult;
|
|
291
253
|
}
|
|
292
|
-
// axe
|
|
293
|
-
else if (
|
|
294
|
-
toolName === 'axe'
|
|
295
|
-
&& result
|
|
296
|
-
&& result.totals
|
|
297
|
-
&& (result.totals.rulesWarned || result.totals.rulesViolated)
|
|
298
|
-
) {
|
|
299
|
-
doAxe(result, standardResult, 'incomplete');
|
|
300
|
-
doAxe(result, standardResult, 'violations');
|
|
301
|
-
}
|
|
302
254
|
// ed11y
|
|
303
255
|
else if (
|
|
304
256
|
toolName === 'ed11y'
|
package/run.js
CHANGED
|
@@ -1794,11 +1794,11 @@ const doActs = async (report, opts = {}) => {
|
|
|
1794
1794
|
excerpt && ! ['<', '>', '=', '#'].some(markupChar => excerpt.includes(markupChar))
|
|
1795
1795
|
) {
|
|
1796
1796
|
// Add the excerpt (up to any ellipsis) to the text property.
|
|
1797
|
-
instance.text = excerpt.split(/ … | *\.\.\./)[0];
|
|
1797
|
+
instance.text = [excerpt.split(/ … | *\.\.\./)[0]];
|
|
1798
1798
|
}
|
|
1799
1799
|
// Otherwise, i.e. if it has no markup-free excerpt but has a non-empty path ID:
|
|
1800
1800
|
else if (pathID) {
|
|
1801
|
-
// Initialize a text
|
|
1801
|
+
// Initialize a text property.
|
|
1802
1802
|
let text = '';
|
|
1803
1803
|
// Get the element if it has text content.
|
|
1804
1804
|
const elementLoc = page.locator(`xpath=${pathID}`, {hasText: /.+/});
|
|
@@ -1812,17 +1812,18 @@ const doActs = async (report, opts = {}) => {
|
|
|
1812
1812
|
elementClone
|
|
1813
1813
|
.querySelectorAll('noscript')
|
|
1814
1814
|
.forEach(noscript => noscript.remove());
|
|
1815
|
-
return elementClone.
|
|
1815
|
+
return elementClone.innerText;
|
|
1816
1816
|
});
|
|
1817
1817
|
}
|
|
1818
1818
|
// Otherwise, i.e. if it contains no noscript element:
|
|
1819
1819
|
else {
|
|
1820
1820
|
// Change the text string to the text content of the element.
|
|
1821
|
-
text = await elementLoc.
|
|
1821
|
+
text = await elementLoc.innerText();
|
|
1822
1822
|
}
|
|
1823
1823
|
}
|
|
1824
1824
|
// Add the text string, truncated if necessary, to the instance.
|
|
1825
|
-
|
|
1825
|
+
const textArray = [text.trim().replace(/\s+/g, ' ').slice(0, 300)];
|
|
1826
|
+
instance.text = textArray.filter(segment => segment.length);
|
|
1826
1827
|
}
|
|
1827
1828
|
}
|
|
1828
1829
|
};
|
package/tests/aslint.js
CHANGED
|
@@ -22,7 +22,7 @@ const {cap, tidy} = require('../procs/job');
|
|
|
22
22
|
// Module to handle files.
|
|
23
23
|
const fs = require('fs/promises');
|
|
24
24
|
// Function to get location data with a Testaro identifier.
|
|
25
|
-
const {getElementData} = require('../procs/
|
|
25
|
+
const {getElementData} = require('../procs/getElementData');
|
|
26
26
|
// Function to normalize an XPath.
|
|
27
27
|
const {getNormalizedXPath} = require('../procs/identify');
|
|
28
28
|
|
package/tests/axe.js
CHANGED
|
@@ -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,43 @@
|
|
|
32
32
|
// IMPORTS
|
|
33
33
|
|
|
34
34
|
const axePlaywright = require('axe-playwright');
|
|
35
|
+
// Module to simplify strings.
|
|
36
|
+
const {cap} = require('../procs/job');
|
|
37
|
+
const {getIdentifiers} = require('../procs/getElementData');
|
|
35
38
|
const {injectAxe} = axePlaywright;
|
|
36
39
|
|
|
40
|
+
// CONSTANTS
|
|
41
|
+
|
|
42
|
+
const severityWeights = {
|
|
43
|
+
minor: 0,
|
|
44
|
+
moderate: 0,
|
|
45
|
+
serious: 1,
|
|
46
|
+
critical: 1
|
|
47
|
+
};
|
|
48
|
+
|
|
37
49
|
// FUNCTIONS
|
|
38
50
|
|
|
39
51
|
// Conducts and reports the Axe tests.
|
|
40
|
-
exports.reporter = async (page, report, actIndex
|
|
52
|
+
exports.reporter = async (page, report, actIndex) => {
|
|
41
53
|
const act = report.acts[actIndex];
|
|
42
54
|
const {detailLevel, rules} = act;
|
|
43
55
|
// Initialize the act report.
|
|
44
56
|
let data = {};
|
|
45
|
-
|
|
57
|
+
const result = {
|
|
58
|
+
nativeResult: {},
|
|
59
|
+
standardResult: {}
|
|
60
|
+
};
|
|
61
|
+
const standard = report.standard !== 'no';
|
|
62
|
+
// If standard results are to be reported:
|
|
63
|
+
if (standard) {
|
|
64
|
+
// Initialize the standard result.
|
|
65
|
+
result.standardResult = {
|
|
66
|
+
prevented: false,
|
|
67
|
+
totals: [0, 0, 0, 0],
|
|
68
|
+
instances: []
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const {nativeResult, standardResult} = result;
|
|
46
72
|
// Inject axe-core into the page.
|
|
47
73
|
await injectAxe(page)
|
|
48
74
|
.catch(error => {
|
|
@@ -66,8 +92,8 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
66
92
|
const {inapplicable, passes, incomplete, violations} = axeReport;
|
|
67
93
|
// If the test succeeded:
|
|
68
94
|
if (violations) {
|
|
69
|
-
// Initialize the result.
|
|
70
|
-
|
|
95
|
+
// Initialize the native result.
|
|
96
|
+
nativeResult.totals = {
|
|
71
97
|
rulesNA: 0,
|
|
72
98
|
rulesPassed: 0,
|
|
73
99
|
rulesWarned: 0,
|
|
@@ -85,9 +111,9 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
85
111
|
critical: 0
|
|
86
112
|
}
|
|
87
113
|
};
|
|
88
|
-
|
|
89
|
-
// Populate the totals.
|
|
90
|
-
const {totals} =
|
|
114
|
+
nativeResult.details = axeReport;
|
|
115
|
+
// Populate the native-result totals.
|
|
116
|
+
const {totals} = nativeResult;
|
|
91
117
|
totals.rulesNA = inapplicable.length;
|
|
92
118
|
totals.rulesPassed = passes.length;
|
|
93
119
|
incomplete.forEach(rule => {
|
|
@@ -108,12 +134,50 @@ exports.reporter = async (page, report, actIndex, timeLimit) => {
|
|
|
108
134
|
irrelevants.forEach(irrelevant => {
|
|
109
135
|
delete axeReport[irrelevant];
|
|
110
136
|
});
|
|
137
|
+
// If standard results are to be reported and there are any violations:
|
|
138
|
+
if (standard && (totals.rulesViolated || totals.rulesWarned)) {
|
|
139
|
+
['incomplete', 'violations'].forEach(certainty => {
|
|
140
|
+
if (nativeResult?.details?.[certainty]) {
|
|
141
|
+
nativeResult.details[certainty].forEach(rule => {
|
|
142
|
+
rule.nodes.forEach(node => {
|
|
143
|
+
const whatSet = new Set([
|
|
144
|
+
rule.help,
|
|
145
|
+
... node.any.map(anyItem => anyItem.message),
|
|
146
|
+
... node.all.map(allItem => allItem.message)
|
|
147
|
+
]);
|
|
148
|
+
const ordinalSeverity = severityWeights[node.impact]
|
|
149
|
+
+ (certainty === 'violations' ? 2 : 0);
|
|
150
|
+
const identifiers = getIdentifiers(node.html);
|
|
151
|
+
const instance = {
|
|
152
|
+
ruleID: rule.id,
|
|
153
|
+
what: Array.from(whatSet.values()).join('; '),
|
|
154
|
+
ordinalSeverity,
|
|
155
|
+
tagName: identifiers[0],
|
|
156
|
+
id: identifiers[1],
|
|
157
|
+
location: {
|
|
158
|
+
doc: 'dom',
|
|
159
|
+
type: 'selector',
|
|
160
|
+
spec: node.target && node.target.length ? node.target[0] : ''
|
|
161
|
+
},
|
|
162
|
+
excerpt: cap(node.html),
|
|
163
|
+
boxID: '',
|
|
164
|
+
pathID: ''
|
|
165
|
+
};
|
|
166
|
+
standardResult.instances.push(instance);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
111
172
|
}
|
|
112
173
|
// Otherwise, i.e. if the test failed:
|
|
113
174
|
else {
|
|
114
175
|
// Report this.
|
|
115
176
|
data.prevented = true;
|
|
116
177
|
data.error = 'ERROR: Act failed';
|
|
178
|
+
if (standard) {
|
|
179
|
+
standardResult.prevented = true;
|
|
180
|
+
}
|
|
117
181
|
}
|
|
118
182
|
}
|
|
119
183
|
// Return the result.
|
package/tests/htmlcs.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
// Module to add and use unique element IDs.
|
|
19
19
|
const {addTestaroIDs} = require('../procs/testaro');
|
|
20
20
|
// Module to get location data from an element.
|
|
21
|
-
const {getElementData} = require('../procs/
|
|
21
|
+
const {getElementData} = require('../procs/getElementData');
|
|
22
22
|
// Module to handle files.
|
|
23
23
|
const fs = require('fs/promises');
|
|
24
24
|
|
package/tests/qualWeb.js
CHANGED
|
@@ -20,7 +20,7 @@ const {ACTRules} = require('@qualweb/act-rules');
|
|
|
20
20
|
const {WCAGTechniques} = require('@qualweb/wcag-techniques');
|
|
21
21
|
const {BestPractices} = require('@qualweb/best-practices');
|
|
22
22
|
const {addTestaroIDs} = require('../procs/testaro');
|
|
23
|
-
const {getElementData} = require('../procs/
|
|
23
|
+
const {getElementData} = require('../procs/getElementData');
|
|
24
24
|
|
|
25
25
|
// CONSTANTS
|
|
26
26
|
|
package/tests/wax.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
// Function to add and use unique element IDs.
|
|
19
19
|
const {addTestaroIDs} = require('../procs/testaro');
|
|
20
20
|
// Function to get location data from an element.
|
|
21
|
-
const {getElementData} = require('../procs/
|
|
21
|
+
const {getElementData} = require('../procs/getElementData');
|
|
22
22
|
// Modules to run WAX.
|
|
23
23
|
const runWax = require('@wally-ax/wax-dev');
|
|
24
24
|
const waxDev = {runWax};
|