testaro 18.7.0 → 18.8.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/testaro/embAc.js +25 -47
- package/testaro/filter.js +16 -82
- package/testaro/focVis.js +29 -74
- package/testaro/hr.js +12 -53
- package/validation/tests/jobs/embAc.json +9 -4
- package/validation/tests/jobs/filter.json +8 -13
- package/validation/tests/targets/embAc/bad.html +1 -1
package/package.json
CHANGED
package/testaro/embAc.js
CHANGED
|
@@ -8,59 +8,37 @@
|
|
|
8
8
|
|
|
9
9
|
// ########## IMPORTS
|
|
10
10
|
|
|
11
|
-
// Module to
|
|
12
|
-
const {
|
|
11
|
+
// Module to perform common operations.
|
|
12
|
+
const {init, report} = require('../procs/testaro');
|
|
13
13
|
|
|
14
14
|
// ########## FUNCTIONS
|
|
15
15
|
|
|
16
|
+
// Runs the test and returns the result.
|
|
16
17
|
exports.reporter = async (page, withItems) => {
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
'a a, a button, a input, a select, button a, button button, button input, button select'
|
|
18
|
+
// Initialize the locators and result.
|
|
19
|
+
const all = await init(
|
|
20
|
+
page, 'a a, a button, a input, a select, button a, button button, button input, button select'
|
|
20
21
|
);
|
|
21
|
-
const locs = await loc.all();
|
|
22
|
-
// Initialize the result.
|
|
23
|
-
const data = {};
|
|
24
|
-
const totals = [0, 0, 0, 0];
|
|
25
|
-
const standardInstances = [];
|
|
26
22
|
// For each locator:
|
|
27
|
-
for (const loc of
|
|
28
|
-
// Get
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
totals[2]++;
|
|
33
|
-
if (withItems) {
|
|
34
|
-
standardInstances.push({
|
|
35
|
-
ruleID: 'embAc',
|
|
36
|
-
what: `Interactive element is embedded in a ${parentTagName === 'A' ? 'link' : 'button'}`,
|
|
37
|
-
ordinalSeverity: 2,
|
|
38
|
-
tagName: elData.tagName,
|
|
39
|
-
id: elData.id,
|
|
40
|
-
location: elData.location,
|
|
41
|
-
excerpt: elData.excerpt
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
if (! withItems) {
|
|
46
|
-
standardInstances.push({
|
|
47
|
-
ruleID: 'embAc',
|
|
48
|
-
what: 'Interactive elements are contained by links or buttons',
|
|
49
|
-
ordinalSeverity: 2,
|
|
50
|
-
count: totals[2],
|
|
51
|
-
tagName: '',
|
|
52
|
-
id: '',
|
|
53
|
-
location: {
|
|
54
|
-
doc: '',
|
|
55
|
-
type: '',
|
|
56
|
-
spec: ''
|
|
57
|
-
},
|
|
58
|
-
excerpt: ''
|
|
23
|
+
for (const loc of all.allLocs) {
|
|
24
|
+
// Get whether its embedder is a link or a button.
|
|
25
|
+
const embedderTagName = await loc.evaluate(element => {
|
|
26
|
+
const embedder = element.parentElement.closest('a, button');
|
|
27
|
+
return embedder ? embedder.tagName : '';
|
|
59
28
|
});
|
|
29
|
+
let param = 'a link or button';
|
|
30
|
+
if (embedderTagName === 'A') {
|
|
31
|
+
param = 'a link';
|
|
32
|
+
}
|
|
33
|
+
else if (embedderTagName === 'BUTTON') {
|
|
34
|
+
param = 'a button';
|
|
35
|
+
}
|
|
36
|
+
all.locs.push([loc, param]);
|
|
60
37
|
}
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
38
|
+
// Populate and return the result.
|
|
39
|
+
const whats = [
|
|
40
|
+
'Interactive element is embedded in __param__',
|
|
41
|
+
'Interactive elements are contained by links or buttons'
|
|
42
|
+
];
|
|
43
|
+
return await report(withItems, all, 'embAc', whats, 2);
|
|
66
44
|
};
|
package/testaro/filter.js
CHANGED
|
@@ -8,95 +8,29 @@
|
|
|
8
8
|
|
|
9
9
|
// ########## IMPORTS
|
|
10
10
|
|
|
11
|
-
// Module to
|
|
12
|
-
const {
|
|
11
|
+
// Module to perform common operations.
|
|
12
|
+
const {init, report} = require('../procs/testaro');
|
|
13
13
|
|
|
14
14
|
// ########## FUNCTIONS
|
|
15
15
|
|
|
16
|
+
// Runs the test and returns the result.
|
|
16
17
|
exports.reporter = async (page, withItems) => {
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
const locsAll = await locAll.all();
|
|
20
|
-
// Initialize the standard results.
|
|
21
|
-
const data = {};
|
|
22
|
-
const totals = [0, 0, 0, 0];
|
|
23
|
-
const standardInstances = [];
|
|
24
|
-
// Initialize the instance locators.
|
|
25
|
-
const locs = [];
|
|
18
|
+
// Initialize the locators and result.
|
|
19
|
+
const all = await init(page, 'body *');
|
|
26
20
|
// For each locator:
|
|
27
|
-
for (const loc of
|
|
28
|
-
//
|
|
29
|
-
const
|
|
30
|
-
const styleDec = window.getComputedStyle(
|
|
21
|
+
for (const loc of all.allLocs) {
|
|
22
|
+
// Get whether its element violates the rule.
|
|
23
|
+
const isBad = await loc.evaluate(el => {
|
|
24
|
+
const styleDec = window.getComputedStyle(el);
|
|
31
25
|
return styleDec.filter !== 'none';
|
|
32
26
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
// If it does:
|
|
28
|
+
if (isBad) {
|
|
29
|
+
// Add the locator to the array of violators.
|
|
30
|
+
all.locs.push(loc);
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const impact = await loc.evaluate(element => element.querySelectorAll('*').length);
|
|
42
|
-
const elData = await getLocatorData(loc);
|
|
43
|
-
// Add to the standard result.
|
|
44
|
-
totals[2]++;
|
|
45
|
-
totals[1] += impact;
|
|
46
|
-
// If itemization is required:
|
|
47
|
-
if (withItems) {
|
|
48
|
-
// Add a standard instance for the element.
|
|
49
|
-
standardInstances.push({
|
|
50
|
-
ruleID: 'filter',
|
|
51
|
-
what: `Element has a filter style; impacted element count: ${impact}`,
|
|
52
|
-
ordinalSeverity: 2,
|
|
53
|
-
tagName: elData.tagName,
|
|
54
|
-
id: elData.id,
|
|
55
|
-
location: elData.location,
|
|
56
|
-
excerpt: elData.excerpt
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// If itemization is not required and there are any instances:
|
|
61
|
-
if (! withItems && totals[2]) {
|
|
62
|
-
// Adda summary instance:
|
|
63
|
-
standardInstances.push({
|
|
64
|
-
ruleID: 'filter',
|
|
65
|
-
what: 'Elements have filter styles',
|
|
66
|
-
ordinalSeverity: 2,
|
|
67
|
-
count: totals[2],
|
|
68
|
-
tagName: '',
|
|
69
|
-
id: '',
|
|
70
|
-
location: {
|
|
71
|
-
doc: '',
|
|
72
|
-
type: '',
|
|
73
|
-
spec: ''
|
|
74
|
-
},
|
|
75
|
-
excerpt: ''
|
|
76
|
-
});
|
|
77
|
-
// If any impact occurred:
|
|
78
|
-
if (totals[1]) {
|
|
79
|
-
// Add a summary instance.
|
|
80
|
-
standardInstances.push({
|
|
81
|
-
ruleID: 'filter',
|
|
82
|
-
what: 'Elements are impacted by elements with filter styles',
|
|
83
|
-
ordinalSeverity: 1,
|
|
84
|
-
count: totals[1],
|
|
85
|
-
tagName: '',
|
|
86
|
-
id: '',
|
|
87
|
-
location: {
|
|
88
|
-
doc: '',
|
|
89
|
-
type: '',
|
|
90
|
-
spec: ''
|
|
91
|
-
},
|
|
92
|
-
excerpt: ''
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// Return the result.
|
|
97
|
-
return {
|
|
98
|
-
data,
|
|
99
|
-
totals,
|
|
100
|
-
standardInstances
|
|
101
|
-
};
|
|
33
|
+
// Populate and return the result.
|
|
34
|
+
const whats = ['Element has a filter style', 'Elements have filter styles'];
|
|
35
|
+
return await report(withItems, all, 'filter', whats, 2);
|
|
102
36
|
};
|
package/testaro/focVis.js
CHANGED
|
@@ -6,88 +6,43 @@
|
|
|
6
6
|
|
|
7
7
|
// ########## IMPORTS
|
|
8
8
|
|
|
9
|
-
// Module to
|
|
10
|
-
const {
|
|
9
|
+
// Module to perform common operations.
|
|
10
|
+
const {init, report} = require('../procs/testaro');
|
|
11
11
|
|
|
12
12
|
// ########## FUNCTIONS
|
|
13
13
|
|
|
14
|
+
// Runs the test and returns the result.
|
|
14
15
|
exports.reporter = async (page, withItems) => {
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const isOff = isAbove || isLeft;
|
|
25
|
-
return isOff;
|
|
16
|
+
// Initialize the locators and result.
|
|
17
|
+
const all = await init(page, 'a:visible');
|
|
18
|
+
// For each locator:
|
|
19
|
+
for (const loc of all.allLocs) {
|
|
20
|
+
// Get how its element violates the rule, if it does.
|
|
21
|
+
const isBad = await loc.evaluate(el => {
|
|
22
|
+
const isAbove = el.offsetTop + el.offsetHeight <= 0;
|
|
23
|
+
const isLeft = el.offsetLeft + el.offsetWidth <= 0;
|
|
24
|
+
return [isAbove, isLeft];
|
|
26
25
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
for (const loc of locs) {
|
|
37
|
-
// Get data on it.
|
|
38
|
-
const elData = await getLocatorData(loc);
|
|
39
|
-
// Add to the totals.
|
|
40
|
-
totals[2]++;
|
|
41
|
-
if (withItems) {
|
|
42
|
-
let where;
|
|
43
|
-
if (elData.location.type === 'selector') {
|
|
44
|
-
where = 'above or to the left of';
|
|
26
|
+
// If it does:
|
|
27
|
+
if (isBad[0] || isBad[1]) {
|
|
28
|
+
// Add the locator to the array of violators.
|
|
29
|
+
let param;
|
|
30
|
+
if (isBad[0] && isBad[1]) {
|
|
31
|
+
param = 'above and to the left of';
|
|
32
|
+
}
|
|
33
|
+
else if (isBad[0]) {
|
|
34
|
+
param = 'above';
|
|
45
35
|
}
|
|
46
36
|
else {
|
|
47
|
-
|
|
48
|
-
const isAbove = elData.location.spec.y < 0;
|
|
49
|
-
if (isLeft && isAbove) {
|
|
50
|
-
where = 'above and to the left of';
|
|
51
|
-
}
|
|
52
|
-
else if (isLeft) {
|
|
53
|
-
where = 'to the left of';
|
|
54
|
-
}
|
|
55
|
-
else if (isAbove) {
|
|
56
|
-
where = 'above';
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
where = 'possibly above or to the left of';
|
|
60
|
-
}
|
|
37
|
+
param = 'to the left of';
|
|
61
38
|
}
|
|
62
|
-
|
|
63
|
-
ruleID: 'focVis',
|
|
64
|
-
what: `Visible link is ${where} the display`,
|
|
65
|
-
ordinalSeverity: 2,
|
|
66
|
-
tagName: 'A',
|
|
67
|
-
id: elData.id,
|
|
68
|
-
location: elData.location,
|
|
69
|
-
excerpt: elData.excerpt
|
|
70
|
-
});
|
|
39
|
+
all.locs.push([loc, param]);
|
|
71
40
|
}
|
|
72
41
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
id: '',
|
|
80
|
-
location: {
|
|
81
|
-
doc: '',
|
|
82
|
-
type: '',
|
|
83
|
-
spec: ''
|
|
84
|
-
},
|
|
85
|
-
excerpt: ''
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
return {
|
|
89
|
-
data,
|
|
90
|
-
totals,
|
|
91
|
-
standardInstances
|
|
92
|
-
};
|
|
42
|
+
// Populate and return the result.
|
|
43
|
+
const whats = [
|
|
44
|
+
'Visible link is __param__ the display',
|
|
45
|
+
'Visible links are above or to the left of the display'
|
|
46
|
+
];
|
|
47
|
+
return await report(withItems, all, 'focVis', whats, 2);
|
|
93
48
|
};
|
package/testaro/hr.js
CHANGED
|
@@ -7,61 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
// ########## IMPORTS
|
|
9
9
|
|
|
10
|
-
// Module to
|
|
11
|
-
const {
|
|
10
|
+
// Module to perform common operations.
|
|
11
|
+
const {init, report} = require('../procs/testaro');
|
|
12
12
|
|
|
13
13
|
// ########## FUNCTIONS
|
|
14
14
|
|
|
15
|
-
//
|
|
15
|
+
// Runs the test and returns the result.
|
|
16
16
|
exports.reporter = async (page, withItems) => {
|
|
17
|
-
// Initialize the
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// Add to the totals.
|
|
27
|
-
totals[0]++;
|
|
28
|
-
// If itemization is required:
|
|
29
|
-
if (withItems) {
|
|
30
|
-
// Get data on the element.
|
|
31
|
-
const elData = await getLocatorData(loc);
|
|
32
|
-
// Add a standard instance.
|
|
33
|
-
standardInstances.push({
|
|
34
|
-
ruleID: 'hr',
|
|
35
|
-
what: 'Element instead of styling is used for vertical segmentation',
|
|
36
|
-
ordinalSeverity: 0,
|
|
37
|
-
tagName: 'HR',
|
|
38
|
-
id: elData.id,
|
|
39
|
-
location: elData.location,
|
|
40
|
-
excerpt: elData.excerpt
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
// If itemization is not required and there are instances:
|
|
45
|
-
if (! withItems && totals[0]) {
|
|
46
|
-
// Add a summary instance.
|
|
47
|
-
standardInstances.push({
|
|
48
|
-
ruleID: 'hr',
|
|
49
|
-
what: 'Elements instead of styling are used for vertical segmentation',
|
|
50
|
-
ordinalSeverity: 0,
|
|
51
|
-
count: totals[0],
|
|
52
|
-
tagName: 'HR',
|
|
53
|
-
id: '',
|
|
54
|
-
location: {
|
|
55
|
-
doc: '',
|
|
56
|
-
type: '',
|
|
57
|
-
spec: ''
|
|
58
|
-
},
|
|
59
|
-
excerpt: ''
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
return {
|
|
63
|
-
data,
|
|
64
|
-
totals,
|
|
65
|
-
standardInstances
|
|
66
|
-
};
|
|
17
|
+
// Initialize the locators and result.
|
|
18
|
+
const all = await init(page, 'body hr');
|
|
19
|
+
all.locs = all.allLocs;
|
|
20
|
+
// Populate and return the result.
|
|
21
|
+
const whats = [
|
|
22
|
+
'Element instead of styling is used for vertical segmentation',
|
|
23
|
+
'Elements instead of styling are used for vertical segmentation'
|
|
24
|
+
];
|
|
25
|
+
return await report(withItems, all, 'hr', whats, 0, 'HR');
|
|
67
26
|
};
|
|
@@ -67,6 +67,11 @@
|
|
|
67
67
|
"=",
|
|
68
68
|
"BUTTON"
|
|
69
69
|
],
|
|
70
|
+
[
|
|
71
|
+
"standardResult.instances.0.id",
|
|
72
|
+
"=",
|
|
73
|
+
"buttonInLink"
|
|
74
|
+
],
|
|
70
75
|
[
|
|
71
76
|
"standardResult.instances.0.location.doc",
|
|
72
77
|
"=",
|
|
@@ -75,12 +80,12 @@
|
|
|
75
80
|
[
|
|
76
81
|
"standardResult.instances.0.location.type",
|
|
77
82
|
"=",
|
|
78
|
-
"
|
|
83
|
+
"selector"
|
|
79
84
|
],
|
|
80
85
|
[
|
|
81
|
-
"standardResult.instances.0.location.spec
|
|
82
|
-
"
|
|
83
|
-
|
|
86
|
+
"standardResult.instances.0.location.spec",
|
|
87
|
+
"=",
|
|
88
|
+
"#buttonInLink"
|
|
84
89
|
],
|
|
85
90
|
[
|
|
86
91
|
"standardResult.instances.0.excerpt",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
[
|
|
56
56
|
"standardResult.totals.1",
|
|
57
57
|
"=",
|
|
58
|
-
|
|
58
|
+
0
|
|
59
59
|
],
|
|
60
60
|
[
|
|
61
61
|
"standardResult.instances.0.ruleID",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
[
|
|
66
66
|
"standardResult.instances.0.what",
|
|
67
67
|
"i",
|
|
68
|
-
"
|
|
68
|
+
"Element has"
|
|
69
69
|
],
|
|
70
70
|
[
|
|
71
71
|
"standardResult.instances.0.tagName",
|
|
@@ -127,7 +127,12 @@
|
|
|
127
127
|
[
|
|
128
128
|
"standardResult.totals.1",
|
|
129
129
|
"=",
|
|
130
|
-
|
|
130
|
+
0
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
"standardResult.instances.length",
|
|
134
|
+
"=",
|
|
135
|
+
1
|
|
131
136
|
],
|
|
132
137
|
[
|
|
133
138
|
"standardResult.instances.0.ruleID",
|
|
@@ -139,20 +144,10 @@
|
|
|
139
144
|
"i",
|
|
140
145
|
"Elements have"
|
|
141
146
|
],
|
|
142
|
-
[
|
|
143
|
-
"standardResult.instances.1.ordinalSeverity",
|
|
144
|
-
"=",
|
|
145
|
-
1
|
|
146
|
-
],
|
|
147
147
|
[
|
|
148
148
|
"standardResult.instances.0.count",
|
|
149
149
|
"=",
|
|
150
150
|
2
|
|
151
|
-
],
|
|
152
|
-
[
|
|
153
|
-
"standardResult.instances.1.count",
|
|
154
|
-
"=",
|
|
155
|
-
7
|
|
156
151
|
]
|
|
157
152
|
],
|
|
158
153
|
"rules": [
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<main>
|
|
11
11
|
<h1>Page with embedded interactive elements</h1>
|
|
12
12
|
<p>All of the following embeddings violate the HTML specification for <a href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element">links</a> or <a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element">buttons</a>.</p>
|
|
13
|
-
<p>Bug 1. This link to <a href="https://en.wikipedia.org/wiki/Button">information about <button type="button">buttons</button> like this</a> contains one.</p>
|
|
13
|
+
<p>Bug 1. This link to <a href="https://en.wikipedia.org/wiki/Button">information about <button id="buttonInLink" type="button">buttons</button> like this</a> contains one.</p>
|
|
14
14
|
<p>Bug 2. This link to <a href="https://en.wikipedia.org/wiki/Input_method">information about checkboxes such as <input type="checkbox" aria-label="yes or no"> this</a> contains one.</p>
|
|
15
15
|
<p>Bug 3. This link to <a href="https://en.wikipedia.org/wiki/Drop-down_list">information about drop-down lists such as <select aria-label="choose one"><option>A</option><option>B</option></select></a> contains one.</p>
|
|
16
16
|
<p>Bugs 4 and 5. This link to <a href="https://en.wikipedia.org/wiki/HTML">information about HTML text inputs (<input type="text" aria-label="input">), <button type="button">buttons</button>, etc.</a> contains a text input and a button.</p>
|