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 CHANGED
@@ -1,45 +1,68 @@
1
- # testaro
1
+ # Contributing to Testaro
2
2
 
3
- Ensemble testing for web accessibility
3
+ ## Types of contributions
4
4
 
5
- ## Contributing
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
- Contributions to Testaro are welcome.
11
+ ## Adding tools
8
12
 
9
- ### Testaro rule specification
13
+ To come.
10
14
 
11
- Testaro integrates 8 accessibility testing tools, and one of them is Testaro itself. The Testaro tool has defined 43 rules, and the other 7 tools have defined about 600 rules in the aggregate. Contributing a new Testaro rule can add value if the new rule will not merely duplicate one of the existing rules. The issue classification (`tic…`) files in the `procs` directory of the [Testilo](https://www.npmjs.com/package/testilo) package can help in this determination.
15
+ ## Improving execution speed
12
16
 
13
- If you determine that a new Testaro rule would be valuable, the first step is to specify it. This specification has the following parts:
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
- ### Testaro rule validation
19
+ ## Improving rule implementations.
20
20
 
21
- All Testaro rules have validators, as mentioned above.
21
+ To come.
22
22
 
23
- The first step in creating a validator is to create at least one HTML file that will be tested against the new rule. A single `index.html` file may suffice. It should contain cases that will pass the test and cases that will fail the test. If appropriate, you can create multiple targets, such as `good.html` and `bad.html`.
23
+ ## Implementing new rules
24
24
 
25
- The second step is to create a validation job. It launches a browser, navigates to a validation target, and conducts the test. It includes expectations about the results. Typically, the expectations relate to the standard instances included in the results. The `Tests/Expectations` section of the `README.md` file describes the syntax of expectations.
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
- When a rule `xyz` has been defined and the `npm test xyz` statement is executed, the validation job will be run.
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
- ### Rule creation
29
+ ### Step 1
30
30
 
31
- Once you have specified a new rule, you, or somebody else, can develop the rule in accord with your specification. Developing the rule consists of:
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
- For example, if the new rule has the ID `bigAlt`, it must succeed when the statement `npm test bigAlt` is executed.
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
- Some existing Testaro rules are simple enough to be defined in JSON files. If a new rule is similarly simple, you can define it with a similar JSON file.
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
- An example is the `titledEl` rule:
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
- To create a simple rule, you can copy one of the existing JSON files and replace the values with values that are appropriate for the new rule. Testaro uses the properties in the file as follows:
58
- - Every element matching the selector is treated as a violator of the rule.
59
- - Testaro describes violations with one of the `complaints` values. If the user has requested itemized results, the `instance` value is used; otherwise the `summary` value is used.
60
- - Testaro assigns the `ordinalSeverity` value as the ordinal severity of each violation. This is a scale of integers, from 0 to 3.
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
- Your new rule may not be quite so simple. For example, it may need to examine the selected elements and identify only some of them as rule violators.
66
-
67
- You will need to define such a rule in a JavaScript file, rather than a JSON file.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "26.3.0",
3
+ "version": "26.3.2",
4
4
  "description": "Run 650 web accessibility tests from 8 tools and get a standardized report",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
+ }
@@ -2,7 +2,7 @@
2
2
  "ruleID": "linkTo",
3
3
  "selector": "a:not([href]):visible",
4
4
  "complaints": {
5
- "instance": "Link has no href attribute",
5
+ "instance": "Element has no href attribute",
6
6
  "summary": "Links are missing href attributes"
7
7
  },
8
8
  "ordinalSeverity": 2,
@@ -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 el violates the rule.
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
+ }
@@ -34,7 +34,7 @@
34
34
  [
35
35
  "standardResult.instances.0.what",
36
36
  "i",
37
- "Link has no"
37
+ "Element has no"
38
38
  ],
39
39
  [
40
40
  "standardResult.instances.0.ordinalSeverity",
@@ -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>