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/testaro/captionLoc.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
3
|
© 2025 Juan S. Casado.
|
|
4
|
-
© 2025 Jonathan Robert Pool.
|
|
4
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
5
5
|
|
|
6
6
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
7
7
|
https://opensource.org/license/mit/ for details.
|
|
@@ -20,7 +20,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
|
|
21
21
|
// FUNCTIONS
|
|
22
22
|
|
|
23
|
-
exports.reporter = async (page, withItems) => {
|
|
23
|
+
exports.reporter = async (page, catalog, 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, withItems) => {
|
|
|
31
31
|
};
|
|
32
32
|
const whats = 'caption elements are not the first children of table elements';
|
|
33
33
|
return await doTest(
|
|
34
|
-
page, withItems, 'captionLoc', 'caption', whats, 3,
|
|
34
|
+
page, catalog, withItems, 'captionLoc', 'caption', whats, 3, getBadWhat.toString()
|
|
35
35
|
);
|
|
36
36
|
};
|
package/testaro/datalistRef.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
3
|
© 2025 Juan S. Casado.
|
|
4
|
-
© 2025 Jonathan Robert Pool.
|
|
4
|
+
© 2025–2026 Jonathan Robert Pool.
|
|
5
5
|
|
|
6
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
7
|
-
https://opensource.org/license/mit/ for details.
|
|
6
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
8
7
|
|
|
9
8
|
SPDX-License-Identifier: MIT
|
|
10
9
|
*/
|
|
@@ -20,7 +19,7 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
19
|
|
|
21
20
|
// FUNCTIONS
|
|
22
21
|
|
|
23
|
-
exports.reporter = async (page, withItems) => {
|
|
22
|
+
exports.reporter = async (page, catalog, withItems) => {
|
|
24
23
|
const getBadWhat = element => {
|
|
25
24
|
// Get the ID of the datalist element referenced by the list attribute of the element.
|
|
26
25
|
const listID = element.getAttribute('list');
|
|
@@ -47,6 +46,6 @@ exports.reporter = async (page, withItems) => {
|
|
|
47
46
|
};
|
|
48
47
|
const whats = 'list attributes of input elements are empty or IDs of no or non-datalist elements';
|
|
49
48
|
return await doTest(
|
|
50
|
-
page, withItems, 'datalistRef', 'input[list]', whats, 3,
|
|
49
|
+
page, catalog, withItems, 'datalistRef', 'input[list]', whats, 3, getBadWhat.toString()
|
|
51
50
|
);
|
|
52
51
|
};
|
package/testaro/distortion.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023 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.
|
|
@@ -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, withItems) => {
|
|
24
|
+
exports.reporter = async (page, catalog, 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, withItems) => {
|
|
|
38
38
|
};
|
|
39
39
|
const whats = 'Elements distort their texts';
|
|
40
40
|
return await doTest(
|
|
41
|
-
page, withItems, 'distortion', 'body *', whats, 0,
|
|
41
|
+
page, catalog, withItems, 'distortion', 'body *', whats, 0, getBadWhat.toString()
|
|
42
42
|
);
|
|
43
43
|
};
|
package/testaro/docType.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2022–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
5
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
6
|
https://opensource.org/license/mit/ for details.
|
|
@@ -12,13 +13,16 @@
|
|
|
12
13
|
Derived from the bbc-a11y allDocumentsMustHaveAW3cRecommendedDoctype test.
|
|
13
14
|
This test reports a failure to equip the page document with a W3C-recommended HTML doctype.
|
|
14
15
|
*/
|
|
16
|
+
|
|
17
|
+
// Runs the test and returns the result.
|
|
15
18
|
exports.reporter = async page => {
|
|
16
|
-
//
|
|
19
|
+
// Returns whether the page declares a document type.
|
|
17
20
|
const docHasType = await page.evaluate(() => {
|
|
18
21
|
const docType = document.doctype;
|
|
19
22
|
const docHasType = !! docType && docType.name && docType.name.toLowerCase() === 'html';
|
|
20
23
|
return docHasType;
|
|
21
24
|
});
|
|
25
|
+
// Return data, totals, and, if no document type is declared, a standard instance.
|
|
22
26
|
return {
|
|
23
27
|
data: {docHasType},
|
|
24
28
|
totals: [0, 0, 0, docHasType ? 0 : 1],
|
|
@@ -26,14 +30,7 @@ exports.reporter = async page => {
|
|
|
26
30
|
ruleID: 'docType',
|
|
27
31
|
what: 'Document has no standard HTML doctype preamble',
|
|
28
32
|
ordinalSeverity: 3,
|
|
29
|
-
|
|
30
|
-
id: '',
|
|
31
|
-
location: {
|
|
32
|
-
doc: 'dom',
|
|
33
|
-
type: 'selector',
|
|
34
|
-
spec: 'html'
|
|
35
|
-
},
|
|
36
|
-
excerpt: ''
|
|
33
|
+
count: 1
|
|
37
34
|
}]
|
|
38
35
|
};
|
|
39
36
|
};
|
package/testaro/dupAtt.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
6
6
|
|
|
7
7
|
SPDX-License-Identifier: MIT
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
dupAtt.js
|
|
12
|
-
This test reports duplicate attributes
|
|
12
|
+
This test reports duplicate attributes. The test is performed on the source of the document, because browsers delete additional same-name attributes in the DOM.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// ########## IMPORTS
|
|
@@ -19,8 +19,8 @@ const {getSource} = require('../procs/getSource');
|
|
|
19
19
|
|
|
20
20
|
// ########## FUNCTIONS
|
|
21
21
|
|
|
22
|
-
//
|
|
23
|
-
exports.reporter = async (page, withItems) => {
|
|
22
|
+
// Runs the test and returns the result.
|
|
23
|
+
exports.reporter = async (page, _, withItems) => {
|
|
24
24
|
// Initialize the data and standard result.
|
|
25
25
|
const data = {total: 0};
|
|
26
26
|
if (withItems) {
|
|
@@ -88,38 +88,25 @@ exports.reporter = async (page, withItems) => {
|
|
|
88
88
|
});
|
|
89
89
|
// If itemization is required and there are any instances:
|
|
90
90
|
if (data.items) {
|
|
91
|
-
// For each
|
|
91
|
+
// For each violator:
|
|
92
92
|
data.items.forEach(item => {
|
|
93
|
-
// Add
|
|
93
|
+
// Add an instance to the standard instances.
|
|
94
94
|
standardInstances.push({
|
|
95
95
|
ruleID: 'dupAtt',
|
|
96
|
-
what:
|
|
96
|
+
what: `${item.tagName} element has 2 attributes named ${item.duplicatedAttribute}`,
|
|
97
97
|
ordinalSeverity: 2,
|
|
98
|
-
|
|
99
|
-
id: item.id,
|
|
100
|
-
location: {
|
|
101
|
-
doc: item.id ? 'source' : '',
|
|
102
|
-
type: item.id ? 'selector' : '',
|
|
103
|
-
spec: item.id ? `#${item.id}` : ''
|
|
104
|
-
},
|
|
105
|
-
excerpt: item.duplicatedAttribute
|
|
98
|
+
count: 1
|
|
106
99
|
});
|
|
107
100
|
});
|
|
108
101
|
}
|
|
109
|
-
// Otherwise, if there are any
|
|
102
|
+
// Otherwise, if itemization is not required and there are any violations:
|
|
110
103
|
else if (data.total) {
|
|
111
|
-
// Add a summary instance.
|
|
104
|
+
// Add a summary instance to the standard instances.
|
|
112
105
|
standardInstances.push({
|
|
113
106
|
ruleID: 'dupAtt',
|
|
114
107
|
what: 'In some elements 2 attributes have the same name',
|
|
115
108
|
ordinalSeverity: 2,
|
|
116
|
-
count: data.total
|
|
117
|
-
location: {
|
|
118
|
-
doc: '',
|
|
119
|
-
type: '',
|
|
120
|
-
spec: ''
|
|
121
|
-
},
|
|
122
|
-
excerpt: ''
|
|
109
|
+
count: data.total
|
|
123
110
|
});
|
|
124
111
|
}
|
|
125
112
|
totals = [0, 0, data.total, 0];
|
package/testaro/elements.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
6
6
|
|
|
7
7
|
SPDX-License-Identifier: MIT
|
|
8
8
|
*/
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
2. Data on each specified element also include the text content of the parent element.
|
|
16
16
|
3. Data on each specified element also include data on its sibling nodes.
|
|
17
17
|
*/
|
|
18
|
+
|
|
18
19
|
exports.reporter = async (
|
|
19
|
-
page,
|
|
20
|
+
page, _, _, detailLevel = 0, tagName = null, onlyVisible = false, attribute
|
|
20
21
|
) => {
|
|
21
22
|
// Determine a selector of the specified elements, including any descendants of open shadow roots.
|
|
22
23
|
let selector = `body ${tagName ? tagName.toLowerCase() : '*'}`;
|
package/testaro/embAc.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2021–2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
5
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
6
|
https://opensource.org/license/mit/ for details.
|
|
@@ -18,7 +19,8 @@ const {doTest} = require('../procs/testaro');
|
|
|
18
19
|
|
|
19
20
|
// FUNCTIONS
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
// Runs the test and returns the result.
|
|
23
|
+
exports.reporter = async (page, catalog, withItems) => {
|
|
22
24
|
const getBadWhat = element => {
|
|
23
25
|
// Get whether the embedding element is a link or a button.
|
|
24
26
|
const embedder = element.parentElement.closest('a, button');
|
|
@@ -30,5 +32,5 @@ exports.reporter = async (page, withItems) => {
|
|
|
30
32
|
.map(tag => `a ${tag}, button ${tag}`)
|
|
31
33
|
.join(', ');
|
|
32
34
|
const whats = 'interactive elements are embedded in links or buttons';
|
|
33
|
-
return await doTest(page, withItems, 'embAc', selector, whats, 2,
|
|
35
|
+
return await doTest(page, catalog, withItems, 'embAc', selector, whats, 2, getBadWhat.toString());
|
|
34
36
|
};
|
package/testaro/focAll.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2021–2023 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
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
7
6
|
|
|
8
7
|
SPDX-License-Identifier: MIT
|
|
9
8
|
*/
|
|
@@ -12,6 +11,8 @@
|
|
|
12
11
|
focAll
|
|
13
12
|
This test reports discrepancies between focusable and Tab-focused element counts. The test first counts all the visible focusable (i.e. with tabIndex 0) elements (except counting each group of radio buttons as only one focusable element). Then it repeatedly presses the Tab (or Option-Tab in webkit) key until it has reached all the elements it can and counts those elements. If the two counts differ, navigation can be made more difficult. The cause may be surprising changes in content during navigation with the Tab key, or inability to reach every focusable element (or widget, such as one radio button or tab in each group) merely by pressing the Tab key.
|
|
14
13
|
*/
|
|
14
|
+
|
|
15
|
+
// Runs the test and returns the result.
|
|
15
16
|
exports.reporter = async page => {
|
|
16
17
|
// Get locators of visible elements.
|
|
17
18
|
const locAll = await page.locator('body *:visible');
|
|
@@ -32,7 +33,7 @@ exports.reporter = async page => {
|
|
|
32
33
|
*/
|
|
33
34
|
let tabFocused = 0;
|
|
34
35
|
let refocused = 0;
|
|
35
|
-
const keyName = page.
|
|
36
|
+
const keyName = page.context().browser()?.browserType().name() === 'webkit' ? 'Alt+Tab' : 'Tab';
|
|
36
37
|
while (refocused < 100 && tabFocused < 2000) {
|
|
37
38
|
await page.keyboard.press(keyName);
|
|
38
39
|
const isNewFocus = await page.evaluate(() => {
|
|
@@ -65,16 +66,8 @@ exports.reporter = async page => {
|
|
|
65
66
|
standardInstances: count ? [{
|
|
66
67
|
ruleID: 'focAll',
|
|
67
68
|
what: 'Some focusable elements are not Tab-focusable or vice versa',
|
|
68
|
-
count,
|
|
69
69
|
ordinalSeverity: 2,
|
|
70
|
-
|
|
71
|
-
id: '',
|
|
72
|
-
location: {
|
|
73
|
-
doc: '',
|
|
74
|
-
type: '',
|
|
75
|
-
spec: ''
|
|
76
|
-
},
|
|
77
|
-
excerpt: ''
|
|
70
|
+
count
|
|
78
71
|
}] : []
|
|
79
72
|
};
|
|
80
73
|
};
|
package/testaro/focAndOp.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.
|
|
@@ -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, withItems) => {
|
|
25
|
+
exports.reporter = async (page, catalog, withItems) => {
|
|
26
26
|
const getBadWhat = element => {
|
|
27
27
|
// Get whether the element is visible.
|
|
28
28
|
const isVisible = element.checkVisibility({
|
|
@@ -116,6 +116,6 @@ exports.reporter = async (page, withItems) => {
|
|
|
116
116
|
};
|
|
117
117
|
const whats = 'Elements are Tab-focusable but not operable or vice versa';
|
|
118
118
|
return await doTest(
|
|
119
|
-
page, withItems, 'focAndOp', 'body *', whats, 2,
|
|
119
|
+
page, catalog, withItems, 'focAndOp', 'body *', whats, 2, getBadWhat.toString()
|
|
120
120
|
);
|
|
121
121
|
};
|
package/testaro/focInd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2021–2023 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.
|
|
@@ -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, withItems) => {
|
|
30
|
+
exports.reporter = async (page, catalog, 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, withItems) => {
|
|
|
86
86
|
};
|
|
87
87
|
const whats = 'Elements fail to have standard focus indicators';
|
|
88
88
|
return await doTest(
|
|
89
|
-
page, withItems, 'focInd', 'body *', whats, 1,
|
|
89
|
+
page, catalog, withItems, 'focInd', 'body *', whats, 1, getBadWhat.toString()
|
|
90
90
|
);
|
|
91
91
|
};
|
package/testaro/focVis.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2022–2025 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.
|
|
@@ -20,7 +20,8 @@ const {doTest} = require('../procs/testaro');
|
|
|
20
20
|
|
|
21
21
|
// FUNCTIONS
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
// Runs the test and returns the result.
|
|
24
|
+
exports.reporter = async (page, catalog, withItems) => {
|
|
24
25
|
const getBadWhat = element => {
|
|
25
26
|
const isVisible = element.checkVisibility({
|
|
26
27
|
contentVisibilityAuto: true,
|
|
@@ -41,6 +42,6 @@ exports.reporter = async (page, withItems) => {
|
|
|
41
42
|
};
|
|
42
43
|
const whats = 'Visible links are above or to the left of the display';
|
|
43
44
|
return await doTest(
|
|
44
|
-
page, withItems, 'focVis', 'a', whats, 2,
|
|
45
|
+
page, catalog, withItems, 'focVis', 'a', whats, 2, getBadWhat.toString()
|
|
45
46
|
);
|
|
46
47
|
};
|
package/testaro/headEl.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
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
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
7
6
|
|
|
8
7
|
SPDX-License-Identifier: MIT
|
|
9
8
|
*/
|
|
@@ -16,7 +15,7 @@
|
|
|
16
15
|
|
|
17
16
|
// ########## FUNCTIONS
|
|
18
17
|
|
|
19
|
-
//
|
|
18
|
+
// Runs the test and returns the result.
|
|
20
19
|
exports.reporter = async page => {
|
|
21
20
|
// Initialize the data and standard result.
|
|
22
21
|
const data = {
|
|
@@ -56,18 +55,12 @@ exports.reporter = async page => {
|
|
|
56
55
|
});
|
|
57
56
|
// If there are any instances:
|
|
58
57
|
if (data.total) {
|
|
59
|
-
// Add a summary instance.
|
|
58
|
+
// Add a summary instance to the standard instances.
|
|
60
59
|
standardInstances.push({
|
|
61
60
|
ruleID: 'headEl',
|
|
62
61
|
what: `Invalid elements within the head: ${data.badTagNames.join(', ')}`,
|
|
63
62
|
ordinalSeverity: 2,
|
|
64
|
-
count: data.total
|
|
65
|
-
location: {
|
|
66
|
-
doc: '',
|
|
67
|
-
type: '',
|
|
68
|
-
spec: ''
|
|
69
|
-
},
|
|
70
|
-
excerpt: ''
|
|
63
|
+
count: data.total
|
|
71
64
|
});
|
|
72
65
|
}
|
|
73
66
|
totals = [0, 0, data.total, 0];
|
package/testaro/headingAmb.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2026 Jonathan Robert Pool.
|
|
3
4
|
|
|
4
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
5
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
6
6
|
|
|
7
7
|
SPDX-License-Identifier: MIT
|
|
8
8
|
*/
|
|
@@ -13,101 +13,58 @@
|
|
|
13
13
|
This test reports adjacent headings with the same levels and text contents.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
//
|
|
16
|
+
// IMPORTS
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
18
|
+
const {doTest} = require('../procs/testaro');
|
|
20
19
|
|
|
21
20
|
// ########## FUNCTIONS
|
|
22
21
|
|
|
23
|
-
//
|
|
24
|
-
exports.reporter = async (page, withItems) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// Get the non-inferior ones among them.
|
|
43
|
-
const nonInferiors = priorHeadings.filter(priorHeading => priorHeading.tagName[1] <= level);
|
|
44
|
-
// If there are any:
|
|
45
|
-
const nonInferiorCount = nonInferiors.length;
|
|
46
|
-
if (nonInferiorCount) {
|
|
47
|
-
// Get the last of them.
|
|
48
|
-
const prior = nonInferiors[nonInferiorCount - 1];
|
|
49
|
-
// If they have the same level and text:
|
|
50
|
-
if (['tagName', 'textContent'].every(property => prior[property] === heading[property])) {
|
|
51
|
-
// Add the index of the later heading to the index of violating headings.
|
|
52
|
-
badIndexes.push(index);
|
|
22
|
+
// Runs the test and returns the result.
|
|
23
|
+
exports.reporter = async (page, catalog, withItems) => {
|
|
24
|
+
const getBadWhat = element => {
|
|
25
|
+
const {tagName} = element;
|
|
26
|
+
const level = tagName[1];
|
|
27
|
+
const textContent = element.textContent.trim().replace(/\s+/g, ' ');
|
|
28
|
+
const headingTagNames = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'];
|
|
29
|
+
// Initialize the inspected element as the previous element sibling of the element.
|
|
30
|
+
let inspectedElement = element.previousElementSibling;
|
|
31
|
+
// As long as the inspected element exists:
|
|
32
|
+
while (inspectedElement) {
|
|
33
|
+
const inspectedTagName = inspectedElement.tagName;
|
|
34
|
+
// If it is a heading:
|
|
35
|
+
if (headingTagNames.includes(inspectedTagName)) {
|
|
36
|
+
// If it is inferior to the element:
|
|
37
|
+
if (inspectedTagName[1] > level) {
|
|
38
|
+
// Stop inspecting it and start inspecting its previous sibling.
|
|
39
|
+
inspectedElement = inspectedElement.previousElementSibling;
|
|
40
|
+
continue;
|
|
53
41
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// If itemization is required:
|
|
63
|
-
if (withItems) {
|
|
64
|
-
// For each instance:
|
|
65
|
-
for (const index of ambIndexes) {
|
|
66
|
-
// If it exists:
|
|
67
|
-
const loc = locsAll[index];
|
|
68
|
-
if (loc) {
|
|
69
|
-
// Get data on the element.
|
|
70
|
-
const elData = await getLocatorData(loc);
|
|
71
|
-
// Add a standard instance.
|
|
72
|
-
standardInstances.push({
|
|
73
|
-
ruleID: 'headingAmb',
|
|
74
|
-
what: 'Heading has the same text as the prior same-level sibling heading',
|
|
75
|
-
ordinalSeverity: 1,
|
|
76
|
-
tagName: elData.tagName,
|
|
77
|
-
id: elData.id,
|
|
78
|
-
location: elData.location,
|
|
79
|
-
excerpt: elData.excerpt
|
|
80
|
-
});
|
|
42
|
+
// Otherwise, if its level is the same as that of the element:
|
|
43
|
+
else if (inspectedTagName === tagName) {
|
|
44
|
+
const inspectedTextContent = inspectedElement.textContent.trim().replace(/\s+/g, ' ');
|
|
45
|
+
// If they have identical text contents:
|
|
46
|
+
if (inspectedTextContent === textContent) {
|
|
47
|
+
// Return a violation description.
|
|
48
|
+
return 'Heading has the same text as the prior same-level sibling heading';
|
|
49
|
+
}
|
|
81
50
|
}
|
|
82
|
-
// Otherwise, i.e. if it
|
|
51
|
+
// Otherwise, i.e. if it is superior to the element:
|
|
83
52
|
else {
|
|
84
|
-
//
|
|
85
|
-
|
|
53
|
+
// Stop inspecting.
|
|
54
|
+
break;
|
|
86
55
|
}
|
|
87
56
|
}
|
|
57
|
+
// Otherwise, i.e. if it is not a heading:
|
|
58
|
+
else {
|
|
59
|
+
// Inspect its previous sibling.
|
|
60
|
+
inspectedElement = inspectedElement.previousElementSibling;
|
|
61
|
+
}
|
|
88
62
|
}
|
|
89
|
-
// Otherwise, i.e. if itemization is not required:
|
|
90
|
-
else {
|
|
91
|
-
// Add a summary instance.
|
|
92
|
-
standardInstances.push({
|
|
93
|
-
ruleID: 'headingAmb',
|
|
94
|
-
what: 'Adjacent sibling same-level headings have the same text',
|
|
95
|
-
ordinalSeverity: 1,
|
|
96
|
-
count: totals[1],
|
|
97
|
-
tagName: '',
|
|
98
|
-
id: '',
|
|
99
|
-
location: {
|
|
100
|
-
doc: '',
|
|
101
|
-
type: '',
|
|
102
|
-
spec: ''
|
|
103
|
-
},
|
|
104
|
-
excerpt: ''
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return {
|
|
109
|
-
data,
|
|
110
|
-
totals,
|
|
111
|
-
standardInstances
|
|
112
63
|
};
|
|
64
|
+
const headingLevels = [1, 2, 3, 4, 5, 6];
|
|
65
|
+
const selector = headingLevels.map(level => `body h${level}`).join(', ');
|
|
66
|
+
const whats = 'Adjacent sibling same-level headings have the same text';
|
|
67
|
+
return await doTest(
|
|
68
|
+
page, catalog, withItems, 'headingAmb', selector, whats, 1, getBadWhat.toString()
|
|
69
|
+
);
|
|
113
70
|
};
|
package/testaro/hovInd.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
© 2023–2025 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
|
-
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
-
https://opensource.org/license/mit/ for details.
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or https://opensource.org/license/mit/ for details.
|
|
7
6
|
|
|
8
7
|
SPDX-License-Identifier: MIT
|
|
9
8
|
*/
|
|
@@ -19,7 +18,8 @@ const {doTest} = require('../procs/testaro');
|
|
|
19
18
|
|
|
20
19
|
// FUNCTIONS
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
// Runs the test and returns the result.
|
|
22
|
+
exports.reporter = async (page, _, withItems) => {
|
|
23
23
|
const getBadWhat = element => {
|
|
24
24
|
const violationTypes = [];
|
|
25
25
|
const isVisible = element.checkVisibility({
|
|
@@ -140,5 +140,5 @@ exports.reporter = async (page, withItems) => {
|
|
|
140
140
|
};
|
|
141
141
|
const selector = 'a, button, input, [onmouseenter], [onmouseover]';
|
|
142
142
|
const whats = 'elements have confusing hover indicators';
|
|
143
|
-
return await doTest(page, withItems, 'hovInd', selector, whats, 1,
|
|
143
|
+
return await doTest(page, withItems, 'hovInd', selector, whats, 1, getBadWhat.toString());
|
|
144
144
|
};
|