testaro 64.6.0 → 64.7.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/standardize.js +16 -9
- package/procs/testaro.js +3 -3
- package/run.js +7 -8
- package/tests/htmlcs.js +3 -3
- package/tests/wave.js +34 -9
- package/tests/wax.js +13 -3
package/package.json
CHANGED
package/procs/standardize.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
Converts test results to the standard format.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
//
|
|
16
|
+
// FUNCTIONS
|
|
17
17
|
|
|
18
18
|
// Limits the length of and unilinearizes a string.
|
|
19
19
|
const cap = rawString => {
|
|
@@ -327,11 +327,11 @@ const doWAVE = (result, standardResult, categoryName) => {
|
|
|
327
327
|
const {items} = category;
|
|
328
328
|
if (items) {
|
|
329
329
|
Object.keys(items).forEach(ruleID => {
|
|
330
|
-
items[ruleID].selectors.forEach(
|
|
330
|
+
items[ruleID].selectors.forEach(violationFacts => {
|
|
331
331
|
let tagName = '';
|
|
332
332
|
let id = '';
|
|
333
|
-
if (typeof
|
|
334
|
-
const finalTerm =
|
|
333
|
+
if (typeof violationFacts[0] === 'string') {
|
|
334
|
+
const finalTerm = violationFacts[0].replace(/^.+\s/, '');
|
|
335
335
|
if (finalTerm.includes('#')) {
|
|
336
336
|
const finalArray = finalTerm.split('#');
|
|
337
337
|
tagName = finalArray[0].replace(/:.*/, '');
|
|
@@ -350,9 +350,9 @@ const doWAVE = (result, standardResult, categoryName) => {
|
|
|
350
350
|
location: {
|
|
351
351
|
doc: 'dom',
|
|
352
352
|
type: 'selector',
|
|
353
|
-
spec:
|
|
353
|
+
spec: violationFacts[0]
|
|
354
354
|
},
|
|
355
|
-
excerpt:
|
|
355
|
+
excerpt: violationFacts[1]
|
|
356
356
|
};
|
|
357
357
|
standardResult.instances.push(instance);
|
|
358
358
|
});
|
|
@@ -667,13 +667,18 @@ const convert = (toolName, data, result, standardResult) => {
|
|
|
667
667
|
result.violations.forEach(violation => {
|
|
668
668
|
// Get its standard instance properties.
|
|
669
669
|
const element = violation.element.replace(/\s+/g, ' ');
|
|
670
|
-
const {
|
|
670
|
+
const {boxID, description, message, notInDOM, pathID, severity} = violation;
|
|
671
671
|
const ordinalSeverity = ['Minor', 'Moderate', '', 'Severe'].indexOf(severity);
|
|
672
672
|
const tagNameCandidate = element.replace(/^<| .*$/g, '');
|
|
673
673
|
const tagName = /^[a-zA-Z0-9]+$/.test(tagNameCandidate) ? tagNameCandidate.toUpperCase() : '';
|
|
674
674
|
let id = '';
|
|
675
675
|
const location = {};
|
|
676
|
-
if (
|
|
676
|
+
if (notInDOM) {
|
|
677
|
+
location.doc = 'notInDOM';
|
|
678
|
+
location.type = '';
|
|
679
|
+
location.spec = '';
|
|
680
|
+
}
|
|
681
|
+
else if (tagName) {
|
|
677
682
|
const idTerm = element
|
|
678
683
|
.replace(/>.*$/, '')
|
|
679
684
|
.split(' ')
|
|
@@ -696,7 +701,9 @@ const convert = (toolName, data, result, standardResult) => {
|
|
|
696
701
|
tagName,
|
|
697
702
|
id,
|
|
698
703
|
location,
|
|
699
|
-
excerpt: element
|
|
704
|
+
excerpt: element,
|
|
705
|
+
boxID,
|
|
706
|
+
pathID
|
|
700
707
|
};
|
|
701
708
|
// Add the instance to the standard result.
|
|
702
709
|
standardResult.instances.push(instance);
|
package/procs/testaro.js
CHANGED
|
@@ -235,9 +235,9 @@ exports.addTestaroIDs = async page => {
|
|
|
235
235
|
});
|
|
236
236
|
};
|
|
237
237
|
// Returns location data from the extract of a standard instance.
|
|
238
|
-
exports.getLocationData = async (page,
|
|
239
|
-
const testaroIDArray =
|
|
240
|
-
// If the
|
|
238
|
+
exports.getLocationData = async (page, excerpt) => {
|
|
239
|
+
const testaroIDArray = excerpt.match(/data-testaro-id="(\d+)#"/);
|
|
240
|
+
// If the excerpt contains a Testaro identifier:
|
|
241
241
|
if (testaroIDArray) {
|
|
242
242
|
const testaroID = testaroIDArray[1];
|
|
243
243
|
// Return location data for the element.
|
package/run.js
CHANGED
|
@@ -413,11 +413,10 @@ const launch = exports.launch = async (
|
|
|
413
413
|
get: () => ['en-US', 'en']
|
|
414
414
|
});
|
|
415
415
|
});
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (isTestaroTest || isHTMLCSTest || isNuTest) {
|
|
416
|
+
const needsXPath = act.type === 'test'
|
|
417
|
+
&& ['testaro', 'htmlcs', 'nuVal', 'nuVnu', 'wax'].includes(act.which);
|
|
418
|
+
// If the launch is for a test act that requires XPaths:
|
|
419
|
+
if (needsXPath) {
|
|
421
420
|
// Add a script to the page to add a window method to get the XPath of an element.
|
|
422
421
|
await page.addInitScript(() => {
|
|
423
422
|
window.getXPath = element => {
|
|
@@ -466,7 +465,7 @@ const launch = exports.launch = async (
|
|
|
466
465
|
});
|
|
467
466
|
}
|
|
468
467
|
// If the launch is for a testaro test act:
|
|
469
|
-
if (
|
|
468
|
+
if (act.type === 'test' && act.which === 'testaro') {
|
|
470
469
|
// Add a script to the page to compute the accessible name of an element.
|
|
471
470
|
await page.addInitScript({path: require.resolve('./dist/nameComputation.js')});
|
|
472
471
|
// Add a script to the page to:
|
|
@@ -478,7 +477,7 @@ const launch = exports.launch = async (
|
|
|
478
477
|
&& typeof window.computeAccessibleName === 'function';
|
|
479
478
|
return nameIsComputable ? window.computeAccessibleName(element) : '';
|
|
480
479
|
};
|
|
481
|
-
// Add a window method to return
|
|
480
|
+
// Add a window method to return a standard instance.
|
|
482
481
|
window.getInstance = (
|
|
483
482
|
element, ruleID, what, count = 1, ordinalSeverity, summaryTagName = ''
|
|
484
483
|
) => {
|
|
@@ -494,7 +493,7 @@ const launch = exports.launch = async (
|
|
|
494
493
|
const rawExcerpt = (element.textContent.trim() || element.outerHTML.trim())
|
|
495
494
|
.replace(/\s+/g, ' ');
|
|
496
495
|
const excerpt = rawExcerpt.slice(0, 200);
|
|
497
|
-
// Return an itemized instance.
|
|
496
|
+
// Return an itemized standard instance.
|
|
498
497
|
return {
|
|
499
498
|
ruleID,
|
|
500
499
|
what,
|
package/tests/htmlcs.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
// IMPORTS
|
|
16
16
|
|
|
17
|
-
// Module to add
|
|
17
|
+
// Module to add and use unique element IDs.
|
|
18
18
|
const {addTestaroIDs, getLocationData} = require('../procs/testaro');
|
|
19
19
|
// Module to handle files.
|
|
20
20
|
const fs = require('fs/promises');
|
|
@@ -81,7 +81,7 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
81
81
|
result.Error = {};
|
|
82
82
|
result.Warning = {};
|
|
83
83
|
// For each violation:
|
|
84
|
-
|
|
84
|
+
for (const string of messageStrings) {
|
|
85
85
|
// Split its message into severity class, rule ID, tagname, ID, rule description, and excerpt.
|
|
86
86
|
const parts = string.split(/\|/, 6);
|
|
87
87
|
const partCount = parts.length;
|
|
@@ -110,7 +110,7 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
110
110
|
pathID
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
}
|
|
113
|
+
}
|
|
114
114
|
}
|
|
115
115
|
return {
|
|
116
116
|
data,
|
package/tests/wave.js
CHANGED
|
@@ -96,30 +96,55 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
96
96
|
// Add WCAG information from the WAVE documentation.
|
|
97
97
|
const waveDocJSON = await fs.readFile('procs/wavedoc.json', 'utf8');
|
|
98
98
|
const waveDoc = JSON.parse(waveDocJSON);
|
|
99
|
-
|
|
99
|
+
// For each rule category:
|
|
100
|
+
for (const categoryName of Object.keys(categories)) {
|
|
100
101
|
const category = categories[categoryName];
|
|
101
|
-
// If any violations were reported:
|
|
102
|
+
// If any violations were reported in the category:
|
|
102
103
|
if (
|
|
103
104
|
category
|
|
104
105
|
&& category.items
|
|
105
106
|
&& Object.keys(category.items).length
|
|
106
107
|
) {
|
|
107
108
|
const {items} = category;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
// For each rule violated (named item by WAVE):
|
|
110
|
+
for (const ruleName of Object.keys(items)) {
|
|
111
|
+
const ruleDoc = waveDoc.find((rule => rule.name === ruleName));
|
|
112
|
+
const {guidelines} = ruleDoc;
|
|
113
|
+
const rule = items[ruleName];
|
|
114
|
+
// Add WCAG information to the rule data.
|
|
115
|
+
rule.wcag = guidelines;
|
|
116
|
+
// For each violation:
|
|
117
|
+
for (const index in rule.selectors) {
|
|
118
|
+
const selector = rule.selectors[index];
|
|
119
|
+
// Get an excerpt of the element.
|
|
120
|
+
const excerpt = await page.evaluate(selector => {
|
|
121
|
+
const element = document.querySelector(selector);
|
|
122
|
+
// If the selector matches an element:
|
|
123
|
+
if (element) {
|
|
124
|
+
// Get an excerpt of the element.
|
|
125
|
+
const rawExcerpt = element.textContent.trim() || element.outerHTML.trim();
|
|
126
|
+
const normalizedExcerpt = rawExcerpt.replace(/\s+/g, ' ');
|
|
127
|
+
return normalizedExcerpt.slice(0, 300);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
}, selector);
|
|
133
|
+
// Convert the violation selector to a selector-excerpt pair.
|
|
134
|
+
rule.selectors[index] = [selector, excerpt];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
113
137
|
}
|
|
114
|
-
}
|
|
138
|
+
};
|
|
115
139
|
// Add important data to the result.
|
|
116
140
|
if (statistics) {
|
|
117
141
|
data.pageTitle = statistics.pagetitle || '';
|
|
118
142
|
data.pageURL = statistics.pageurl || '';
|
|
119
|
-
data.
|
|
143
|
+
data.elapsedSeconds = statistics.time || null;
|
|
120
144
|
data.creditsRemaining = statistics.creditsremaining || null;
|
|
121
145
|
data.allItemCount = statistics.allitemcount || null;
|
|
122
146
|
data.totalElements = statistics.totalelements || null;
|
|
147
|
+
data.waveURL = statistics.waveurl || '';
|
|
123
148
|
}
|
|
124
149
|
// Return the result.
|
|
125
150
|
resolve(actResult);
|
package/tests/wax.js
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
|
17
17
|
|
|
18
|
-
//
|
|
18
|
+
// Module to add and use unique element IDs.
|
|
19
|
+
const {addTestaroIDs, getLocationData} = require('../procs/testaro');
|
|
20
|
+
// Modules to run WAX.
|
|
19
21
|
const runWax = require('@wally-ax/wax-dev');
|
|
20
22
|
const waxDev = {runWax};
|
|
21
23
|
|
|
@@ -26,15 +28,17 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
26
28
|
// Initialize the act report.
|
|
27
29
|
let data = {};
|
|
28
30
|
let result = {};
|
|
29
|
-
// Run WAX.
|
|
30
31
|
const act = report.acts[actIndex];
|
|
31
32
|
const rules = act.rules || [];
|
|
33
|
+
// Annotate all elements on the page with unique identifiers.
|
|
34
|
+
await addTestaroIDs(page);
|
|
32
35
|
const pageCode = await page.content();
|
|
33
36
|
const waxOptions = {
|
|
34
37
|
rules,
|
|
35
38
|
apiKey: process.env.WAX_KEY || ''
|
|
36
39
|
};
|
|
37
40
|
try {
|
|
41
|
+
// Run WAX.
|
|
38
42
|
const actReport = await waxDev.runWax(pageCode, waxOptions);
|
|
39
43
|
// If WAX failed with a string report:
|
|
40
44
|
if (typeof actReport === 'string') {
|
|
@@ -54,6 +58,12 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
54
58
|
}
|
|
55
59
|
// Otherwise, i.e. if it is a successful report:
|
|
56
60
|
else {
|
|
61
|
+
// Add location data to its excerpts.
|
|
62
|
+
for (const violation of actReport) {
|
|
63
|
+
const {element} = violation;
|
|
64
|
+
const elementLocation = await getLocationData(page, element);
|
|
65
|
+
Object.assign(violation, elementLocation);
|
|
66
|
+
}
|
|
57
67
|
// Populate the act report.
|
|
58
68
|
result = {
|
|
59
69
|
violations: actReport
|
|
@@ -81,7 +91,6 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
81
91
|
data.error = 'wax failure';
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
|
-
// Return the results.
|
|
85
94
|
try {
|
|
86
95
|
JSON.stringify(data);
|
|
87
96
|
}
|
|
@@ -92,6 +101,7 @@ exports.reporter = async (page, report, actIndex) => {
|
|
|
92
101
|
error: message
|
|
93
102
|
};
|
|
94
103
|
}
|
|
104
|
+
// Return the results.
|
|
95
105
|
return {
|
|
96
106
|
data,
|
|
97
107
|
result
|