testaro 26.3.0 → 26.3.2
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/CONTRIBUTING.md +60 -37
- package/package.json +1 -1
- package/testaro/linkOldAtt.json +10 -0
- package/testaro/linkTo.json +1 -1
- package/testaro/nonTable.js +1 -1
- package/tests/testaro.js +1 -0
- package/validation/tests/jobs/linkOldAtt.json +130 -0
- package/validation/tests/jobs/linkTo.json +1 -1
- package/validation/tests/targets/linkOldAtt/index.html +17 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -1,45 +1,68 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Contributing to Testaro
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Types of contributions
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Testaro can benefit from contributions of various types, such as:
|
|
6
|
+
- Adding other tools to the tools that it integrates.
|
|
7
|
+
- Improving its execution speed.
|
|
8
|
+
- Improving its own rule implementations.
|
|
9
|
+
- Implementing new rules.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
## Adding tools
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
To come.
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
## Improving execution speed
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
1. Adding an entry to the `evalRules` or `etcRules` object in the `tests/testaro.js` file.
|
|
15
|
-
1. Adding a validation target directory to the `validation/tests/targets` directory.
|
|
16
|
-
1. Adding at least one validation target to the target directory.
|
|
17
|
-
1. Adding a validation job to the `validation/tests/jobs` directory.
|
|
17
|
+
To come.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Improving rule implementations.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
To come.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## Implementing new rules
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Testaro has about 50 of its own rules, in addition to the approximately 600 rules of the other tools that it integrates. According to the issue classifications in the [Testilo](https://www.npmjs.com/package/testilo) package, these 650 or so rules can be classified into about 260 accessibility _issues_, because some rules of some tools at least approximately duplicate some rules of other tools.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
However, many other significant accessibility issues exist that are not covered by any of the existing rules. Thus, Testaro welcomes contributions of new rules for such issues.
|
|
28
28
|
|
|
29
|
-
###
|
|
29
|
+
### Step 1
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
1. Creating a rule-definition file.
|
|
33
|
-
1. Adding the file to the `testaro` directory.
|
|
34
|
-
1. Validating it.
|
|
31
|
+
The first step in contributing a new rule to Testaro is to satisfy yourself that it will not duplicate existing rules. The `procs/score/tic35.js` file in the Testilo package should be helpful here.
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
### Step 2
|
|
34
|
+
|
|
35
|
+
The second step is to write a validator for the new rule. A validator is software that defines the correct behavior of the implementation of the rule.
|
|
36
|
+
|
|
37
|
+
Every Testaro rule has a correspoding validator. A validator has two parts:
|
|
38
|
+
- A job file, in the `validation/tests/jobs` directory. It tells Testaro what tests to perform and what the results should be.
|
|
39
|
+
- A target directory, within the `validation/tests/targets` directory. The target directory contains one or more HTML files that will be tested by the job.
|
|
40
|
+
|
|
41
|
+
Inspecting some of the jobs and targets in the `validation/tests` directory can help you understand how validators work.
|
|
42
|
+
|
|
43
|
+
### Step 3
|
|
44
|
+
|
|
45
|
+
The third step is to add an entry to the `evalRules` or `etcRules` object in the `tests/testaro.js` file.
|
|
46
|
+
|
|
47
|
+
### Step 4
|
|
48
|
+
|
|
49
|
+
The fourth step is to implement the new rule by creating a JavaScript or JSON file and saving it in the `testaro` directory.
|
|
50
|
+
|
|
51
|
+
To optimize quality, it may be wise for one person to perform steps 1, 2, and 3, and then for a second person independently to perform step 4 (“clean-room” development).
|
|
52
|
+
|
|
53
|
+
At any time after an implementation is attempted or revised, the developer can run the validation on it, simply by executing the statement `npm test xyz` (replacing `xyz` with the name of the new rule). When the implementation fails validation, diagnosis may find fault either with the implementation or with the validator.
|
|
54
|
+
|
|
55
|
+
Whether a new rule should be implemented in JSON or JavaScript depends on the complexity of the rule. The JSON format is effective for simple rules,and JavaScript is needed for more complex rules.
|
|
37
56
|
|
|
38
57
|
### Simple rules
|
|
39
58
|
|
|
40
|
-
|
|
59
|
+
You can create a JSON-defined rule if a single CSS selector can identify all and only the elements on a page that violate the rule.
|
|
60
|
+
|
|
61
|
+
Suppose, for example, that you want a rule prohibiting `i` elements (because `i` represents confusingly many different semantic properties). A single CSS selector, namely `"i"`, will identify all the `i` elements on the page, so this rule can be defined with JSON.
|
|
62
|
+
|
|
63
|
+
Substantially more complex rules, too, can satisfy this criterion. An example is the `captionLoc` rule, which prohibits `caption` elements that are not the first children of `table` elements. Its CSS selector is `"*:not(table) > caption, caption:not(:first-child)"`. That selector identifies every `caption` element that is the child of any non-`table` element, and also every caption element that is not the first among its sibling elements. The only ways to **avoid** being caught by this selector are (1) not to be a `caption` element and (2) to be a `caption` element that is the first child of a `table` element. Thus, the selector catches all the `caption` elements that are not first children of `table` elements, and only those.
|
|
41
64
|
|
|
42
|
-
|
|
65
|
+
You can copy and revise any of the existing JSON files in the `testaro` directory to implement a new rule. If, for example, you start with a copy of the `titledEl` file, you can change its properties to fit your new rule. In particular:
|
|
43
66
|
|
|
44
67
|
```json
|
|
45
68
|
{
|
|
@@ -54,20 +77,20 @@ An example is the `titledEl` rule:
|
|
|
54
77
|
}
|
|
55
78
|
```
|
|
56
79
|
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- When Testaro itemizes results, it reports the tag name of violating elements. When it only summarizes results, it includes the `summaryTagName`. If every violating element necessarily has one particular tag name, then you should make that (e.g., `BUTTON`) the value of `summaryTagName`.
|
|
80
|
+
- Assign a violation description for a single instance to `complaints.instance`.
|
|
81
|
+
- Assign a violation description for a summary instance (when itemization has been turned off) to `complaints.summary`.
|
|
82
|
+
- Assign an integer from 0 through 3 to `ordinalSeverity`.
|
|
83
|
+
- If all instances of violations of the rule necessarily involve elements of the same type, assign its tag name (such as `"BUTTON"`) to `summaryTagName`.
|
|
62
84
|
|
|
63
85
|
### Complex rules
|
|
64
86
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
An example of such an existing rule is `filter`. The test for that rule initially selects all elements that descend from the `body` element (or a sample of 100 such elements in the page contains more than 100). Then it examines each selected element to determine whether it violates the rule. Specifically, it determines whether the element has a `filter` style property with a value other than `'none'`. It reports those violations.
|
|
70
|
-
|
|
71
|
-
To define such a rule, you can copy an existing rule file and replace parts of its code as needed. Examples include:
|
|
72
|
-
- `allSlanted`, `distortion`, `filter`, `miniText`, `zIndex`: violations based on element styles.
|
|
87
|
+
More complex Testaro rules are implemented in JavaScript. You can use any of the existing JavaScript rules, or `data/template.js` file, as an example to begin with. Examples include:
|
|
88
|
+
- `allSlanted`, `distortion`, `filter`, `lineHeight`, `miniText`, `zIndex`: violations based on element styles.
|
|
89
|
+
- `focOp`, `opFoc`, `targetSize`: violations based on attributes
|
|
73
90
|
- `linkTitle`: violations based on attributes and text content.
|
|
91
|
+
- `linkAmb`, `pseudoP`, `radioSet`: violations based on relations among elements and text.
|
|
92
|
+
- `hover`, `tabNav`: violations based on performing actions and observing page behavior.
|
|
93
|
+
- `role`: violations based on data about standards.
|
|
94
|
+
- `docType`, `title`: violations based on page properties.
|
|
95
|
+
|
|
96
|
+
Some utility functions in modules in the `procs` directory are available for support of new rules.
|
package/package.json
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ruleID": "linkOldAtt",
|
|
3
|
+
"selector": "a[charset], a[coords], a[name], a[rev], a[shape]",
|
|
4
|
+
"complaints": {
|
|
5
|
+
"instance": "Element has a deprecated attribute",
|
|
6
|
+
"summary": "Links have deprecated attributes"
|
|
7
|
+
},
|
|
8
|
+
"ordinalSeverity": 1,
|
|
9
|
+
"summaryTagName": "A"
|
|
10
|
+
}
|
package/testaro/linkTo.json
CHANGED
package/testaro/nonTable.js
CHANGED
|
@@ -15,7 +15,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
15
15
|
const all = await init(page, 'table');
|
|
16
16
|
// For each locator:
|
|
17
17
|
for (const loc of all.allLocs) {
|
|
18
|
-
// Get whether its
|
|
18
|
+
// Get whether its element violates the rule.
|
|
19
19
|
const isBad = await loc.evaluate(el => {
|
|
20
20
|
const role = el.getAttribute('role');
|
|
21
21
|
// If it contains another table:
|
package/tests/testaro.js
CHANGED
|
@@ -39,6 +39,7 @@ const evalRules = {
|
|
|
39
39
|
lineHeight: 'text with a line height less than 1.5 times its font size',
|
|
40
40
|
linkExt: 'links that automatically open new windows',
|
|
41
41
|
linkAmb: 'links with identical texts but different destinations',
|
|
42
|
+
linkOldAtt: 'links with deprecated attributes',
|
|
42
43
|
linkTitle: 'links with title attributes repeating text content',
|
|
43
44
|
linkTo: 'links without destinations',
|
|
44
45
|
linkUl: 'missing underlines on inline links',
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "linkOldAtt",
|
|
3
|
+
"what": "validation of linkOldAtt test",
|
|
4
|
+
"strict": true,
|
|
5
|
+
"timeLimit": 20,
|
|
6
|
+
"acts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "launch",
|
|
9
|
+
"which": "chromium",
|
|
10
|
+
"url": "file://validation/tests/targets/linkOldAtt/index.html",
|
|
11
|
+
"what": "page with links with and without deprecated attributes"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "test",
|
|
15
|
+
"which": "testaro",
|
|
16
|
+
"withItems": true,
|
|
17
|
+
"stopOnFail": true,
|
|
18
|
+
"expect": [
|
|
19
|
+
[
|
|
20
|
+
"standardResult.totals.1",
|
|
21
|
+
"=",
|
|
22
|
+
2
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
"standardResult.totals.2",
|
|
26
|
+
"=",
|
|
27
|
+
0
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"standardResult.instances.0.ruleID",
|
|
31
|
+
"=",
|
|
32
|
+
"linkOldAtt"
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
"standardResult.instances.0.what",
|
|
36
|
+
"i",
|
|
37
|
+
"Element has a deprecated attribute"
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
"standardResult.instances.0.ordinalSeverity",
|
|
41
|
+
"=",
|
|
42
|
+
1
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
"standardResult.instances.0.tagName",
|
|
46
|
+
"=",
|
|
47
|
+
"A"
|
|
48
|
+
],
|
|
49
|
+
[
|
|
50
|
+
"standardResult.instances.0.location.doc",
|
|
51
|
+
"=",
|
|
52
|
+
"dom"
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
"standardResult.instances.0.location.type",
|
|
56
|
+
"=",
|
|
57
|
+
"box"
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"standardResult.instances.0.location.spec.y",
|
|
61
|
+
">",
|
|
62
|
+
0
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
"standardResult.instances.0.excerpt",
|
|
66
|
+
"=",
|
|
67
|
+
"French information"
|
|
68
|
+
]
|
|
69
|
+
],
|
|
70
|
+
"rules": [
|
|
71
|
+
"y",
|
|
72
|
+
"linkOldAtt"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "test",
|
|
77
|
+
"which": "testaro",
|
|
78
|
+
"withItems": false,
|
|
79
|
+
"stopOnFail": true,
|
|
80
|
+
"expect": [
|
|
81
|
+
[
|
|
82
|
+
"standardResult.totals.1",
|
|
83
|
+
"=",
|
|
84
|
+
2
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"standardResult.totals.3",
|
|
88
|
+
"=",
|
|
89
|
+
0
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
"standardResult.instances.0.ruleID",
|
|
93
|
+
"=",
|
|
94
|
+
"linkOldAtt"
|
|
95
|
+
],
|
|
96
|
+
[
|
|
97
|
+
"standardResult.instances.0.what",
|
|
98
|
+
"i",
|
|
99
|
+
"Links have deprecated attributes"
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"standardResult.instances.0.tagName",
|
|
103
|
+
"=",
|
|
104
|
+
"A"
|
|
105
|
+
],
|
|
106
|
+
[
|
|
107
|
+
"standardResult.instances.0.ordinalSeverity",
|
|
108
|
+
"=",
|
|
109
|
+
1
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
"standardResult.instances.0.count",
|
|
113
|
+
"=",
|
|
114
|
+
2
|
|
115
|
+
]
|
|
116
|
+
],
|
|
117
|
+
"rules": [
|
|
118
|
+
"y",
|
|
119
|
+
"linkOldAtt"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
"sources": {
|
|
124
|
+
"script": "",
|
|
125
|
+
"host": {},
|
|
126
|
+
"requester": ""
|
|
127
|
+
},
|
|
128
|
+
"creationTime": "2013-05-28T12:00:00",
|
|
129
|
+
"timeStamp": "00000"
|
|
130
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page with links with current and deprecated attributes</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page with links with current and deprecated attributes</h1>
|
|
12
|
+
<p>This is a link to <a href="https://en.wikipedia.org" hreflang="en">English information</a>.</p>
|
|
13
|
+
<p>Defect 1: This is a link to <a href="https://fr.wikipedia.org" hreflang="fr" charset="utf-8">French information</a>.</p>
|
|
14
|
+
<p>Defect 2: This is a link to <a href="https://de.wikipedia.org" name="dewiki">German information</a>.</p>
|
|
15
|
+
</main>
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|