testaro 74.2.3 → 75.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/LICENSE +2 -0
- package/README.md +68 -61
- package/actSpecs-doc.md +25 -1
- package/actSpecs.js +6 -4
- package/package.json +2 -2
- package/procs/catalog.js +12 -1
- package/procs/dateTime.js +4 -2
- package/procs/doActs.js +15 -8
- package/procs/launch.js +0 -1
- package/procs/shoot.js +48 -43
- package/run.js +3 -1
- package/testaro/adbID.js +2 -2
- package/testaro/allCapStyle.js +2 -2
- package/testaro/allCaps.js +3 -3
- package/testaro/allHidden.js +2 -2
- package/testaro/allSlanted.js +2 -2
- package/testaro/altScheme.js +2 -2
- package/testaro/attVal.js +2 -2
- package/testaro/autocomplete.js +3 -2
- package/testaro/bulk.js +2 -2
- package/testaro/buttonMenu.js +3 -3
- package/testaro/captionLoc.js +2 -2
- package/testaro/datalistRef.js +2 -2
- package/testaro/distortion.js +2 -2
- package/testaro/docType.js +1 -1
- package/testaro/dupAtt.js +2 -2
- package/testaro/embAc.js +2 -2
- package/testaro/focAll.js +2 -2
- package/testaro/focAndOp.js +2 -2
- package/testaro/focInd.js +2 -2
- package/testaro/focVis.js +2 -2
- package/testaro/headEl.js +2 -2
- package/testaro/headingAmb.js +2 -2
- package/testaro/hovInd.js +2 -2
- package/testaro/hover.js +2 -2
- package/testaro/hr.js +2 -2
- package/testaro/imageLink.js +2 -2
- package/testaro/labClash.js +2 -2
- package/testaro/legendLoc.js +2 -2
- package/testaro/lineHeight.js +2 -2
- package/testaro/linkAmb.js +2 -2
- package/testaro/linkExt.js +2 -2
- package/testaro/linkOldAtt.js +2 -2
- package/testaro/linkTo.js +2 -2
- package/testaro/linkUl.js +2 -2
- package/testaro/miniText.js +2 -2
- package/testaro/motion.js +55 -40
- package/testaro/nonTable.js +2 -2
- package/testaro/optRoleSel.js +2 -2
- package/testaro/phOnly.js +2 -2
- package/testaro/pseudoP.js +2 -2
- package/testaro/radioSet.js +2 -2
- package/testaro/role.js +2 -2
- package/testaro/secHeading.js +2 -2
- package/testaro/styleDiff.js +2 -2
- package/testaro/tabNav.js +2 -2
- package/testaro/targetsNear.js +2 -2
- package/testaro/textNodes.js +1 -1
- package/testaro/textSem.js +2 -2
- package/testaro/titledEl.js +2 -2
- package/testaro/zIndex.js +2 -2
- package/tests/testaro.js +3 -30
- package/testaro/shoot0.js +0 -27
- package/testaro/shoot1.js +0 -33
package/procs/shoot.js
CHANGED
|
@@ -6,57 +6,35 @@
|
|
|
6
6
|
|
|
7
7
|
/*
|
|
8
8
|
shoot
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Call shape:
|
|
12
|
-
shoot(page, label, options?)
|
|
13
|
-
label: string|number used in the saved filename. Sanitized to
|
|
14
|
-
testaro-shoot-<safe>.png — characters outside [A-Za-z0-9._-]
|
|
15
|
-
collapse to '_', leading/trailing dots and underscores are
|
|
16
|
-
stripped, length is capped at 100, and an empty result becomes
|
|
17
|
-
'unnamed'.
|
|
18
|
-
options: optional object:
|
|
19
|
-
exclusion: a Playwright Locator to mask in the screenshot.
|
|
20
|
-
dir: output directory (defaults to the OS temp dir).
|
|
9
|
+
Manages the production and disposition of screenshots of a page.
|
|
21
10
|
*/
|
|
22
11
|
|
|
23
12
|
// IMPORTS
|
|
24
13
|
|
|
25
14
|
// Shared configuration for timeout multiplier.
|
|
26
15
|
const {applyMultiplier} = require('./config');
|
|
16
|
+
const {nowStamp} = require('./dateTime');
|
|
27
17
|
const fs = require('fs/promises');
|
|
28
18
|
const path = require('path');
|
|
29
19
|
const {PNG} = require('pngjs');
|
|
30
20
|
|
|
31
21
|
// FUNCTIONS
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
characters; falls back to 'unnamed' if nothing usable remains.
|
|
38
|
-
*/
|
|
39
|
-
const sanitizeLabel = (label) => {
|
|
40
|
-
const raw = String(label);
|
|
41
|
-
const cleaned = raw
|
|
42
|
-
.replace(/[^A-Za-z0-9._-]+/g, '_')
|
|
43
|
-
.replace(/^[._]+|[._]+$/g, '')
|
|
44
|
-
.slice(0, 100) || 'unnamed';
|
|
45
|
-
if (cleaned !== raw) {
|
|
46
|
-
console.log(`>> shoot: label sanitized from "${raw}" to "${cleaned}"`);
|
|
47
|
-
}
|
|
48
|
-
return cleaned;
|
|
23
|
+
// Returns a probably unique file name.
|
|
24
|
+
const randomFileName = (suffixLength = 3) => {
|
|
25
|
+
const fileName = `${nowStamp()}-${Math.random().toString(36).slice(2, 2 + suffixLength)}`;
|
|
26
|
+
return fileName;
|
|
49
27
|
};
|
|
50
|
-
|
|
51
28
|
// Creates and returns a screenshot.
|
|
52
|
-
const screenShot = async (page,
|
|
29
|
+
const screenShot = async (page, exclusionLocator = null) => {
|
|
53
30
|
const options = {
|
|
54
31
|
fullPage: true,
|
|
55
32
|
omitBackground: true,
|
|
33
|
+
scale: 'css',
|
|
56
34
|
timeout: applyMultiplier(4000)
|
|
57
35
|
};
|
|
58
|
-
if (
|
|
59
|
-
options.mask = [
|
|
36
|
+
if (exclusionLocator) {
|
|
37
|
+
options.mask = [exclusionLocator];
|
|
60
38
|
}
|
|
61
39
|
// Make and return a screenshot as a buffer.
|
|
62
40
|
return await page.screenshot(options)
|
|
@@ -65,28 +43,55 @@ const screenShot = async (page, exclusion = null) => {
|
|
|
65
43
|
return '';
|
|
66
44
|
});
|
|
67
45
|
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
46
|
+
// Creates and disposes of the PNG of a screenshot.
|
|
47
|
+
exports.shoot = async (page, report, {
|
|
48
|
+
// Playwright locator of a mask.
|
|
49
|
+
exclusionSelector = null,
|
|
50
|
+
// Color fidelity: 0 (grayscale), 2 (RGB), 4 (grayscale alpha), 6 (RGBA).
|
|
51
|
+
colorType = 0,
|
|
52
|
+
// Disposition: return, report, file.
|
|
53
|
+
action = 'return'
|
|
54
|
+
} = {}) => {
|
|
71
55
|
// Make and get a screenshot as a buffer.
|
|
72
|
-
let shot = await screenShot(page,
|
|
56
|
+
let shot = await screenShot(page, exclusionSelector ? page.locator(exclusionSelector) : null);
|
|
73
57
|
// If it succeeded:
|
|
74
58
|
if (shot.length) {
|
|
75
59
|
// Get the screenshot as an object representation of a PNG image.
|
|
76
60
|
let png = PNG.sync.read(shot);
|
|
77
61
|
shot = null;
|
|
78
|
-
|
|
62
|
+
// Convert the PNG object to a buffer, applying the specified color type.
|
|
63
|
+
const pngBuffer = PNG.sync.write(png, {colorType});
|
|
79
64
|
png = null;
|
|
80
65
|
// Force garbage collection if available and if --expose-gc was a node option.
|
|
81
66
|
if (global.gc) {
|
|
82
67
|
global.gc();
|
|
83
68
|
}
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
69
|
+
// Convert the buffer to a base64 string.
|
|
70
|
+
const base64 = pngBuffer.toString('base64');
|
|
71
|
+
// If the string is to be returned:
|
|
72
|
+
if (action === 'return') {
|
|
73
|
+
// Return it.
|
|
74
|
+
return base64;
|
|
75
|
+
}
|
|
76
|
+
// Otherwise, if it is to be appended to the report:
|
|
77
|
+
if (action === 'report') {
|
|
78
|
+
report.images ??= [];
|
|
79
|
+
// Append it to the images array in the report.
|
|
80
|
+
report.images.push(base64);
|
|
81
|
+
// Return the index of the added image in the array.
|
|
82
|
+
return report.images.length - 1;
|
|
83
|
+
}
|
|
84
|
+
// Otherwise, if it is to be saved in a file:
|
|
85
|
+
if (action === 'file') {
|
|
86
|
+
const fileName = randomFileName(4);
|
|
87
|
+
const filePath = path.join(report.jobData.tmpDir, fileName);
|
|
88
|
+
// Save it in a file.
|
|
89
|
+
await fs.writeFile(filePath, base64);
|
|
90
|
+
// Return the file name.
|
|
91
|
+
return fileName;
|
|
92
|
+
}
|
|
93
|
+
// Otherwise, i.e. if the action is invalid, return this.
|
|
94
|
+
return '';
|
|
90
95
|
}
|
|
91
96
|
// Otherwise, i.e. if it failed:
|
|
92
97
|
else {
|
package/run.js
CHANGED
|
@@ -126,7 +126,9 @@ exports.doJob = async (job, opts = {}) => {
|
|
|
126
126
|
});
|
|
127
127
|
// If the job specifies a browser ID and a target and requires standardization:
|
|
128
128
|
if (job.browserID && job.target && job.standard !== 'no') {
|
|
129
|
-
//
|
|
129
|
+
// Initialize a catalog so it precedes any page images in the report.
|
|
130
|
+
report.catalog = {};
|
|
131
|
+
// Add a catalog of the target, and a page image if required, to the report.
|
|
130
132
|
report.catalog = await getCatalog(report);
|
|
131
133
|
}
|
|
132
134
|
// Perform the acts and revise the report.
|
package/testaro/adbID.js
CHANGED
|
@@ -22,7 +22,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
22
22
|
// FUNCTIONS
|
|
23
23
|
|
|
24
24
|
// Runs the test and returns the result.
|
|
25
|
-
exports.reporter = async (page,
|
|
25
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
26
26
|
const getBadWhat = element => {
|
|
27
27
|
// Get the IDs in the aria-describedby attribute of the element.
|
|
28
28
|
const IDs = element.getAttribute('aria-describedby').trim().split(/\s+/).filter(Boolean);
|
|
@@ -57,6 +57,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
57
57
|
};
|
|
58
58
|
const whats = 'Elements have aria-describedby attributes with missing or invalid id values';
|
|
59
59
|
return await doTest(
|
|
60
|
-
page, catalog, withItems, 'adbID', 'body [aria-describedby]', whats, 3, getBadWhat.toString()
|
|
60
|
+
page, report.catalog, withItems, 'adbID', 'body [aria-describedby]', whats, 3, getBadWhat.toString()
|
|
61
61
|
);
|
|
62
62
|
};
|
package/testaro/allCapStyle.js
CHANGED
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
// Get the style declaration of the element.
|
|
26
26
|
const styleDec = window.getComputedStyle(element);
|
|
@@ -46,6 +46,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
46
46
|
const selector = 'body, body *:not(style, script, svg)';
|
|
47
47
|
const whats = 'Elements have an all-capital text transformation style';
|
|
48
48
|
return await doTest(
|
|
49
|
-
page, catalog, withItems, 'allCapStyle', selector, whats, 0, getBadWhat.toString()
|
|
49
|
+
page, report.catalog, withItems, 'allCapStyle', selector, whats, 0, getBadWhat.toString()
|
|
50
50
|
);
|
|
51
51
|
};
|
package/testaro/allCaps.js
CHANGED
|
@@ -110,12 +110,12 @@ const classifyWithAI = entries => new Promise((resolve, reject) => {
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
// Runs the test and returns the result.
|
|
113
|
-
exports.reporter = async (
|
|
113
|
+
exports.reporter = async (_0, report, _1, withItems) => {
|
|
114
114
|
const data = {};
|
|
115
115
|
const totals = [0, 0, 0, 0];
|
|
116
116
|
const standardInstances = [];
|
|
117
117
|
// Get data on the catalog entries whose text values contain 2+ consecutive capital letters.
|
|
118
|
-
const qualifying = Object.entries(catalog)
|
|
118
|
+
const qualifying = Object.entries(report.catalog)
|
|
119
119
|
.filter(([, entry]) => entry.text && /\p{Lu}{2,}/u.test(entry.text))
|
|
120
120
|
.map(([index, entry]) => ({
|
|
121
121
|
index: Number(index),
|
|
@@ -163,7 +163,7 @@ exports.reporter = async (_, catalog, withItems) => {
|
|
|
163
163
|
}
|
|
164
164
|
catch(error) {
|
|
165
165
|
data.aiError = error.message;
|
|
166
|
-
violations = getRuleBasedViolations(catalog);
|
|
166
|
+
violations = getRuleBasedViolations(report.catalog);
|
|
167
167
|
}
|
|
168
168
|
const estimatedLeftOut = data.leftOut?.estimatedViolations ?? 0;
|
|
169
169
|
// Add the estimated violation count to the totals.
|
package/testaro/allHidden.js
CHANGED
|
@@ -19,7 +19,7 @@ const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
|
19
19
|
// FUNCTIONS
|
|
20
20
|
|
|
21
21
|
// Runs the test and returns the result.
|
|
22
|
-
exports.reporter = async (page,
|
|
22
|
+
exports.reporter = async (page, report) => {
|
|
23
23
|
// Get a count of elements deemed visible by Playwright.
|
|
24
24
|
const visibleElementCount = await page.locator('body :visible').count();
|
|
25
25
|
// If no element is visible:
|
|
@@ -33,7 +33,7 @@ exports.reporter = async (page, catalog) => {
|
|
|
33
33
|
what: 'The entire page body is hidden or empty',
|
|
34
34
|
ordinalSeverity: 3,
|
|
35
35
|
count: 1,
|
|
36
|
-
catalogIndex: getXPathCatalogIndex(catalog, '/html/body')
|
|
36
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, '/html/body')
|
|
37
37
|
}]
|
|
38
38
|
};
|
|
39
39
|
}
|
package/testaro/allSlanted.js
CHANGED
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
const styleDec = window.getComputedStyle(element);
|
|
26
26
|
const {textContent} = element;
|
|
@@ -45,6 +45,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
45
45
|
const selector = 'body, body *:not(style, script, svg)';
|
|
46
46
|
const whats = 'Elements contain all-slanted text';
|
|
47
47
|
return await doTest(
|
|
48
|
-
page, catalog, withItems, 'allSlanted', selector, whats, 0, getBadWhat.toString()
|
|
48
|
+
page, report.catalog, withItems, 'allSlanted', selector, whats, 0, getBadWhat.toString()
|
|
49
49
|
);
|
|
50
50
|
};
|
package/testaro/altScheme.js
CHANGED
|
@@ -21,7 +21,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
21
21
|
// FUNCTIONS
|
|
22
22
|
|
|
23
23
|
// Runs the test and returns the result.
|
|
24
|
-
exports.reporter = async (page,
|
|
24
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
25
25
|
const getBadWhat = element => {
|
|
26
26
|
// Get the value of the alt attribute of the element.
|
|
27
27
|
const alt = (element.getAttribute('alt') || '').trim();
|
|
@@ -41,6 +41,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
41
41
|
};
|
|
42
42
|
const whats = 'img elements have alt attributes with URL or filename values';
|
|
43
43
|
return await doTest(
|
|
44
|
-
page, catalog, withItems, 'altScheme', 'body img[alt]', whats, 1, getBadWhat.toString()
|
|
44
|
+
page, report.catalog, withItems, 'altScheme', 'body img[alt]', whats, 1, getBadWhat.toString()
|
|
45
45
|
);
|
|
46
46
|
};
|
package/testaro/attVal.js
CHANGED
|
@@ -19,7 +19,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
19
19
|
// FUNCTIONS
|
|
20
20
|
|
|
21
21
|
// Runs the test and returns the result.
|
|
22
|
-
exports.reporter = async (page,
|
|
22
|
+
exports.reporter = async (page, report, _0, withItems, attributeName, areLicit, values) => {
|
|
23
23
|
const getBadWhat = element => {
|
|
24
24
|
// Get the value of the attribute.
|
|
25
25
|
const value = element.getAttribute(attributeName);
|
|
@@ -31,6 +31,6 @@ exports.reporter = async (page, catalog, withItems, attributeName, areLicit, val
|
|
|
31
31
|
};
|
|
32
32
|
const whats = `Elements have attribute ${attributeName} with illicit values`;
|
|
33
33
|
return await doTest(
|
|
34
|
-
page, catalog, withItems, 'attVal', `body [${attributeName}]`, whats, 2, getBadWhat.toString()
|
|
34
|
+
page, report.catalog, withItems, 'attVal', `body [${attributeName}]`, whats, 2, getBadWhat.toString()
|
|
35
35
|
);
|
|
36
36
|
};
|
package/testaro/autocomplete.js
CHANGED
|
@@ -22,7 +22,8 @@ const {doTest} = require('../procs/testaro');
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
23
|
exports.reporter = async (
|
|
24
24
|
page,
|
|
25
|
-
|
|
25
|
+
report,
|
|
26
|
+
_0,
|
|
26
27
|
withItems,
|
|
27
28
|
labels = {
|
|
28
29
|
name: ['your name', 'full name', 'first and last name'],
|
|
@@ -85,5 +86,5 @@ exports.reporter = async (
|
|
|
85
86
|
[0, 1, 2, 3].forEach(index => {
|
|
86
87
|
getBadWhatString = getBadWhatString.replace(placeHolders[index], replacers[index]);
|
|
87
88
|
});
|
|
88
|
-
return doTest(page, catalog, withItems, 'autocomplete', selector, whats, 2, getBadWhatString);
|
|
89
|
+
return doTest(page, report.catalog, withItems, 'autocomplete', selector, whats, 2, getBadWhatString);
|
|
89
90
|
};
|
package/testaro/bulk.js
CHANGED
|
@@ -20,7 +20,7 @@ const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report) => {
|
|
24
24
|
// Get a count of elements deemed visible by Playwright.
|
|
25
25
|
const visibleElementCount = await page.locator('body :visible').count();
|
|
26
26
|
// Convert the count to a severity level, treating up to 400 as non-reportable.
|
|
@@ -38,7 +38,7 @@ exports.reporter = async (page, catalog) => {
|
|
|
38
38
|
what: `Page contains ${visibleElementCount} visible elements`,
|
|
39
39
|
ordinalSeverity: severity,
|
|
40
40
|
count: 1,
|
|
41
|
-
catalogIndex: getXPathCatalogIndex(catalog, '/html')
|
|
41
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, '/html')
|
|
42
42
|
}]
|
|
43
43
|
};
|
|
44
44
|
}
|
package/testaro/buttonMenu.js
CHANGED
|
@@ -180,7 +180,7 @@ const focusSuccess = async (miLocsDir, priorIndex, key, isPseudo) => {
|
|
|
180
180
|
return result;
|
|
181
181
|
};
|
|
182
182
|
// Performs the test and reports the result.
|
|
183
|
-
exports.reporter = async (page,
|
|
183
|
+
exports.reporter = async (page, report, _0, withItems, trialKeySpecs = []) => {
|
|
184
184
|
// Initialize the result.
|
|
185
185
|
const data = {};
|
|
186
186
|
const totals = [0, 0, 0, 0];
|
|
@@ -304,7 +304,7 @@ exports.reporter = async (page, catalog, withItems, trialKeySpecs = []) => {
|
|
|
304
304
|
what: `Menu responds nonstandardly to the ${key} key`,
|
|
305
305
|
ordinalSeverity: 2,
|
|
306
306
|
count: 1,
|
|
307
|
-
catalogIndex: getXPathCatalogIndex(catalog, mbXPath)
|
|
307
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, mbXPath)
|
|
308
308
|
});
|
|
309
309
|
}
|
|
310
310
|
// Stop testing the menu button.
|
|
@@ -339,7 +339,7 @@ exports.reporter = async (page, catalog, withItems, trialKeySpecs = []) => {
|
|
|
339
339
|
what: 'Menu button does not control exactly 1 menu',
|
|
340
340
|
ordinalSeverity: 2,
|
|
341
341
|
count: 1,
|
|
342
|
-
catalogIndex: getXPathCatalogIndex(catalog, mbXPath)
|
|
342
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, mbXPath)
|
|
343
343
|
});
|
|
344
344
|
}
|
|
345
345
|
}
|
package/testaro/captionLoc.js
CHANGED
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
|
|
21
21
|
// FUNCTIONS
|
|
22
22
|
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
const parent = element.parentElement;
|
|
26
26
|
// If the element is not the first child of a table element:
|
|
@@ -31,6 +31,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
31
31
|
};
|
|
32
32
|
const whats = 'caption elements are not the first children of table elements';
|
|
33
33
|
return await doTest(
|
|
34
|
-
page, catalog, withItems, 'captionLoc', 'body caption', whats, 3, getBadWhat.toString()
|
|
34
|
+
page, report.catalog, withItems, 'captionLoc', 'body caption', whats, 3, getBadWhat.toString()
|
|
35
35
|
);
|
|
36
36
|
};
|
package/testaro/datalistRef.js
CHANGED
|
@@ -19,7 +19,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
19
19
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
|
-
exports.reporter = async (page,
|
|
22
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
23
23
|
const getBadWhat = element => {
|
|
24
24
|
// Get the ID of the datalist element referenced by the list attribute of the element.
|
|
25
25
|
const listID = element.getAttribute('list');
|
|
@@ -46,6 +46,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
46
46
|
};
|
|
47
47
|
const whats = 'list attributes of input elements are empty or IDs of no or non-datalist elements';
|
|
48
48
|
return await doTest(
|
|
49
|
-
page, catalog, withItems, 'datalistRef', 'body input[list]', whats, 3, getBadWhat.toString()
|
|
49
|
+
page, report.catalog, withItems, 'datalistRef', 'body input[list]', whats, 3, getBadWhat.toString()
|
|
50
50
|
);
|
|
51
51
|
};
|
package/testaro/distortion.js
CHANGED
|
@@ -21,7 +21,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
21
21
|
// FUNCTIONS
|
|
22
22
|
|
|
23
23
|
// Runs the test and returns the result.
|
|
24
|
-
exports.reporter = async (page,
|
|
24
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
25
25
|
const getBadWhat = element => {
|
|
26
26
|
const styleDec = window.getComputedStyle(element);
|
|
27
27
|
const {transform} = styleDec;
|
|
@@ -38,6 +38,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
38
38
|
};
|
|
39
39
|
const whats = 'Elements distort their texts';
|
|
40
40
|
return await doTest(
|
|
41
|
-
page, catalog, withItems, 'distortion', 'body, body *', whats, 0, getBadWhat.toString()
|
|
41
|
+
page, report.catalog, withItems, 'distortion', 'body, body *', whats, 0, getBadWhat.toString()
|
|
42
42
|
);
|
|
43
43
|
};
|
package/testaro/docType.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
// Runs the test and returns the result.
|
|
18
|
-
exports.reporter = async (page,
|
|
18
|
+
exports.reporter = async (page, report) => {
|
|
19
19
|
// Returns whether the page declares a document type.
|
|
20
20
|
const docHasType = await page.evaluate(() => {
|
|
21
21
|
const docType = document.doctype;
|
package/testaro/dupAtt.js
CHANGED
|
@@ -20,7 +20,7 @@ const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
|
20
20
|
// ########## FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
// Initialize the data and standard result.
|
|
25
25
|
const data = {total: 0};
|
|
26
26
|
if (withItems) {
|
|
@@ -96,7 +96,7 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
96
96
|
what: `${item.tagName} element has 2 attributes named ${item.duplicatedAttribute}`,
|
|
97
97
|
ordinalSeverity: 2,
|
|
98
98
|
count: 1,
|
|
99
|
-
catalogIndex: getXPathCatalogIndex(catalog, '/html/body')
|
|
99
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, '/html/body')
|
|
100
100
|
});
|
|
101
101
|
});
|
|
102
102
|
}
|
package/testaro/embAc.js
CHANGED
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
// Get whether the embedding element is a link or a button.
|
|
26
26
|
const embedder = element.parentElement.closest('a, button');
|
|
@@ -32,5 +32,5 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
32
32
|
.map(tag => `a ${tag}, button ${tag}`)
|
|
33
33
|
.join(', ');
|
|
34
34
|
const whats = 'interactive elements are embedded in links or buttons';
|
|
35
|
-
return await doTest(page, catalog, withItems, 'embAc', selector, whats, 2, getBadWhat.toString());
|
|
35
|
+
return await doTest(page, report.catalog, withItems, 'embAc', selector, whats, 2, getBadWhat.toString());
|
|
36
36
|
};
|
package/testaro/focAll.js
CHANGED
|
@@ -19,7 +19,7 @@ const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
|
19
19
|
// FUNCTIONS
|
|
20
20
|
|
|
21
21
|
// Runs the test and returns the result.
|
|
22
|
-
exports.reporter = async (page,
|
|
22
|
+
exports.reporter = async (page, report) => {
|
|
23
23
|
// Get locators of visible elements.
|
|
24
24
|
const locAll = await page.locator('body *:visible');
|
|
25
25
|
// Get the count of focusable elements.
|
|
@@ -74,7 +74,7 @@ exports.reporter = async (page, catalog) => {
|
|
|
74
74
|
what: 'Some focusable elements are not Tab-focusable or vice versa',
|
|
75
75
|
ordinalSeverity: 2,
|
|
76
76
|
count,
|
|
77
|
-
catalogIndex: getXPathCatalogIndex(catalog, '/html/body')
|
|
77
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, '/html/body')
|
|
78
78
|
}] : []
|
|
79
79
|
};
|
|
80
80
|
};
|
package/testaro/focAndOp.js
CHANGED
|
@@ -22,7 +22,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
22
22
|
// FUNCTIONS
|
|
23
23
|
|
|
24
24
|
// Runs the test and returns the result.
|
|
25
|
-
exports.reporter = async (page,
|
|
25
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
26
26
|
const getBadWhat = element => {
|
|
27
27
|
// Get whether the element is visible.
|
|
28
28
|
const isVisible = element.checkVisibility({
|
|
@@ -118,6 +118,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
118
118
|
};
|
|
119
119
|
const whats = 'Elements are Tab-focusable but not operable or vice versa';
|
|
120
120
|
return await doTest(
|
|
121
|
-
page, catalog, withItems, 'focAndOp', 'body, body *', whats, 2, getBadWhat.toString()
|
|
121
|
+
page, report.catalog, withItems, 'focAndOp', 'body, body *', whats, 2, getBadWhat.toString()
|
|
122
122
|
);
|
|
123
123
|
};
|
package/testaro/focInd.js
CHANGED
|
@@ -27,7 +27,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
27
27
|
// FUNCTIONS
|
|
28
28
|
|
|
29
29
|
// Runs the test and returns the result.
|
|
30
|
-
exports.reporter = async (page,
|
|
30
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
31
31
|
const getBadWhat = element => {
|
|
32
32
|
// Get whether the element is visible.
|
|
33
33
|
const isVisible = element.checkVisibility({
|
|
@@ -86,6 +86,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
86
86
|
};
|
|
87
87
|
const whats = 'Elements fail to have standard focus indicators';
|
|
88
88
|
return await doTest(
|
|
89
|
-
page, catalog, withItems, 'focInd', 'body, body *', whats, 1, getBadWhat.toString()
|
|
89
|
+
page, report.catalog, withItems, 'focInd', 'body, body *', whats, 1, getBadWhat.toString()
|
|
90
90
|
);
|
|
91
91
|
};
|
package/testaro/focVis.js
CHANGED
|
@@ -21,7 +21,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
21
21
|
// FUNCTIONS
|
|
22
22
|
|
|
23
23
|
// Runs the test and returns the result.
|
|
24
|
-
exports.reporter = async (page,
|
|
24
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
25
25
|
const getBadWhat = element => {
|
|
26
26
|
const isVisible = element.checkVisibility({
|
|
27
27
|
contentVisibilityAuto: true,
|
|
@@ -42,6 +42,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
42
42
|
};
|
|
43
43
|
const whats = 'Visible links are above or to the left of the display';
|
|
44
44
|
return await doTest(
|
|
45
|
-
page, catalog, withItems, 'focVis', 'body a', whats, 2, getBadWhat.toString()
|
|
45
|
+
page, report.catalog, withItems, 'focVis', 'body a', whats, 2, getBadWhat.toString()
|
|
46
46
|
);
|
|
47
47
|
};
|
package/testaro/headEl.js
CHANGED
|
@@ -20,7 +20,7 @@ const {getXPathCatalogIndex} = require('../procs/xPath');
|
|
|
20
20
|
// ########## FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report) => {
|
|
24
24
|
// Initialize the data and standard result.
|
|
25
25
|
const data = {
|
|
26
26
|
total: 0,
|
|
@@ -65,7 +65,7 @@ exports.reporter = async (page, catalog) => {
|
|
|
65
65
|
what: `Invalid elements within the head: ${data.badTagNames.join(', ')}`,
|
|
66
66
|
ordinalSeverity: 2,
|
|
67
67
|
count: data.total,
|
|
68
|
-
catalogIndex: getXPathCatalogIndex(catalog, '/html/head')
|
|
68
|
+
catalogIndex: getXPathCatalogIndex(report.catalog, '/html/head')
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
totals = [0, 0, data.total, 0];
|
package/testaro/headingAmb.js
CHANGED
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
// ########## FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
const {tagName} = element;
|
|
26
26
|
const level = tagName[1];
|
|
@@ -70,6 +70,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
70
70
|
const selector = headingLevels.map(level => `body h${level}`).join(', ');
|
|
71
71
|
const whats = 'Adjacent sibling same-level headings have the same text';
|
|
72
72
|
return await doTest(
|
|
73
|
-
page, catalog, withItems, 'headingAmb', selector, whats, 1, getBadWhat.toString()
|
|
73
|
+
page, report.catalog, withItems, 'headingAmb', selector, whats, 1, getBadWhat.toString()
|
|
74
74
|
);
|
|
75
75
|
};
|
package/testaro/hovInd.js
CHANGED
|
@@ -19,7 +19,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
19
19
|
// FUNCTIONS
|
|
20
20
|
|
|
21
21
|
// Runs the test and returns the result.
|
|
22
|
-
exports.reporter = async (page,
|
|
22
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
23
23
|
const getBadWhat = element => {
|
|
24
24
|
const violationTypes = [];
|
|
25
25
|
const isVisible = element.checkVisibility({
|
|
@@ -140,5 +140,5 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
140
140
|
};
|
|
141
141
|
const selector = 'body a, body button, body input, body [onmouseenter], body [onmouseover]';
|
|
142
142
|
const whats = 'elements have confusing hover indicators';
|
|
143
|
-
return await doTest(page, catalog, withItems, 'hovInd', selector, whats, 1, getBadWhat.toString());
|
|
143
|
+
return await doTest(page, report.catalog, withItems, 'hovInd', selector, whats, 1, getBadWhat.toString());
|
|
144
144
|
};
|
package/testaro/hover.js
CHANGED
|
@@ -64,7 +64,7 @@ const getVisibleCountChange = async (
|
|
|
64
64
|
const getViolationDescription = (change, elapsedTime) =>
|
|
65
65
|
`Hovering over the element changes the related visible element count by ${change} in ${elapsedTime}ms`;
|
|
66
66
|
// Runs the test and returns the result.
|
|
67
|
-
exports.reporter = async (page,
|
|
67
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
68
68
|
// Initialize the locators and result.
|
|
69
69
|
const candidateLocs = await page.locator([
|
|
70
70
|
'[aria-controls]:visible',
|
|
@@ -141,5 +141,5 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
141
141
|
}
|
|
142
142
|
// Get and return a result.
|
|
143
143
|
const whats = 'Hovering over elements changes the number of related visible elements';
|
|
144
|
-
return await getBasicResult(catalog, withItems, 'hover', 0, whats, data, violations);
|
|
144
|
+
return await getBasicResult(report.catalog, withItems, 'hover', 0, whats, data, violations);
|
|
145
145
|
};
|
package/testaro/hr.js
CHANGED
|
@@ -20,13 +20,13 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
// Return a violation description.
|
|
26
26
|
return `hr element is used for vertical segmentation`;
|
|
27
27
|
}
|
|
28
28
|
const whats = 'HR elements are used for vertical segmentation';
|
|
29
29
|
return await doTest(
|
|
30
|
-
page, catalog, withItems, 'hr', 'body hr', whats, 0, getBadWhat.toString()
|
|
30
|
+
page, report.catalog, withItems, 'hr', 'body hr', whats, 0, getBadWhat.toString()
|
|
31
31
|
);
|
|
32
32
|
};
|
package/testaro/imageLink.js
CHANGED
|
@@ -22,7 +22,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
22
22
|
// FUNCTIONS
|
|
23
23
|
|
|
24
24
|
// Runs the test and returns the result.
|
|
25
|
-
exports.reporter = async (page,
|
|
25
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
26
26
|
const getBadWhat = element => {
|
|
27
27
|
const href = element.getAttribute('href') || '';
|
|
28
28
|
// If the destination of the element is an image file:
|
|
@@ -33,6 +33,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
33
33
|
};
|
|
34
34
|
const whats = 'Links have image files as their destinations';
|
|
35
35
|
return await doTest(
|
|
36
|
-
page, catalog, withItems, 'imageLink', 'body a[href]', whats, 0, getBadWhat.toString()
|
|
36
|
+
page, report.catalog, withItems, 'imageLink', 'body a[href]', whats, 0, getBadWhat.toString()
|
|
37
37
|
);
|
|
38
38
|
};
|
package/testaro/labClash.js
CHANGED
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
// FUNCTIONS
|
|
21
21
|
|
|
22
22
|
// Runs the test and returns the result.
|
|
23
|
-
exports.reporter = async (page,
|
|
23
|
+
exports.reporter = async (page, report, _, withItems) => {
|
|
24
24
|
const getBadWhat = element => {
|
|
25
25
|
// Get the label types of the element.
|
|
26
26
|
const labelTypes = [];
|
|
@@ -44,6 +44,6 @@ exports.reporter = async (page, catalog, withItems) => {
|
|
|
44
44
|
const selector = 'body button, body input:not([type=hidden]), body select, body textarea';
|
|
45
45
|
const whats = 'Elements have inconsistent label types';
|
|
46
46
|
return await doTest(
|
|
47
|
-
page, catalog, withItems, 'labClash', selector, whats, 2, getBadWhat.toString()
|
|
47
|
+
page, report.catalog, withItems, 'labClash', selector, whats, 2, getBadWhat.toString()
|
|
48
48
|
);
|
|
49
49
|
};
|