testaro 18.7.0 → 18.9.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/isInlineLink.js +0 -4
- 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/testaro/labClash.js +24 -62
- package/testaro/lineHeight.js +21 -82
- package/testaro/linkAmb.js +23 -46
- package/testaro/linkExt.js +9 -53
- package/testaro/linkTitle.js +21 -51
- package/testaro/linkTo.js +9 -54
- package/testaro/linkUl.js +21 -67
- package/validation/tests/jobs/embAc.json +9 -4
- package/validation/tests/jobs/filter.json +8 -13
- package/validation/tests/jobs/lineHeight.json +5 -5
- package/validation/tests/targets/embAc/bad.html +1 -1
package/package.json
CHANGED
package/procs/isInlineLink.js
CHANGED
|
@@ -7,17 +7,14 @@
|
|
|
7
7
|
exports.isInlineLink = async loc => await loc.evaluate(element => {
|
|
8
8
|
// Initialize the link as inline.
|
|
9
9
|
let result = true;
|
|
10
|
-
console.log('Initialized as inline');
|
|
11
10
|
// If it is in a list item in a list of at least 2 links:
|
|
12
11
|
const listAncestor = element.closest('ul, ol');
|
|
13
12
|
if (listAncestor) {
|
|
14
|
-
console.log('Has a list ancestor');
|
|
15
13
|
if (listAncestor.children.length > 1 && Array.from(listAncestor.children).every(child => {
|
|
16
14
|
const isValidListItem = child.tagName === 'LI';
|
|
17
15
|
const has1Link = child.querySelectorAll('a').length === 1;
|
|
18
16
|
return isValidListItem && has1Link;
|
|
19
17
|
})) {
|
|
20
|
-
console.log('List is pure');
|
|
21
18
|
// If the list text is entirely link text:
|
|
22
19
|
const listText = listAncestor.textContent.replace(/\s/g, '');
|
|
23
20
|
let linkTextRaw = '';
|
|
@@ -27,7 +24,6 @@ exports.isInlineLink = async loc => await loc.evaluate(element => {
|
|
|
27
24
|
const linkText = linkTextRaw.replace(/\s/g, '');
|
|
28
25
|
console.log(linkText);
|
|
29
26
|
if (listText === linkText && listText.length) {
|
|
30
|
-
console.log('No extraneous text, so non-inline');
|
|
31
27
|
// Reclassify the link as non-inline.
|
|
32
28
|
result = false;
|
|
33
29
|
}
|
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
|
};
|
package/testaro/labClash.js
CHANGED
|
@@ -5,80 +5,42 @@
|
|
|
5
5
|
labels are additive, not conflicting.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
// Module to get locator data.
|
|
11
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
8
|
+
// Module to perform common operations.
|
|
9
|
+
const {init, report} = require('../procs/testaro');
|
|
12
10
|
|
|
13
11
|
// ########## FUNCTIONS
|
|
14
12
|
|
|
13
|
+
// Runs the test and returns the result.
|
|
15
14
|
exports.reporter = async (page, withItems) => {
|
|
16
|
-
// Initialize the
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const locsAll = await locAll.all();
|
|
23
|
-
// For each of them:
|
|
24
|
-
for (const loc of locsAll) {
|
|
25
|
-
// Get its label types.
|
|
26
|
-
const labelTypes = await loc.evaluate(element => {
|
|
15
|
+
// Initialize the locators and result.
|
|
16
|
+
const all = await init(page, 'button, input:not([type=hidden]), select, textarea');
|
|
17
|
+
// For each locator:
|
|
18
|
+
for (const loc of all.allLocs) {
|
|
19
|
+
// Get the label types of its element.
|
|
20
|
+
const labelTypes = await loc.evaluate(el => {
|
|
27
21
|
const labelTypes = [];
|
|
28
|
-
// Attribute
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
labelTypes.push('aria-labelledby');
|
|
35
|
-
}
|
|
22
|
+
// Attribute and reference labels.
|
|
23
|
+
['aria-label', 'aria-labelledby'].forEach(type => {
|
|
24
|
+
if (el.hasAttribute(type)) {
|
|
25
|
+
labelTypes.push(type);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
36
28
|
// Explicit and implicit labels.
|
|
37
|
-
const labels = Array.from(
|
|
29
|
+
const labels = Array.from(el.labels);
|
|
38
30
|
if (labels.length) {
|
|
39
31
|
labelTypes.push('label');
|
|
40
32
|
}
|
|
41
33
|
return labelTypes;
|
|
42
34
|
});
|
|
43
|
-
// If it has
|
|
35
|
+
// If it has more than 1:
|
|
44
36
|
if (labelTypes.length > 1) {
|
|
45
|
-
// Add to the
|
|
46
|
-
|
|
47
|
-
if (withItems) {
|
|
48
|
-
const elData = await getLocatorData(loc);
|
|
49
|
-
standardInstances.push({
|
|
50
|
-
ruleID: 'labClash',
|
|
51
|
-
what: `Element has inconsistent label types (${labelTypes.join(', ')})`,
|
|
52
|
-
ordinalSeverity: 2,
|
|
53
|
-
tagName: elData.tagName,
|
|
54
|
-
id: elData.id,
|
|
55
|
-
location: elData.location,
|
|
56
|
-
excerpt: elData.excerpt
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// If there are any instances and itemization is not required:
|
|
61
|
-
if (totals[2] && ! withItems) {
|
|
62
|
-
// Add a summary standard instance.
|
|
63
|
-
standardInstances.push({
|
|
64
|
-
ruleID: 'labClash',
|
|
65
|
-
what: 'Elements have inconsistent label types',
|
|
66
|
-
count: totals[2],
|
|
67
|
-
ordinalSeverity: 2,
|
|
68
|
-
tagName: '',
|
|
69
|
-
id: '',
|
|
70
|
-
location: {
|
|
71
|
-
doc: '',
|
|
72
|
-
type: '',
|
|
73
|
-
spec: ''
|
|
74
|
-
},
|
|
75
|
-
excerpt: ''
|
|
76
|
-
});
|
|
37
|
+
// Add the locator and a list of them to the array of violators.
|
|
38
|
+
all.locs.push([loc, labelTypes.join(', ')]);
|
|
77
39
|
}
|
|
78
40
|
}
|
|
79
|
-
return
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
41
|
+
// Populate and return the result.
|
|
42
|
+
const whats = [
|
|
43
|
+
'Element has inconsistent label types (__param__)', 'Elements have inconsistent label types'
|
|
44
|
+
];
|
|
45
|
+
return await report(withItems, all, 'labClash', whats, 2);
|
|
84
46
|
};
|
package/testaro/lineHeight.js
CHANGED
|
@@ -7,98 +7,37 @@
|
|
|
7
7
|
their subtrees are excluded.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
// Module to get locator data.
|
|
13
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
10
|
+
// Module to perform common operations.
|
|
11
|
+
const {init, report} = require('../procs/testaro');
|
|
14
12
|
|
|
15
13
|
// ########## FUNCTIONS
|
|
16
14
|
|
|
17
|
-
//
|
|
18
|
-
const getRatio = ordinalSeverity => ['1.5', '1.3', '1.1', '0.9'][ordinalSeverity];
|
|
15
|
+
// Runs the test and returns the result.
|
|
19
16
|
exports.reporter = async (page, withItems) => {
|
|
20
|
-
// Initialize the
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// For each of them:
|
|
28
|
-
for (const loc of locsAll) {
|
|
29
|
-
// Get data on it.
|
|
30
|
-
const facts = await loc.evaluate(element => {
|
|
31
|
-
const styleDec = window.getComputedStyle(element);
|
|
17
|
+
// Initialize the locators and result.
|
|
18
|
+
const all = await init(page, 'body *', {hasText: /[^\s]/});
|
|
19
|
+
// For each locator:
|
|
20
|
+
for (const loc of all.allLocs) {
|
|
21
|
+
// Get whether its element violates the rule.
|
|
22
|
+
const data = await loc.evaluate(el => {
|
|
23
|
+
const styleDec = window.getComputedStyle(el);
|
|
32
24
|
const {fontSize, lineHeight} = styleDec;
|
|
33
25
|
return {
|
|
34
26
|
fontSize: Number.parseFloat(fontSize),
|
|
35
27
|
lineHeight: Number.parseFloat(lineHeight)
|
|
36
28
|
};
|
|
37
29
|
});
|
|
38
|
-
// If
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
else if (ratio < 1.1) {
|
|
45
|
-
ordinalSeverity = 2;
|
|
46
|
-
}
|
|
47
|
-
else if (ratio < 1.3) {
|
|
48
|
-
ordinalSeverity = 1;
|
|
49
|
-
}
|
|
50
|
-
else if (ratio < 1.5) {
|
|
51
|
-
ordinalSeverity = 0;
|
|
30
|
+
// If it does:
|
|
31
|
+
const isBad = data.lineHeight < 1.5 * data.fontSize;
|
|
32
|
+
if (isBad) {
|
|
33
|
+
// Add the locator to the array of violators.
|
|
34
|
+
all.locs.push([loc, `font size ${data.fontSize} px, line height ${data.lineHeight} px`]);
|
|
52
35
|
}
|
|
53
|
-
if (ordinalSeverity > -1) {
|
|
54
|
-
// Add to the totals.
|
|
55
|
-
totals[ordinalSeverity]++;
|
|
56
|
-
// If itemization is required:
|
|
57
|
-
if (withItems) {
|
|
58
|
-
// Get data on the element.
|
|
59
|
-
const elData = await getLocatorData(loc);
|
|
60
|
-
// Add a standard instance.
|
|
61
|
-
standardInstances.push({
|
|
62
|
-
ruleID: 'lineHeight',
|
|
63
|
-
what:
|
|
64
|
-
`Element line height ${facts.lineHeight} px is less than ${getRatio(ordinalSeverity)} times its font size ${facts.fontSize} px`,
|
|
65
|
-
ordinalSeverity,
|
|
66
|
-
tagName: elData.tagName,
|
|
67
|
-
id: elData.id,
|
|
68
|
-
location: elData.location,
|
|
69
|
-
excerpt: elData.excerpt
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// If itemization is not required:
|
|
75
|
-
if (! withItems) {
|
|
76
|
-
// For each ordinal severity:
|
|
77
|
-
[0, 1, 2, 3].forEach(ordinalSeverity => {
|
|
78
|
-
// If there are instances with it:
|
|
79
|
-
if (totals[ordinalSeverity]) {
|
|
80
|
-
// Add a summary instance.
|
|
81
|
-
standardInstances.push({
|
|
82
|
-
ruleID: 'lineHeight',
|
|
83
|
-
what:
|
|
84
|
-
`Elements have line heights less than ${getRatio(ordinalSeverity)} times their font sizes`,
|
|
85
|
-
ordinalSeverity,
|
|
86
|
-
count: totals[ordinalSeverity],
|
|
87
|
-
tagName: '',
|
|
88
|
-
id: '',
|
|
89
|
-
location: {
|
|
90
|
-
doc: '',
|
|
91
|
-
type: '',
|
|
92
|
-
spec: ''
|
|
93
|
-
},
|
|
94
|
-
excerpt: ''
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
36
|
}
|
|
99
|
-
return
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
37
|
+
// Populate and return the result.
|
|
38
|
+
const whats = [
|
|
39
|
+
'Element line height is less than 1.5 times its font size (__param__)',
|
|
40
|
+
'Elements have line heights less than 1.5 times their font sizes'
|
|
41
|
+
];
|
|
42
|
+
return await report(withItems, all, 'lineHeight', whats, 1);
|
|
104
43
|
};
|
package/testaro/linkAmb.js
CHANGED
|
@@ -5,61 +5,38 @@
|
|
|
5
5
|
Text contents are compared case-insensitively.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
|
|
8
|
+
// Module to perform common operations.
|
|
9
|
+
const {init, report} = require('../procs/testaro');
|
|
10
10
|
// Module to get locator data.
|
|
11
11
|
const {getLocatorData} = require('../procs/getLocatorData');
|
|
12
12
|
|
|
13
13
|
// ########## FUNCTIONS
|
|
14
14
|
|
|
15
|
+
// Runs the test and returns the result.
|
|
15
16
|
exports.reporter = async (page, withItems) => {
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
// Get data on them.
|
|
23
|
-
const excerpts = new Set();
|
|
24
|
-
for (const loc of locsAll) {
|
|
17
|
+
// Initialize the locators and result.
|
|
18
|
+
const all = await init(page, 'a[href]:visible');
|
|
19
|
+
const linkTexts = new Set();
|
|
20
|
+
// For each locator:
|
|
21
|
+
for (const loc of all.allLocs) {
|
|
22
|
+
// Get its text.
|
|
25
23
|
const elData = await getLocatorData(loc);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
what: 'Link has the same text as, but a different destination from, another',
|
|
32
|
-
ordinalSeverity: 2,
|
|
33
|
-
tagName: 'A',
|
|
34
|
-
id: elData.id,
|
|
35
|
-
location: elData.location,
|
|
36
|
-
excerpt: elData.excerpt
|
|
37
|
-
});
|
|
38
|
-
}
|
|
24
|
+
// If a previous link has the same text:
|
|
25
|
+
const linkText = elData.excerpt.toLowerCase();
|
|
26
|
+
if (linkTexts.has(linkText)) {
|
|
27
|
+
// Add the locator to the array of violators.
|
|
28
|
+
all.locs.push(loc);
|
|
39
29
|
}
|
|
30
|
+
// Otherwise, i.e. if this is the first link with the text:
|
|
40
31
|
else {
|
|
41
|
-
|
|
32
|
+
// Record its text.
|
|
33
|
+
linkTexts.add(linkText);
|
|
42
34
|
}
|
|
43
35
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
tagName: 'A',
|
|
51
|
-
id: '',
|
|
52
|
-
location: {
|
|
53
|
-
doc: '',
|
|
54
|
-
type: '',
|
|
55
|
-
spec: ''
|
|
56
|
-
},
|
|
57
|
-
excerpt: ''
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
data,
|
|
62
|
-
totals,
|
|
63
|
-
standardInstances
|
|
64
|
-
};
|
|
36
|
+
// Populate and return the result.
|
|
37
|
+
const whats = [
|
|
38
|
+
'Link has the same text as, but a different destination from, another',
|
|
39
|
+
'Links have the same texts but different destinations'
|
|
40
|
+
];
|
|
41
|
+
return await report(withItems, all, 'linkAmb', whats, 2);
|
|
65
42
|
};
|
package/testaro/linkExt.js
CHANGED
|
@@ -5,61 +5,17 @@
|
|
|
5
5
|
risk miscommunication of the externality and remove control from the user.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
// Module to get locator data.
|
|
11
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
8
|
+
// Module to perform common operations.
|
|
9
|
+
const {init, report} = require('../procs/testaro');
|
|
12
10
|
|
|
13
11
|
// ########## FUNCTIONS
|
|
14
12
|
|
|
13
|
+
// Runs the test and returns the result.
|
|
15
14
|
exports.reporter = async (page, withItems) => {
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
// Add to the result.
|
|
23
|
-
totals[0] = locs.length;
|
|
24
|
-
// If itemization is required:
|
|
25
|
-
if (withItems) {
|
|
26
|
-
// For each such link:
|
|
27
|
-
for (const loc of locs) {
|
|
28
|
-
// Get data on it.
|
|
29
|
-
const elData = await getLocatorData(loc);
|
|
30
|
-
// Add to the result.
|
|
31
|
-
standardInstances.push({
|
|
32
|
-
ruleID: 'linkExt',
|
|
33
|
-
what: 'Link has a target=_blank attribute',
|
|
34
|
-
ordinalSeverity: 0,
|
|
35
|
-
tagName: 'A',
|
|
36
|
-
id: elData.id,
|
|
37
|
-
location: elData.location,
|
|
38
|
-
excerpt: elData.excerpt
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
// Otherwise, i.e. if itemization is not required:
|
|
43
|
-
else {
|
|
44
|
-
// Add a summary instance.
|
|
45
|
-
standardInstances.push({
|
|
46
|
-
ruleID: 'linkExt',
|
|
47
|
-
what: 'Links have target=_blank attributes',
|
|
48
|
-
count: totals[0],
|
|
49
|
-
ordinalSeverity: 0,
|
|
50
|
-
tagName: 'A',
|
|
51
|
-
id: '',
|
|
52
|
-
location: {
|
|
53
|
-
doc: '',
|
|
54
|
-
type: '',
|
|
55
|
-
spec: ''
|
|
56
|
-
},
|
|
57
|
-
excerpt: ''
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
data,
|
|
62
|
-
totals,
|
|
63
|
-
standardInstances
|
|
64
|
-
};
|
|
15
|
+
// Initialize the locators and result.
|
|
16
|
+
const all = await init(page, 'a[target=_blank]');
|
|
17
|
+
all.locs = all.allLocs;
|
|
18
|
+
// Populate and return the result.
|
|
19
|
+
const whats = ['Link has a target=_blank attribute', 'Links have target=_blank attributes'];
|
|
20
|
+
return await report(withItems, all, 'linkExt', whats, 0);
|
|
65
21
|
};
|
package/testaro/linkTitle.js
CHANGED
|
@@ -1,66 +1,36 @@
|
|
|
1
1
|
/*
|
|
2
2
|
linkTitle
|
|
3
3
|
Related to Tenon rule 79.
|
|
4
|
-
This test reports links with title attributes
|
|
4
|
+
This test reports links with title attributes whose values the link text contains.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
|
|
7
|
+
// Module to perform common operations.
|
|
8
|
+
const {init, report} = require('../procs/testaro');
|
|
9
9
|
// Module to get locator data.
|
|
10
10
|
const {getLocatorData} = require('../procs/getLocatorData');
|
|
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
|
-
const locs = await locAll.all();
|
|
21
|
-
// For each of them:
|
|
22
|
-
for (const loc of locs) {
|
|
23
|
-
// Get data on it.
|
|
24
|
-
const title = await loc.getAttribute('title');
|
|
16
|
+
// Initialize the locators and result.
|
|
17
|
+
const all = await init(page, 'a[title]');
|
|
18
|
+
// For each locator:
|
|
19
|
+
for (const loc of all.allLocs) {
|
|
20
|
+
// Get whether its element violates the rule.
|
|
25
21
|
const elData = await getLocatorData(loc);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
ruleID: 'linkTitle',
|
|
33
|
-
what: 'Link has a title attribute that repeats link text content',
|
|
34
|
-
ordinalSeverity: 0,
|
|
35
|
-
tagName: 'A',
|
|
36
|
-
id: elData.id,
|
|
37
|
-
location: elData.location,
|
|
38
|
-
excerpt: elData.excerpt
|
|
39
|
-
});
|
|
40
|
-
}
|
|
22
|
+
const title = await loc.getAttribute('title');
|
|
23
|
+
const isBad = elData.excerpt.toLowerCase().includes(title.toLowerCase());
|
|
24
|
+
// If it does:
|
|
25
|
+
if (isBad) {
|
|
26
|
+
// Add the locator to the array of violators.
|
|
27
|
+
all.locs.push(loc);
|
|
41
28
|
}
|
|
42
29
|
}
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
count: totals[0],
|
|
50
|
-
ordinalSeverity: 0,
|
|
51
|
-
tagName: 'A',
|
|
52
|
-
id: '',
|
|
53
|
-
location: {
|
|
54
|
-
doc: '',
|
|
55
|
-
type: '',
|
|
56
|
-
spec: ''
|
|
57
|
-
},
|
|
58
|
-
excerpt: ''
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
return {
|
|
62
|
-
data,
|
|
63
|
-
totals,
|
|
64
|
-
standardInstances
|
|
65
|
-
};
|
|
30
|
+
// Populate and return the result.
|
|
31
|
+
const whats = [
|
|
32
|
+
'Link has a title attribute that repeats link text content',
|
|
33
|
+
'Links have title attributes that repeat link text contents'
|
|
34
|
+
];
|
|
35
|
+
return await report(withItems, all, 'linkTitle', whats, 0);
|
|
66
36
|
};
|
package/testaro/linkTo.js
CHANGED
|
@@ -4,62 +4,17 @@
|
|
|
4
4
|
This test reports failures to equip links with destinations.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
// Module to get locator data.
|
|
10
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
7
|
+
// Module to perform common operations.
|
|
8
|
+
const {init, report} = require('../procs/testaro');
|
|
11
9
|
|
|
12
10
|
// ########## FUNCTIONS
|
|
13
11
|
|
|
12
|
+
// Runs the test and returns the result.
|
|
14
13
|
exports.reporter = async (page, withItems) => {
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
// For each of them:
|
|
22
|
-
for (const loc of locs) {
|
|
23
|
-
// If itemization is required:
|
|
24
|
-
if (withItems) {
|
|
25
|
-
// Get data on the element.
|
|
26
|
-
const elData = await getLocatorData(loc);
|
|
27
|
-
// Add an instance to the result.
|
|
28
|
-
standardInstances.push({
|
|
29
|
-
ruleID: 'linkTo',
|
|
30
|
-
what: 'Link has no href attribute',
|
|
31
|
-
ordinalSeverity: 2,
|
|
32
|
-
tagName: 'A',
|
|
33
|
-
id: elData.id,
|
|
34
|
-
location: elData.location,
|
|
35
|
-
excerpt: elData.excerpt
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// Add to the totals.
|
|
40
|
-
totals[2] = locs.length;
|
|
41
|
-
// If itemization is not required:
|
|
42
|
-
if (! withItems) {
|
|
43
|
-
// Add a summary instance to the result.
|
|
44
|
-
standardInstances.push({
|
|
45
|
-
ruleID: 'linkTo',
|
|
46
|
-
what: 'Links are missing href attributes',
|
|
47
|
-
count: totals[2],
|
|
48
|
-
ordinalSeverity: 2,
|
|
49
|
-
tagName: 'A',
|
|
50
|
-
id: '',
|
|
51
|
-
location: {
|
|
52
|
-
doc: '',
|
|
53
|
-
type: '',
|
|
54
|
-
spec: ''
|
|
55
|
-
},
|
|
56
|
-
excerpt: ''
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
// Return the result.
|
|
60
|
-
return {
|
|
61
|
-
data,
|
|
62
|
-
totals,
|
|
63
|
-
standardInstances
|
|
64
|
-
};
|
|
14
|
+
// Initialize the locators and result.
|
|
15
|
+
const all = await init(page, 'a:not([href]):visible');
|
|
16
|
+
all.locs = all.allLocs;
|
|
17
|
+
// Populate and return the result.
|
|
18
|
+
const whats = ['Link has no href attribute', 'inks are missing href attributes'];
|
|
19
|
+
return await report(withItems, all, 'linkTo', whats, 2);
|
|
65
20
|
};
|
package/testaro/linkUl.js
CHANGED
|
@@ -8,82 +8,36 @@
|
|
|
8
8
|
merely to discover which passages are links.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
// Module to get locator data.
|
|
14
|
-
const {getLocatorData} = require('../procs/getLocatorData');
|
|
11
|
+
// Module to perform common operations.
|
|
12
|
+
const {init, report} = require('../procs/testaro');
|
|
15
13
|
// Module to classify links.
|
|
16
14
|
const {isInlineLink} = require('../procs/isInlineLink');
|
|
17
15
|
|
|
18
16
|
// ########## FUNCTIONS
|
|
19
17
|
|
|
18
|
+
// Runs the test and returns the result.
|
|
20
19
|
exports.reporter = async (page, withItems) => {
|
|
21
|
-
// Initialize the result.
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const inlineLocs = [];
|
|
29
|
-
for (const loc of locsAll) {
|
|
30
|
-
if (await isInlineLink(loc)) {
|
|
31
|
-
inlineLocs.push(loc);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// Get locators for all non-underlined inline links.
|
|
35
|
-
const locs = [];
|
|
36
|
-
for (const loc of inlineLocs) {
|
|
37
|
-
const isUnderlined = await loc.evaluate(element => {
|
|
38
|
-
const styleDec = window.getComputedStyle(element);
|
|
20
|
+
// Initialize the locators and result.
|
|
21
|
+
const all = await init(page, 'a');
|
|
22
|
+
// For each locator:
|
|
23
|
+
for (const loc of all.allLocs) {
|
|
24
|
+
// Get whether its element is underlined.
|
|
25
|
+
const isUnderlined = await loc.evaluate(el => {
|
|
26
|
+
const styleDec = window.getComputedStyle(el);
|
|
39
27
|
return styleDec.textDecorationLine === 'underline';
|
|
40
28
|
});
|
|
29
|
+
// If it is not:
|
|
41
30
|
if (! isUnderlined) {
|
|
42
|
-
|
|
31
|
+
// Get whether it is inline.
|
|
32
|
+
const isInline = await isInlineLink(loc);
|
|
33
|
+
// If it is:
|
|
34
|
+
if (isInline) {
|
|
35
|
+
// Add the locator to the array of violators.
|
|
36
|
+
all.locs.push(loc);
|
|
37
|
+
}
|
|
43
38
|
}
|
|
44
39
|
}
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (withItems) {
|
|
49
|
-
// For each non-underlined inline link:
|
|
50
|
-
for (const loc of locs) {
|
|
51
|
-
// Get data on it.
|
|
52
|
-
const elData = await getLocatorData(loc);
|
|
53
|
-
// Add an instance to the result.
|
|
54
|
-
standardInstances.push({
|
|
55
|
-
ruleID: 'linkUl',
|
|
56
|
-
what: 'Link is inline but has no underline',
|
|
57
|
-
ordinalSeverity: 1,
|
|
58
|
-
tagName: 'A',
|
|
59
|
-
id: elData.id,
|
|
60
|
-
location: elData.location,
|
|
61
|
-
excerpt: elData.excerpt
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// Otherwise, i.e. if itemization is not required:
|
|
66
|
-
else {
|
|
67
|
-
// Add a summary instance to the result.
|
|
68
|
-
standardInstances.push({
|
|
69
|
-
ruleID: 'linkUl',
|
|
70
|
-
what: 'Inline links are missing underlines',
|
|
71
|
-
count: totals[1],
|
|
72
|
-
ordinalSeverity: 1,
|
|
73
|
-
tagName: 'A',
|
|
74
|
-
id: '',
|
|
75
|
-
location: {
|
|
76
|
-
doc: '',
|
|
77
|
-
type: '',
|
|
78
|
-
spec: ''
|
|
79
|
-
},
|
|
80
|
-
excerpt: ''
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
// Return the result.
|
|
84
|
-
return {
|
|
85
|
-
data,
|
|
86
|
-
totals,
|
|
87
|
-
standardInstances
|
|
88
|
-
};
|
|
40
|
+
// Populate and return the result.
|
|
41
|
+
const whats = ['Link is inline but has no underline', 'Inline links are missing underlines'];
|
|
42
|
+
return await report(withItems, all, 'linkUl', whats, 1);
|
|
89
43
|
};
|
|
@@ -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": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"stopOnFail": true,
|
|
22
22
|
"expect": [
|
|
23
23
|
[
|
|
24
|
-
"standardResult.totals.
|
|
24
|
+
"standardResult.totals.1",
|
|
25
25
|
"=",
|
|
26
26
|
1
|
|
27
27
|
],
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
[
|
|
39
39
|
"standardResult.instances.0.what",
|
|
40
40
|
"i",
|
|
41
|
-
"is less than
|
|
41
|
+
"is less than 1.5 times"
|
|
42
42
|
],
|
|
43
43
|
[
|
|
44
44
|
"standardResult.instances.0.ordinalSeverity",
|
|
45
45
|
"=",
|
|
46
|
-
|
|
46
|
+
1
|
|
47
47
|
],
|
|
48
48
|
[
|
|
49
49
|
"standardResult.instances.0.tagName",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"stopOnFail": true,
|
|
89
89
|
"expect": [
|
|
90
90
|
[
|
|
91
|
-
"standardResult.totals.
|
|
91
|
+
"standardResult.totals.1",
|
|
92
92
|
"=",
|
|
93
93
|
1
|
|
94
94
|
],
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
[
|
|
116
116
|
"standardResult.instances.0.what",
|
|
117
117
|
"i",
|
|
118
|
-
"heights less than
|
|
118
|
+
"heights less than 1.5 times"
|
|
119
119
|
]
|
|
120
120
|
],
|
|
121
121
|
"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>
|