testaro 18.5.0 → 18.6.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 +14 -6
- package/testaro/allCaps.js +34 -80
- package/testaro/allSlanted.js +25 -79
- package/testaro/attVal.js +19 -58
- package/testaro/distortion.js +1 -1
- package/testaro/template.js +1 -1
- package/validation/tests/jobs/allCaps.json +15 -0
- package/validation/tests/jobs/allSlanted.json +10 -5
- package/validation/tests/jobs/attVal.json +1 -1
package/package.json
CHANGED
package/procs/testaro.js
CHANGED
|
@@ -8,9 +8,9 @@ const {getLocatorData} = require('../procs/getLocatorData');
|
|
|
8
8
|
// ########## FUNCTIONS
|
|
9
9
|
|
|
10
10
|
// Initializes locators and a result.
|
|
11
|
-
exports.init = async (page, locAllSelector) => {
|
|
11
|
+
exports.init = async (page, locAllSelector, options = {}) => {
|
|
12
12
|
// Get locators for the specified elements.
|
|
13
|
-
const locAll = page.locator(locAllSelector);
|
|
13
|
+
const locAll = page.locator(locAllSelector, options);
|
|
14
14
|
const allLocs = await locAll.all();
|
|
15
15
|
const result = {
|
|
16
16
|
data: {},
|
|
@@ -30,8 +30,16 @@ exports.report = async (withItems, all, ruleID, whats, ordinalSeverity, tagName
|
|
|
30
30
|
const {locs, result} = all;
|
|
31
31
|
const {totals, standardInstances} = result;
|
|
32
32
|
// For each instance locator:
|
|
33
|
-
for (const
|
|
33
|
+
for (const locItem of locs) {
|
|
34
34
|
// Get data on its element.
|
|
35
|
+
let loc, whatParam;
|
|
36
|
+
if (Array.isArray(locItem)) {
|
|
37
|
+
loc = locItem[0];
|
|
38
|
+
whatParam = locItem[1];
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
loc = locItem;
|
|
42
|
+
}
|
|
35
43
|
const elData = await getLocatorData(loc);
|
|
36
44
|
// Add to the totals.
|
|
37
45
|
totals[ordinalSeverity]++;
|
|
@@ -40,7 +48,7 @@ exports.report = async (withItems, all, ruleID, whats, ordinalSeverity, tagName
|
|
|
40
48
|
// Add a standard instance to the result.
|
|
41
49
|
standardInstances.push({
|
|
42
50
|
ruleID,
|
|
43
|
-
what: whats[0],
|
|
51
|
+
what: whatParam ? whats[0].replace('__param__', whatParam) : whats[0],
|
|
44
52
|
ordinalSeverity,
|
|
45
53
|
tagName: elData.tagName,
|
|
46
54
|
id: elData.id,
|
|
@@ -49,8 +57,8 @@ exports.report = async (withItems, all, ruleID, whats, ordinalSeverity, tagName
|
|
|
49
57
|
});
|
|
50
58
|
}
|
|
51
59
|
}
|
|
52
|
-
// If itemization is not required:
|
|
53
|
-
if (! withItems) {
|
|
60
|
+
// If itemization is not required and any instances exist:
|
|
61
|
+
if (! withItems && locs.length) {
|
|
54
62
|
// Add a summary standard instance to the result.
|
|
55
63
|
standardInstances.push({
|
|
56
64
|
ruleID,
|
package/testaro/allCaps.js
CHANGED
|
@@ -1,96 +1,50 @@
|
|
|
1
1
|
/*
|
|
2
2
|
allCaps
|
|
3
3
|
Related to Tenon rule 153.
|
|
4
|
-
This test reports
|
|
5
|
-
|
|
6
|
-
to read.
|
|
4
|
+
This test reports elements with native or transformed upper-case text at least 8 characters long.
|
|
5
|
+
Blocks of upper-case text are difficult to read.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
// ########## IMPORTS
|
|
10
9
|
|
|
11
|
-
// Module to
|
|
12
|
-
const {
|
|
10
|
+
// Module to perform common operations.
|
|
11
|
+
const {init, report} = require('../procs/testaro');
|
|
13
12
|
|
|
14
13
|
// ########## FUNCTIONS
|
|
15
14
|
|
|
16
|
-
// Runs the test and returns the
|
|
15
|
+
// Runs the test and returns the result.
|
|
17
16
|
exports.reporter = async (page, withItems) => {
|
|
18
|
-
//
|
|
19
|
-
const
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
//
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
isCap = true;
|
|
17
|
+
// Initialize the locators and result.
|
|
18
|
+
const all = await init(page, 'body *:not(style):not(script):not(svg)');
|
|
19
|
+
// For each locator:
|
|
20
|
+
for (const loc of all.allLocs) {
|
|
21
|
+
// Get whether its element violates the rule.
|
|
22
|
+
const isBad = await loc.evaluate(el => {
|
|
23
|
+
const elText = Array
|
|
24
|
+
.from(el.childNodes)
|
|
25
|
+
.filter(node => node.nodeType === Node.TEXT_NODE)
|
|
26
|
+
.map(textNode => textNode.nodeValue)
|
|
27
|
+
.join(' ');
|
|
28
|
+
// If the element text includes 8 sequential upper-case letters, spaces, or hyphen-minuses:
|
|
29
|
+
if (/[- A-Z]{8}/.test(elText)) {
|
|
30
|
+
// Report this.
|
|
31
|
+
return true;
|
|
34
32
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
// Otherwise:
|
|
34
|
+
else {
|
|
35
|
+
// Report whether its text is at least 8 characters long and transformed to upper case.
|
|
36
|
+
const elStyleDec = window.getComputedStyle(el);
|
|
37
|
+
const transformStyle = elStyleDec.textTransform;
|
|
38
|
+
return transformStyle === 'uppercase' && elText.length > 7;
|
|
40
39
|
}
|
|
41
|
-
if (isCap) {
|
|
42
|
-
// Add to the totals.
|
|
43
|
-
result.totals[0]++;
|
|
44
|
-
// If itemization is required:
|
|
45
|
-
if (withItems) {
|
|
46
|
-
// Add a standard instance.
|
|
47
|
-
const {id} = textNodeData[1];
|
|
48
|
-
let spec;
|
|
49
|
-
if (id) {
|
|
50
|
-
spec = `#${id}`;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
const domRect = textNodeData[1].getBoundingClientRect();
|
|
54
|
-
spec = {
|
|
55
|
-
x: Math.round(domRect.x),
|
|
56
|
-
y: Math.round(domRect.y),
|
|
57
|
-
width: Math.round(domRect.width),
|
|
58
|
-
height: Math.round(domRect.height)
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
result.standardInstances.push({
|
|
62
|
-
ruleID: 'allCaps',
|
|
63
|
-
what: 'Text is entirely upper-case',
|
|
64
|
-
ordinalSeverity: 0,
|
|
65
|
-
tagName: textNodeData[1].tagName,
|
|
66
|
-
id: id || '',
|
|
67
|
-
location: {
|
|
68
|
-
doc: 'dom',
|
|
69
|
-
type: id ? 'selector' : 'box',
|
|
70
|
-
spec
|
|
71
|
-
},
|
|
72
|
-
excerpt: textNodeData[0]
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return result;
|
|
78
|
-
}, withItems);
|
|
79
|
-
if (! withItems) {
|
|
80
|
-
result.standardInstances.push({
|
|
81
|
-
ruleID: 'allCaps',
|
|
82
|
-
what: 'Texts are entirely upper-case',
|
|
83
|
-
ordinalSeverity: 0,
|
|
84
|
-
count: result.totals[0],
|
|
85
|
-
tagName: '',
|
|
86
|
-
id: '',
|
|
87
|
-
location: {
|
|
88
|
-
doc: '',
|
|
89
|
-
type: '',
|
|
90
|
-
spec: ''
|
|
91
|
-
},
|
|
92
|
-
excerpt: ''
|
|
93
40
|
});
|
|
41
|
+
// If it does:
|
|
42
|
+
if (isBad) {
|
|
43
|
+
// Add the locator to the array of violators.
|
|
44
|
+
all.locs.push(loc);
|
|
45
|
+
}
|
|
94
46
|
}
|
|
95
|
-
return result
|
|
47
|
+
// Populate and return the result.
|
|
48
|
+
const whats = ['Element contains all-capital text', 'Elements contain all-capital text'];
|
|
49
|
+
return await report(withItems, all, 'allCaps', whats, 0);
|
|
96
50
|
};
|
package/testaro/allSlanted.js
CHANGED
|
@@ -1,93 +1,39 @@
|
|
|
1
1
|
/*
|
|
2
2
|
allSlanted
|
|
3
3
|
Related to Tenon rule 154.
|
|
4
|
-
This test reports
|
|
5
|
-
|
|
6
|
-
to read.
|
|
4
|
+
This test reports elements with italic or oblique text at least 40 characters long. Blocks of
|
|
5
|
+
slanted text are difficult to read.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
// ########## IMPORTS
|
|
10
9
|
|
|
11
|
-
// Module to
|
|
12
|
-
const {
|
|
10
|
+
// Module to perform common operations.
|
|
11
|
+
const {init, report} = require('../procs/testaro');
|
|
13
12
|
|
|
14
13
|
// ########## FUNCTIONS
|
|
15
14
|
|
|
16
|
-
// Runs the test and returns the
|
|
15
|
+
// Runs the test and returns the result.
|
|
17
16
|
exports.reporter = async (page, withItems) => {
|
|
18
|
-
//
|
|
19
|
-
const
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
//
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
// For each text node:
|
|
29
|
-
for (const textNodeData of textNodesData) {
|
|
30
|
-
// If it qualifies:
|
|
31
|
-
let isSlanted = false;
|
|
32
|
-
if (/.{40}/.test(textNodeData[0])) {
|
|
33
|
-
const styleDec = window.getComputedStyle(textNodeData[1]);
|
|
34
|
-
if (['italic', 'oblique'].includes(styleDec.fontStyle)) {
|
|
35
|
-
isSlanted = true;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (isSlanted) {
|
|
39
|
-
// Add to the totals.
|
|
40
|
-
result.totals[0]++;
|
|
41
|
-
// If itemization is required:
|
|
42
|
-
if (withItems) {
|
|
43
|
-
// Add a standard instance.
|
|
44
|
-
const {id} = textNodeData[1];
|
|
45
|
-
let spec;
|
|
46
|
-
if (id) {
|
|
47
|
-
spec = `#${id}`;
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
const domRect = textNodeData[1].getBoundingClientRect();
|
|
51
|
-
spec = {
|
|
52
|
-
x: Math.round(domRect.x),
|
|
53
|
-
y: Math.round(domRect.y),
|
|
54
|
-
width: Math.round(domRect.width),
|
|
55
|
-
height: Math.round(domRect.height)
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
result.standardInstances.push({
|
|
59
|
-
ruleID: 'allSlanted',
|
|
60
|
-
what: 'Text is entirely italic or oblique',
|
|
61
|
-
ordinalSeverity: 0,
|
|
62
|
-
tagName: textNodeData[1].tagName,
|
|
63
|
-
id: id || '',
|
|
64
|
-
location: {
|
|
65
|
-
doc: 'dom',
|
|
66
|
-
type: id ? 'selector' : 'box',
|
|
67
|
-
spec
|
|
68
|
-
},
|
|
69
|
-
excerpt: textNodeData[0]
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
}, withItems);
|
|
76
|
-
if (! withItems) {
|
|
77
|
-
result.standardInstances.push({
|
|
78
|
-
ruleID: 'allSlanted',
|
|
79
|
-
what: 'Texts are entirely italic or oblique',
|
|
80
|
-
ordinalSeverity: 0,
|
|
81
|
-
count: result.totals[0],
|
|
82
|
-
tagName: '',
|
|
83
|
-
id: '',
|
|
84
|
-
location: {
|
|
85
|
-
doc: '',
|
|
86
|
-
type: '',
|
|
87
|
-
spec: ''
|
|
88
|
-
},
|
|
89
|
-
excerpt: ''
|
|
17
|
+
// Initialize the locators and result.
|
|
18
|
+
const all = await init(page, 'body *:not(style):not(script):not(svg)');
|
|
19
|
+
// For each locator:
|
|
20
|
+
for (const loc of all.allLocs) {
|
|
21
|
+
// Get whether its element violates the rule.
|
|
22
|
+
const isBad = await loc.evaluate(el => {
|
|
23
|
+
const elStyleDec = window.getComputedStyle(el);
|
|
24
|
+
const elText = el.textContent;
|
|
25
|
+
return ['italic', 'oblique'].includes(elStyleDec.fontStyle) && elText.length > 39;
|
|
90
26
|
});
|
|
27
|
+
// If it does:
|
|
28
|
+
if (isBad) {
|
|
29
|
+
// Add the locator to the array of violators.
|
|
30
|
+
all.locs.push(loc);
|
|
31
|
+
}
|
|
91
32
|
}
|
|
92
|
-
return result
|
|
33
|
+
// Populate and return the result.
|
|
34
|
+
const whats = [
|
|
35
|
+
'Element contains all-italic or all-oblique text',
|
|
36
|
+
'Elements contain all-italic or all-oblique text'
|
|
37
|
+
];
|
|
38
|
+
return await report(withItems, all, 'allSlanted', whats, 0);
|
|
93
39
|
};
|
package/testaro/attVal.js
CHANGED
|
@@ -5,69 +5,30 @@
|
|
|
5
5
|
|
|
6
6
|
// ########## IMPORTS
|
|
7
7
|
|
|
8
|
-
// Module to
|
|
9
|
-
const {
|
|
8
|
+
// Module to perform common operations.
|
|
9
|
+
const {init, report} = require('../procs/testaro');
|
|
10
10
|
|
|
11
11
|
// ########## FUNCTIONS
|
|
12
12
|
|
|
13
|
-
// Runs the test and returns the
|
|
13
|
+
// Runs the test and returns the result.
|
|
14
14
|
exports.reporter = async (page, withItems, attributeName, areLicit, values) => {
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
for (const loc of locsAll) {
|
|
15
|
+
// Initialize the locators and result.
|
|
16
|
+
const all = await init(page, `[${attributeName}]`);
|
|
17
|
+
// For each locator:
|
|
18
|
+
for (const loc of all.allLocs) {
|
|
19
|
+
// Get whether its element violates the rule.
|
|
21
20
|
const value = await loc.getAttribute(attributeName);
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const isBad = areLicit !== values.includes(value);
|
|
22
|
+
// If it does:
|
|
23
|
+
if (isBad) {
|
|
24
|
+
// Add the locator to the array of violators.
|
|
25
|
+
all.locs.push([loc, value]);
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
|
-
//
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// For each qualifying locator:
|
|
33
|
-
for (const loc of locs) {
|
|
34
|
-
// Get data on its element.
|
|
35
|
-
const elData = await getLocatorData(loc);
|
|
36
|
-
// Get the illicit value of the attribute.
|
|
37
|
-
const badValue = await loc.getAttribute(attributeName);
|
|
38
|
-
// Add a standard instance.
|
|
39
|
-
standardInstances.push({
|
|
40
|
-
ruleID: 'attVal',
|
|
41
|
-
what: `Element has attribute ${attributeName} with illicit value ${badValue}`,
|
|
42
|
-
ordinalSeverity: 2,
|
|
43
|
-
tagName: elData.tagName,
|
|
44
|
-
id: elData.id,
|
|
45
|
-
location: elData.location,
|
|
46
|
-
excerpt: elData.excerpt
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// Otherwise, i.e. if itemization is not required and any instances exist:
|
|
51
|
-
else if (totals[2]) {
|
|
52
|
-
// Add a summary standard instance.
|
|
53
|
-
standardInstances.push({
|
|
54
|
-
ruleID: 'attVal',
|
|
55
|
-
what: `Elements have attribute ${attributeName} with illicit values`,
|
|
56
|
-
ordinalSeverity: 2,
|
|
57
|
-
count: totals[2],
|
|
58
|
-
tagName: '',
|
|
59
|
-
id: '',
|
|
60
|
-
location: {
|
|
61
|
-
doc: '',
|
|
62
|
-
type: '',
|
|
63
|
-
spec: ''
|
|
64
|
-
},
|
|
65
|
-
excerpt: ''
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
data,
|
|
70
|
-
totals,
|
|
71
|
-
standardInstances
|
|
72
|
-
};
|
|
28
|
+
// Populate and return the result.
|
|
29
|
+
const whats = [
|
|
30
|
+
`Element has attribute ${attributeName} with illicit value “__param__”`,
|
|
31
|
+
`Elements have attribute ${attributeName} with illicit values`
|
|
32
|
+
];
|
|
33
|
+
return await report(withItems, all, 'attVal', whats, 2);
|
|
73
34
|
};
|
package/testaro/distortion.js
CHANGED
|
@@ -12,7 +12,7 @@ const {init, report} = require('../procs/testaro');
|
|
|
12
12
|
|
|
13
13
|
// ########## FUNCTIONS
|
|
14
14
|
|
|
15
|
-
// Runs the test and returns the
|
|
15
|
+
// Runs the test and returns the result.
|
|
16
16
|
exports.reporter = async (page, withItems) => {
|
|
17
17
|
// Initialize the locators and result.
|
|
18
18
|
const all = await init(page, 'body *');
|
package/testaro/template.js
CHANGED
|
@@ -10,7 +10,7 @@ const {init, report} = require('../procs/testaro');
|
|
|
10
10
|
|
|
11
11
|
// ########## FUNCTIONS
|
|
12
12
|
|
|
13
|
-
// Runs the test and returns the
|
|
13
|
+
// Runs the test and returns the result.
|
|
14
14
|
exports.reporter = async (page, withItems) => {
|
|
15
15
|
// Initialize the locators and result.
|
|
16
16
|
const all = await init(page, 'body *');
|
|
@@ -30,6 +30,16 @@
|
|
|
30
30
|
"=",
|
|
31
31
|
0
|
|
32
32
|
],
|
|
33
|
+
[
|
|
34
|
+
"standardResult.instances.0.ruleID",
|
|
35
|
+
"=",
|
|
36
|
+
"allCaps"
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
"standardResult.instances.0.what",
|
|
40
|
+
"i",
|
|
41
|
+
"Element contains"
|
|
42
|
+
],
|
|
33
43
|
[
|
|
34
44
|
"standardResult.instances.0.tagName",
|
|
35
45
|
"=",
|
|
@@ -112,6 +122,11 @@
|
|
|
112
122
|
"=",
|
|
113
123
|
0
|
|
114
124
|
],
|
|
125
|
+
[
|
|
126
|
+
"standardResult.instances.0.what",
|
|
127
|
+
"i",
|
|
128
|
+
"Elements contain"
|
|
129
|
+
],
|
|
115
130
|
[
|
|
116
131
|
"standardResult.instances.0.count",
|
|
117
132
|
"=",
|
|
@@ -30,6 +30,16 @@
|
|
|
30
30
|
"=",
|
|
31
31
|
0
|
|
32
32
|
],
|
|
33
|
+
[
|
|
34
|
+
"standardResult.instances.0.ruleID",
|
|
35
|
+
"=",
|
|
36
|
+
"allSlanted"
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
"standardResult.instances.0.what",
|
|
40
|
+
"i",
|
|
41
|
+
"Element contains"
|
|
42
|
+
],
|
|
33
43
|
[
|
|
34
44
|
"standardResult.instances.0.tagName",
|
|
35
45
|
"=",
|
|
@@ -40,11 +50,6 @@
|
|
|
40
50
|
"=",
|
|
41
51
|
0
|
|
42
52
|
],
|
|
43
|
-
[
|
|
44
|
-
"standardResult.instances.0.what",
|
|
45
|
-
"i",
|
|
46
|
-
"Text is entirely"
|
|
47
|
-
],
|
|
48
53
|
[
|
|
49
54
|
"standardResult.instances.0.location.type",
|
|
50
55
|
"=",
|