testaro 60.16.2 → 60.18.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/testaro.js +3 -118
- package/testaro/allCaps.js +32 -36
- package/testaro/allSlanted.js +16 -21
- package/testaro/distortion.js +20 -22
- package/testaro/focAndOp.js +7 -8
- package/testaro/hover.js +1 -1
- package/testaro/hr.js +32 -0
- package/testaro/imageLink.js +19 -16
- package/testaro/legendLoc.js +18 -23
- package/testaro/linkExt.js +31 -0
- package/testaro/linkOldAtt.js +43 -0
- package/testaro/linkTo.js +37 -0
- package/testaro/linkUl.js +24 -30
- package/testaro/nonTable.js +39 -55
- package/testaro/optRoleSel.js +18 -15
- package/testaro/pseudoP.js +54 -0
- package/testaro/role.js +1 -1
- package/testaro/textSem.js +1 -1
- package/testaro/titledEl.js +34 -0
- package/tests/testaro.js +124 -175
- package/data/template.js +0 -39
- package/testaro/hr.json +0 -10
- package/testaro/linkExt.json +0 -10
- package/testaro/linkOldAtt.json +0 -10
- package/testaro/linkTitle.js +0 -46
- package/testaro/linkTo.json +0 -10
- package/testaro/pseudoP.json +0 -10
- package/testaro/titledEl.json +0 -10
package/testaro/linkUl.js
CHANGED
|
@@ -10,43 +10,37 @@
|
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
12
|
linkUl
|
|
13
|
-
This test reports failures to underline inline links. Underlining and color are the traditional style properties that identify links. Lists of links containing only links
|
|
13
|
+
This test reports failures to underline inline links. Underlining and color are the traditional style properties that identify links. Lists of links containing only links may be recognizable without underlines, but other links are difficult or impossible to distinguish visually from surrounding text if not underlined. Underlining adjacent links only on hover provides an indicator valuable only to mouse users, and even they must traverse the text with a mouse merely to discover which passages are links.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
//
|
|
16
|
+
// IMPORTS
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
const {simplify} = require('../procs/testaro');
|
|
20
|
-
// Module to classify links.
|
|
21
|
-
const {isInlineLink} = require('../procs/isInlineLink');
|
|
18
|
+
const {doTest} = require('../procs/testaro');
|
|
22
19
|
|
|
23
|
-
//
|
|
20
|
+
// FUNCTIONS
|
|
24
21
|
|
|
25
22
|
// Runs the test and returns the result.
|
|
26
23
|
exports.reporter = async (page, withItems) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
const getBadWhat = element => {
|
|
25
|
+
const liAncestor = element.closest('li');
|
|
26
|
+
// If the element is not the only link inside a list item:
|
|
27
|
+
if (! (liAncestor && liAncestor.getElementsByTagName('a').length === 1)) {
|
|
28
|
+
const styleDec = window.getComputedStyle(element);
|
|
29
|
+
const {textDecoration} = styleDec;
|
|
30
|
+
// If the element text is not underlined:
|
|
31
|
+
if (! textDecoration.includes('underline')) {
|
|
32
|
+
const styleDec = window.getComputedStyle(element);
|
|
33
|
+
const {display} = styleDec;
|
|
34
|
+
// If the element has does not have a block display style:
|
|
35
|
+
if (display !== 'block') {
|
|
36
|
+
// Return a violation description.
|
|
37
|
+
return 'Element is not a list item but is not underlined';
|
|
38
|
+
}
|
|
41
39
|
}
|
|
42
|
-
}
|
|
43
|
-
complaints: {
|
|
44
|
-
instance: 'Link is inline but has no underline',
|
|
45
|
-
summary: 'Inline links are missing underlines'
|
|
46
|
-
},
|
|
47
|
-
ordinalSeverity: 1,
|
|
48
|
-
summaryTagName: 'A'
|
|
40
|
+
}
|
|
49
41
|
};
|
|
50
|
-
|
|
51
|
-
return await
|
|
42
|
+
const whats = 'Links that are not list items are not underlined';
|
|
43
|
+
return await doTest(
|
|
44
|
+
page, withItems, 'linkUl', 'a', whats, 1, 'A', getBadWhat.toString()
|
|
45
|
+
);
|
|
52
46
|
};
|
package/testaro/nonTable.js
CHANGED
|
@@ -14,65 +14,49 @@
|
|
|
14
14
|
This test reports tables used for layout.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
//
|
|
17
|
+
// IMPORTS
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
const {simplify} = require('../procs/testaro');
|
|
19
|
+
const {doTest} = require('../procs/testaro');
|
|
21
20
|
|
|
22
|
-
//
|
|
21
|
+
// FUNCTIONS
|
|
23
22
|
|
|
24
23
|
// Runs the test and returns the result.
|
|
25
24
|
exports.reporter = async (page, withItems) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|| el.querySelector('col, colgroup, tfoot, thead, th')
|
|
59
|
-
) {
|
|
60
|
-
// Return validity.
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
// Otherwise:
|
|
64
|
-
else {
|
|
65
|
-
// Return misuse.
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
}),
|
|
69
|
-
complaints: {
|
|
70
|
-
instance: 'Table is misused to arrange content',
|
|
71
|
-
summary: 'Tables are misused to arrange content'
|
|
72
|
-
},
|
|
73
|
-
ordinalSeverity: 2,
|
|
74
|
-
summaryTagName: 'TABLE'
|
|
25
|
+
const getBadWhat = element => {
|
|
26
|
+
// If the element contains another table:
|
|
27
|
+
if (element.querySelector('table')) {
|
|
28
|
+
// Return a violation description.
|
|
29
|
+
return 'Element contains another table';
|
|
30
|
+
}
|
|
31
|
+
const rowCount = element.querySelectorAll('tr').length;
|
|
32
|
+
const columnCount = Math.max(
|
|
33
|
+
... Array
|
|
34
|
+
.from(element.querySelectorAll('tr'))
|
|
35
|
+
.map(row => Array.from(row.querySelectorAll('th, td')).length)
|
|
36
|
+
);
|
|
37
|
+
// Otherwise, if it has only 1 column or 1 row:
|
|
38
|
+
if (rowCount === 1 || columnCount === 1) {
|
|
39
|
+
// Return a violation description.
|
|
40
|
+
return 'Element has only one row or one column';
|
|
41
|
+
}
|
|
42
|
+
// Otherwise, if it contains an object or player:
|
|
43
|
+
if (element.querySelector('object, embed, applet, audio, video')) {
|
|
44
|
+
// Return a violation description.
|
|
45
|
+
return 'Element contains an object or player';
|
|
46
|
+
}
|
|
47
|
+
const role = element.getAttribute('role');
|
|
48
|
+
// Otherwise, if it has no table-compatible explicit role or descendant element:
|
|
49
|
+
if (! (
|
|
50
|
+
['grid', 'treegrid'].includes(role)
|
|
51
|
+
|| element.caption
|
|
52
|
+
|| element.querySelector('col, colgroup, tfoot, th, thead')
|
|
53
|
+
)) {
|
|
54
|
+
// Return a violation description.
|
|
55
|
+
return 'Element has no table-compatible explicit role or descendant element';
|
|
56
|
+
}
|
|
75
57
|
};
|
|
76
|
-
|
|
77
|
-
return await
|
|
58
|
+
const whats = 'table elements are misused for non-table content';
|
|
59
|
+
return await doTest(
|
|
60
|
+
page, withItems, 'nonTable', 'table', whats, 2, 'TABLE', getBadWhat.toString()
|
|
61
|
+
);
|
|
78
62
|
};
|
package/testaro/optRoleSel.js
CHANGED
|
@@ -1,6 +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
5
|
|
|
5
6
|
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
7
|
https://opensource.org/license/mit/ for details.
|
|
@@ -11,24 +12,26 @@
|
|
|
11
12
|
/*
|
|
12
13
|
optRoleSel
|
|
13
14
|
Clean-room rule.
|
|
14
|
-
This test reports elements with role=
|
|
15
|
+
This test reports elements with role=option that are missing aria-selected attributes.
|
|
15
16
|
*/
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
// IMPORTS
|
|
18
19
|
|
|
20
|
+
const {doTest} = require('../procs/testaro');
|
|
21
|
+
|
|
22
|
+
// FUNCTIONS
|
|
23
|
+
|
|
24
|
+
// Runs the test and returns the result.
|
|
19
25
|
exports.reporter = async (page, withItems) => {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
complaints: {
|
|
27
|
-
instance: 'Element has an explicit option role but no aria-selected attribute',
|
|
28
|
-
summary: 'Elements with explicit option roles have no aria-selected attributes'
|
|
29
|
-
},
|
|
30
|
-
ordinalSeverity: 1,
|
|
31
|
-
summaryTagName: ''
|
|
26
|
+
const getBadWhat = element => {
|
|
27
|
+
// If the element has no aria-selected attribute:
|
|
28
|
+
if (! element.hasAttribute('aria-selected')) {
|
|
29
|
+
// Return a violation description.
|
|
30
|
+
return 'Element has role=option but no aria-selected attribute';
|
|
31
|
+
}
|
|
32
32
|
};
|
|
33
|
-
|
|
33
|
+
const whats = 'Elements with role=option have no aria-selected attributes';
|
|
34
|
+
return await doTest(
|
|
35
|
+
page, withItems, 'optRoleSel', '[role="option"]', whats, 1, null, getBadWhat.toString()
|
|
36
|
+
);
|
|
34
37
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2025 Jonathan Robert Pool.
|
|
4
|
+
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
+
https://opensource.org/license/mit/ for details.
|
|
7
|
+
|
|
8
|
+
SPDX-License-Identifier: MIT
|
|
9
|
+
*/
|
|
10
|
+
/*
|
|
11
|
+
pseudoP
|
|
12
|
+
This test reports 2 or more sequential br elements without intervening text content. They may be inferior substitutes for p elements.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// IMPORTS
|
|
16
|
+
|
|
17
|
+
const {doTest} = require('../procs/testaro');
|
|
18
|
+
|
|
19
|
+
// FUNCTIONS
|
|
20
|
+
|
|
21
|
+
exports.reporter = async (page, withItems) => {
|
|
22
|
+
const getBadWhat = element => {
|
|
23
|
+
// Get the node before the element node.
|
|
24
|
+
const previousNode = element.previousSibling;
|
|
25
|
+
let isBad = false;
|
|
26
|
+
// If it is a br element:
|
|
27
|
+
if (previousNode && previousNode.nodeType === Node.ELEMENT_NODE && previousNode.tagName === 'BR') {
|
|
28
|
+
// Classify the element as a violator.
|
|
29
|
+
isBad = true;
|
|
30
|
+
}
|
|
31
|
+
// Otherwise, if it is a text node:
|
|
32
|
+
else if (previousNode && previousNode.nodeType === Node.TEXT_NODE) {
|
|
33
|
+
// If the text node contains only whitespace:
|
|
34
|
+
if (previousNode.textContent.trim() === '') {
|
|
35
|
+
// Get the node before the text node.
|
|
36
|
+
const beforeText = previousNode.previousSibling;
|
|
37
|
+
// If that node is a br element:
|
|
38
|
+
if (beforeText && beforeText.nodeType === Node.ELEMENT_NODE && beforeText.tagName === 'BR') {
|
|
39
|
+
// Classify the element as a violator.
|
|
40
|
+
isBad = true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// If the element is a violator:
|
|
45
|
+
if (isBad) {
|
|
46
|
+
// Return a violation description.
|
|
47
|
+
return `Element follows another br element, possibly constituting a pseudo-paragraph`;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const whats = 'br elements follow other br elements, possibly constituting pseudo-paragraphs';
|
|
51
|
+
return await doTest(
|
|
52
|
+
page, withItems, 'pseudoP', 'body br', whats, 0, 'BR', getBadWhat.toString()
|
|
53
|
+
);
|
|
54
|
+
};
|
package/testaro/role.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
/*
|
|
12
12
|
role
|
|
13
|
-
This test reports elements with native-replacing explicit role attributes.
|
|
13
|
+
This test reports elements with native-replacing explicit role attributes. This test uses the getBasicResult function in order to have access to the aria-query dependency.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
// IMPORTS
|
package/testaro/textSem.js
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
© 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2025 Jonathan Robert Pool.
|
|
4
|
+
|
|
5
|
+
Licensed under the MIT License. See LICENSE file at the project root or
|
|
6
|
+
https://opensource.org/license/mit/ for details.
|
|
7
|
+
|
|
8
|
+
SPDX-License-Identifier: MIT
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
titledEl
|
|
13
|
+
This test reports suspicious use of title attributes.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// IMPORTS
|
|
17
|
+
|
|
18
|
+
const {doTest} = require('../procs/testaro');
|
|
19
|
+
|
|
20
|
+
// FUNCTIONS
|
|
21
|
+
|
|
22
|
+
// Runs the test and returns the result.
|
|
23
|
+
exports.reporter = async (page, withItems) => {
|
|
24
|
+
const getBadWhat = element => {
|
|
25
|
+
const elementType = element.tagName.toLowerCase();
|
|
26
|
+
// Return a violation description.
|
|
27
|
+
return `Likely ineffective title attribute is used on the ${elementType} element`;
|
|
28
|
+
}
|
|
29
|
+
const selector = '[title]:not(iframe, link, style)';
|
|
30
|
+
const whats = 'title attributes are used on elements they are likely ineffective on';
|
|
31
|
+
return await doTest(
|
|
32
|
+
page, withItems, 'titledEl', selector, whats, 0, null, getBadWhat.toString()
|
|
33
|
+
);
|
|
34
|
+
};
|