testaro 1.0.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/LICENSE +21 -0
- package/README.md +502 -0
- package/aceconfig.js +7 -0
- package/commands.js +249 -0
- package/index.js +1248 -0
- package/package.json +39 -0
- package/procs/score/asp09.js +555 -0
- package/procs/test/allText.js +76 -0
- package/procs/test/allVis.js +17 -0
- package/procs/test/linksByType.js +90 -0
- package/procs/test/textOf.txt +73 -0
- package/scoring/correlation.js +74 -0
- package/scoring/correlations.json +327 -0
- package/scoring/data.json +26021 -0
- package/scoring/dupCounts.js +39 -0
- package/scoring/dupCounts.json +112 -0
- package/scoring/duplications.json +253 -0
- package/scoring/issues.json +304 -0
- package/scoring/packageData.js +171 -0
- package/scoring/packageIssues.js +34 -0
- package/scoring/rulesetData.json +15 -0
- package/tests/aatt.js +64 -0
- package/tests/alfa.js +107 -0
- package/tests/axe.js +109 -0
- package/tests/bulk.js +21 -0
- package/tests/embAc.js +36 -0
- package/tests/focAll.js +62 -0
- package/tests/focInd.js +99 -0
- package/tests/focOp.js +132 -0
- package/tests/hover.js +195 -0
- package/tests/ibm.js +89 -0
- package/tests/labClash.js +157 -0
- package/tests/linkUl.js +65 -0
- package/tests/menuNav.js +254 -0
- package/tests/motion.js +115 -0
- package/tests/radioSet.js +87 -0
- package/tests/role.js +164 -0
- package/tests/styleDiff.js +146 -0
- package/tests/tabNav.js +282 -0
- package/tests/wave.js +44 -0
- package/tests/zIndex.js +49 -0
- package/validation/batches/sample.json +13 -0
- package/validation/executors/sample.js +11 -0
- package/validation/scripts/app/sample.json +21 -0
- package/validation/scripts/test/bulk.json +39 -0
- package/validation/scripts/test/embAc.json +45 -0
- package/validation/scripts/test/focAll.json +59 -0
- package/validation/scripts/test/focInd.json +55 -0
- package/validation/scripts/test/focOp.json +53 -0
- package/validation/scripts/test/hover.json +47 -0
- package/validation/scripts/test/labClash.json +43 -0
- package/validation/scripts/test/linkUl.json +62 -0
- package/validation/scripts/test/menuNav.json +97 -0
- package/validation/scripts/test/motion.json +53 -0
- package/validation/scripts/test/radioSet.json +43 -0
- package/validation/scripts/test/role.json +42 -0
- package/validation/scripts/test/styleDiff.json +61 -0
- package/validation/scripts/test/tabNav.json +97 -0
- package/validation/scripts/test/zIndex.json +40 -0
- package/validation/targets/bulk/bad.html +48 -0
- package/validation/targets/bulk/good.html +15 -0
- package/validation/targets/embAc/bad.html +21 -0
- package/validation/targets/embAc/good.html +15 -0
- package/validation/targets/focAll/good.html +15 -0
- package/validation/targets/focAll/less.html +15 -0
- package/validation/targets/focAll/more.html +16 -0
- package/validation/targets/focInd/bad.html +31 -0
- package/validation/targets/focInd/good.html +22 -0
- package/validation/targets/focOp/bad.html +18 -0
- package/validation/targets/focOp/good.html +15 -0
- package/validation/targets/hover/bad.html +19 -0
- package/validation/targets/hover/good.html +15 -0
- package/validation/targets/labClash/bad.html +20 -0
- package/validation/targets/labClash/good.html +18 -0
- package/validation/targets/linkUl/bad.html +16 -0
- package/validation/targets/linkUl/good.html +30 -0
- package/validation/targets/linkUl/na.html +20 -0
- package/validation/targets/menuNav/bad.html +106 -0
- package/validation/targets/menuNav/bad.js +348 -0
- package/validation/targets/menuNav/good.html +106 -0
- package/validation/targets/menuNav/good.js +365 -0
- package/validation/targets/menuNav/style.css +22 -0
- package/validation/targets/motion/bad.css +15 -0
- package/validation/targets/motion/bad.html +16 -0
- package/validation/targets/motion/good.html +15 -0
- package/validation/targets/radioSet/bad.html +34 -0
- package/validation/targets/radioSet/good.html +27 -0
- package/validation/targets/role/bad.html +26 -0
- package/validation/targets/role/good.html +22 -0
- package/validation/targets/styleDiff/bad.html +35 -0
- package/validation/targets/styleDiff/good.html +36 -0
- package/validation/targets/tabNav/bad.html +51 -0
- package/validation/targets/tabNav/bad.js +35 -0
- package/validation/targets/tabNav/good.html +53 -0
- package/validation/targets/tabNav/good.js +83 -0
- package/validation/targets/tabNav/goodMoz.js +206 -0
- package/validation/targets/tabNav/style.css +34 -0
- package/validation/targets/zIndex/bad.html +17 -0
- package/validation/targets/zIndex/good.html +15 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Jonathan Pool
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
# testaro
|
|
2
|
+
|
|
3
|
+
Accessibility test automation
|
|
4
|
+
|
|
5
|
+
## Summary
|
|
6
|
+
|
|
7
|
+
Testaro is a collection of web accessibility tests.
|
|
8
|
+
|
|
9
|
+
The purpose of Testaro is to provide programmatic access to over 600 accessibility tests defined in several test packages and in Testaro itself.
|
|
10
|
+
|
|
11
|
+
Calling Testaro requires telling it which operations (including tests) to perform and which URLs to perform them on. Testaro outputs progress messages and a final report (in JSON format) to the standard output.
|
|
12
|
+
|
|
13
|
+
## Origin
|
|
14
|
+
|
|
15
|
+
Testaro is derived from [Autotest](https://github.com/jrpool/autotest).
|
|
16
|
+
|
|
17
|
+
Testaro omits some functionalities of Autotest, such as:
|
|
18
|
+
- tests producing results intended to be human-inspected
|
|
19
|
+
- previous versions of scoring algorithms
|
|
20
|
+
- file operations for score aggregation, report revision, and HTML reports
|
|
21
|
+
- a web user interface
|
|
22
|
+
|
|
23
|
+
## System requirements
|
|
24
|
+
|
|
25
|
+
Version 14 or later of [Node.js](https://nodejs.org/en/).
|
|
26
|
+
|
|
27
|
+
A file system with a directory that Testaro has permission to read and write in.
|
|
28
|
+
|
|
29
|
+
## Technologies
|
|
30
|
+
|
|
31
|
+
Testaro uses the [Playwright](https://playwright.dev/) package to launch browsers, perform user actions in them, and perform tests, and uses [pixelmatch](https://www.npmjs.com/package/pixelmatch) to measure motion.
|
|
32
|
+
|
|
33
|
+
Testaro combines its own collection of tests with tests made available in other packages and APIs:
|
|
34
|
+
- [accessibility-checker](https://www.npmjs.com/package/accessibility-checker) (the IBM Equal Access Accessibility Checker)
|
|
35
|
+
- [alfa](https://alfa.siteimprove.com/) (Siteimprove alfa)
|
|
36
|
+
- [Automated Accessibility Testing Tool](https://www.npmjs.com/package/aatt) (Paypal AATT, running HTML CodeSniffer)
|
|
37
|
+
- [axe-playwright](https://www.npmjs.com/package/axe-playwright) (Deque Axe-core)
|
|
38
|
+
- [WAVE API](https://wave.webaim.org/api/) (WebAIM WAVE)
|
|
39
|
+
|
|
40
|
+
As of March 2022, the counts of tests in the packages referenced above were:
|
|
41
|
+
- AATT: 98
|
|
42
|
+
- Alfa: 103
|
|
43
|
+
- Axe-core: 138
|
|
44
|
+
- Equal Access: 163
|
|
45
|
+
- WAVE: 110
|
|
46
|
+
- subtotal: 612
|
|
47
|
+
- Testaro tests: 15
|
|
48
|
+
- grand total: 627
|
|
49
|
+
|
|
50
|
+
## Code organization
|
|
51
|
+
|
|
52
|
+
The main directories containing code files are:
|
|
53
|
+
- package root: main code files
|
|
54
|
+
- `tests`: files containing the code defining particular tests
|
|
55
|
+
- `procs`: shared procedures
|
|
56
|
+
- `validation`: code and artifacts for the validation of tests
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
To install Testaro, enter `git clone https://github.com/jrpool/testaro.git`.
|
|
61
|
+
|
|
62
|
+
Then make its directory your working directory (`cd testaro`).
|
|
63
|
+
|
|
64
|
+
Before installing its dependencies, authorize yourself to install them. You presumably are already authorized to install dependencies from `https://npmjs.org`. But some of the Testaro dependencies are not there, but rather at `https://npm.pkg.github.com`. If you are not already authorized to install packages from that registry, authorize yourself as follows:
|
|
65
|
+
- Log in at [Github](https://github.com).
|
|
66
|
+
- From your avatar in the upper-right corner, choose “Settings”.
|
|
67
|
+
- In the left sidebar, choose “Developer settings”.
|
|
68
|
+
- In the left sidebar, choose “Personal access tokens”.
|
|
69
|
+
- Activate the button “Generate new token”.
|
|
70
|
+
- Give the new token a descriptive note.
|
|
71
|
+
- Select an expiration date.
|
|
72
|
+
- Check the checkbox `read:packages`.
|
|
73
|
+
- Activate the button “Generate token”.
|
|
74
|
+
- Copy the generated token (you can use the copy icon next to it).
|
|
75
|
+
- In your working directory (the root directory of the Testaro project), create a file named `.npmrc`.
|
|
76
|
+
- Populate the `.npmrc` file with the following statements, replacing `abc` with your Github username and `xyz` with the token that you copied:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
@siteimprove:registry=https://npm.pkg.github.com
|
|
80
|
+
//npm.pkg.github.com/:username=abc
|
|
81
|
+
//npm.pkg.github.com/:_authToken=xyz
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- Install the dependencies (`npm install` or `npm install --verbose`).
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
Successful installation depends on the scoped registry declaration for `@siteimprove` in the `.npmrc` file.
|
|
89
|
+
|
|
90
|
+
Use of WAVE requires you to have a WAVE API key (see the link above under “Technologies”).
|
|
91
|
+
|
|
92
|
+
## Specification
|
|
93
|
+
|
|
94
|
+
To use Testaro, you must specify what it should do. You do this by creating at least one script, and optionally one or more batches.
|
|
95
|
+
|
|
96
|
+
## Scripts
|
|
97
|
+
|
|
98
|
+
### Introduction
|
|
99
|
+
|
|
100
|
+
When you run Testaro, you provide a **script** to it. The script contains **commands**. Testaro performs those commands.
|
|
101
|
+
|
|
102
|
+
A script is a JSON file with the properties:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"what": "string: description of the script",
|
|
107
|
+
"strict": "boolean: whether redirections should be treated as failures",
|
|
108
|
+
"commands": "array of objects: the commands to be performed"
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Example
|
|
113
|
+
|
|
114
|
+
Here is an example of a script:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"what": "Test example.com with alfa",
|
|
119
|
+
"strict": true,
|
|
120
|
+
"commands": [
|
|
121
|
+
{
|
|
122
|
+
"type": "launch",
|
|
123
|
+
"which": "chromium",
|
|
124
|
+
"what": "Chromium browser"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"type": "url",
|
|
128
|
+
"which": "https://example.com/",
|
|
129
|
+
"what": "page with a few accessibility defects"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"type": "test",
|
|
133
|
+
"which": "alfa",
|
|
134
|
+
"what": "Siteimprove alfa package"
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This script tells Testaro to open a page in the Chromium browser, navigate to `example.com`, and perform the tests in the `alfa` package on that URL.
|
|
141
|
+
|
|
142
|
+
### Strictness
|
|
143
|
+
|
|
144
|
+
If the `strict` property is `true`, Testaro will accept redirections that add or subtract a final slash, but otherwise will treat redirections as failures.
|
|
145
|
+
|
|
146
|
+
### Commands
|
|
147
|
+
|
|
148
|
+
#### Commands in general
|
|
149
|
+
|
|
150
|
+
The `commands` property’s value is an array of commands, each formatted as an object.
|
|
151
|
+
|
|
152
|
+
Each command has a `type` property and optionally has a `name` property (used in branching, described below). It must or may have other properties, depending on the value of `type`.
|
|
153
|
+
|
|
154
|
+
#### Command sequence
|
|
155
|
+
|
|
156
|
+
The first two commands in any script have the types `launch` and `url`, respectively, as shown in the example above. They launch a browser and then use it to visit a URL. For example:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"type": "launch",
|
|
161
|
+
"which": "chromium",
|
|
162
|
+
"what": "Open a page in a Chromium browser"
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"type": "url",
|
|
169
|
+
"which": "https://en.wikipedia.org/wiki/Main_Page",
|
|
170
|
+
"what": "English Wikipedia home page"
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### Command types
|
|
175
|
+
|
|
176
|
+
The subsequent commands can tell Testaro to perform any of:
|
|
177
|
+
- moves (clicks, text inputs, hovers, etc.)
|
|
178
|
+
- navigations (browser launches, visits to URLs, waits for page conditions, etc.)
|
|
179
|
+
- alterations (changes to the page)
|
|
180
|
+
- tests (whether in dependency packages or defined within Testaro)
|
|
181
|
+
- scoring (aggregating test results into total scores)
|
|
182
|
+
- branching (continuing from a command other than the next one)
|
|
183
|
+
|
|
184
|
+
##### Moves
|
|
185
|
+
|
|
186
|
+
An example of a **move** is:
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"type": "radio",
|
|
191
|
+
"which": "No",
|
|
192
|
+
"index": 2,
|
|
193
|
+
"what": "No, I am not a smoker"
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
In this case, Testaro checks the third radio button whose text includes the string “No” (case-insensitively).
|
|
198
|
+
|
|
199
|
+
In identifying the target element for a move, Testaro matches the `which` property with the texts of the elements of the applicable type (such as radio buttons). It defines the text of an `input` element as the concatenated texts of its implicit label or explicit labels, if any, plus, for the first input in a `fieldset` element, the text content of the `legend` element of that `fieldset` element. For any other element, Testaro defines the text as the text content of the element.
|
|
200
|
+
|
|
201
|
+
When multiple elements of the same type have indistinguishable texts, you can include an `index` property to specify the index of the target element, among all those that will match.
|
|
202
|
+
|
|
203
|
+
##### Navigations
|
|
204
|
+
|
|
205
|
+
An example of a **navigation** is the command of type `url` above.
|
|
206
|
+
|
|
207
|
+
Once you have included a `url` command in a script, you do not need to add more `url` commands unless you want the browser to visit a different URL.
|
|
208
|
+
|
|
209
|
+
However, some tests modify web pages. In those cases, Testaro inserts additional `url` commands into the `script` property of the `options` object, after those tests, to ensure that changes made by one test do not affect subsequent acts.
|
|
210
|
+
|
|
211
|
+
Another navigation example is:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"type": "wait",
|
|
216
|
+
"which": "travel",
|
|
217
|
+
"what": "title"
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
In this case, Testaro waits until the page title contains the string “travel” (case-insensitively).
|
|
222
|
+
|
|
223
|
+
##### Alterations
|
|
224
|
+
|
|
225
|
+
An example of an **alteration** is:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"type": "reveal",
|
|
230
|
+
"what": "make everything visible"
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
This command causes Testaro to alter the `display` and `visibility` style properties of all elements, where necessary, so those properties do not make any element invisible.
|
|
235
|
+
|
|
236
|
+
##### Tests
|
|
237
|
+
|
|
238
|
+
###### Introduction
|
|
239
|
+
|
|
240
|
+
The possible commands of type `test` are enumerated in the `tests` object defined in the `index.js` file.
|
|
241
|
+
|
|
242
|
+
###### Examples
|
|
243
|
+
|
|
244
|
+
An example of a **packaged test** is:
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"type": "test",
|
|
249
|
+
"which": "wave",
|
|
250
|
+
"reportType": 1,
|
|
251
|
+
"what": "WAVE summary"
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
In this case, Testaro runs the WAVE test with report type 1.
|
|
256
|
+
|
|
257
|
+
An example of a **Testaro-defined** test is:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"type": "test",
|
|
262
|
+
"which": "motion",
|
|
263
|
+
"delay": 1500,
|
|
264
|
+
"interval": 2000,
|
|
265
|
+
"count": 5,
|
|
266
|
+
"what": "test for motion on the page"
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
In this case, Testaro runs the `motion` test with the specified parameters.
|
|
271
|
+
|
|
272
|
+
###### Validation
|
|
273
|
+
|
|
274
|
+
For each of the non-package tests defined in Testaro, a validating script and some files tested by it are also provided. They are in the `validation` directory. A module that you can use to execute those scripts is also there, named `validator.js`.
|
|
275
|
+
|
|
276
|
+
For example, to execute the `focOp.json` validation script, you can enter `node validation/validator focOp`. The `validator.js` module outputs the report to the console.
|
|
277
|
+
|
|
278
|
+
##### Scoring
|
|
279
|
+
|
|
280
|
+
An example of a **scoring** command is:
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"type": "score",
|
|
285
|
+
"which": "asp09",
|
|
286
|
+
"what": "5 packages and 16 custom tests, with duplication discounts"
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
In this case, Testaro executes the procedure specified in the `asp09` score proc (in the `procs/score` directory) to compute a total score for the script or (if there is a batch) the host. The proc is a JavaScript module whose `scorer` function returns an object containing a total score and the itemized scores that yield the total.
|
|
291
|
+
|
|
292
|
+
The `scorer` function inspects the script report to find the required data, applies specific weights and formulas to yield the itemized scores, and combines the itemized scores to yield the total score.
|
|
293
|
+
|
|
294
|
+
The data for scores can include not only test results, but also log statistics. Testaro includes in each report the properties:
|
|
295
|
+
- `logCount`: how many log items the browser generated
|
|
296
|
+
- `logSize`: how large the log items were in the aggregate, in characters
|
|
297
|
+
- `prohibitedCount`: how many log items contain (case-insensitively) `403` and `status`, or `prohibited`
|
|
298
|
+
- `visitTimeoutCount`: how many times an attempt to visit a URL timed out
|
|
299
|
+
- `visitRejectionCount`: how many times a URL visit got an HTTP status other than 200 or 304
|
|
300
|
+
|
|
301
|
+
A good score proc takes account of duplications between test packages: two or more packages that discover the same accessibility defects. Score procs can apply discounts to reflect duplications between test packages, so that, if two or more packages discover the same defect, the defect will not be overweighted.
|
|
302
|
+
|
|
303
|
+
The procedures in the `scoring` directory have produced data there that score procs can use for the calibration of discounts.
|
|
304
|
+
|
|
305
|
+
Some documents are implemented in such a way that some tests are prevented from being conducted on them. When that occurs, the score proc can **infer** a score for that test.
|
|
306
|
+
|
|
307
|
+
##### Branching
|
|
308
|
+
|
|
309
|
+
An example of a **branching** command is:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"type": "next",
|
|
314
|
+
"if": ["totals.invalid", ">", 0],
|
|
315
|
+
"jump": -4,
|
|
316
|
+
"what": "redo search if any invalid elements"
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
This command checks the result of the previous act to determine whether its `result.totals.invalid` property has a positive value. If so, it changes the next command to be performed, specifying the command 4 commands before this one.
|
|
321
|
+
|
|
322
|
+
A `next`-type command can use a `next` property instead of a `jump` property. The value of the `next` property is a command name. It tells Testaro to continue performing commands starting with the command having that value as the value of its `name` property.
|
|
323
|
+
|
|
324
|
+
#### Commands file
|
|
325
|
+
|
|
326
|
+
##### Introduction
|
|
327
|
+
|
|
328
|
+
The `commands.js` file contains rules governing commands. The rules determine whether a command is valid.
|
|
329
|
+
|
|
330
|
+
##### Rule format
|
|
331
|
+
|
|
332
|
+
The rules in `commands.js` are organized into two objects, `etc` and `tests`. The `etc` object contains rules for commands of all types. The `tests` object contains additional rules that apply to some commands of type `test`, depending on the values of their `which` properties, namely which tests they perform.
|
|
333
|
+
|
|
334
|
+
Here is an example of a command:
|
|
335
|
+
|
|
336
|
+
```json
|
|
337
|
+
{
|
|
338
|
+
"type": "link",
|
|
339
|
+
"which": "warming",
|
|
340
|
+
"what": "article on climate change"
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
And here is the applicable property of the `etc` object in `commmands.js`:
|
|
345
|
+
|
|
346
|
+
```js
|
|
347
|
+
link: [
|
|
348
|
+
'Click a link',
|
|
349
|
+
{
|
|
350
|
+
which: [true, 'string', 'hasLength', 'substring of the link text'],
|
|
351
|
+
what: [false, 'string', 'hasLength', 'comment']
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The rule is an array with two elements: a string ('Click a link') describing the command and an object containing requirements for any command of type `link`.
|
|
357
|
+
|
|
358
|
+
The requirement `which: [true, 'string', 'hasLength', 'substring of the link text']` specifies what is required for the `which` property of a `link`-type command. The requirement is an array.
|
|
359
|
+
|
|
360
|
+
In most cases, the array has length 4:
|
|
361
|
+
- 0. Is the property (here `which`) required (`true` or `false`)? The value `true` here means that every `link`-type command **must** contain a `which` property.
|
|
362
|
+
- 1. What format must the property value have (`'string'`, `'array'`, `'boolean'`, or `'number'`)?
|
|
363
|
+
- 2. What other validity criterion applies (if any)? (Empty string if none.) The `hasLength` criterion means that the string must be at least 1 character long.
|
|
364
|
+
- 3. Description of the property. Here, the value of `which` is some substring of the text content of the link that is to be clicked. Thus, a `link` command tells Testaro to find the first link whose text content has this substring and click it.
|
|
365
|
+
|
|
366
|
+
The validity criterion named in item 2 may be any of these:
|
|
367
|
+
- `'hasLength'`: is not a blank string
|
|
368
|
+
- `'isURL`': is a string starting with `http`, `https`, or `file`, then `://`, then ending with 1 or more non-whitespace characters
|
|
369
|
+
- `'isBrowserType'`: is `'chromium'`, `'firefox'`, or `'webkit'`
|
|
370
|
+
- `'isFocusable'`: is `'a'`, `'button'`, `'input'`, `'select'`, or `'option'`
|
|
371
|
+
- `'isState'`: is `'loaded'` or `'idle'`
|
|
372
|
+
- `'isTest'`: is the name of a test
|
|
373
|
+
- `'isWaitable'`: is `'url'`, `'title'`, or `'body'`
|
|
374
|
+
- `'areStrings'`: is an array of strings
|
|
375
|
+
|
|
376
|
+
When `commands.js` specifies a `withItems` requirement for a `test`-type command, that requirement is an array of length 2, and is always `[true, 'boolean']`. That means that this `test`-type command must have a `withItems` property, whose value must be `true` or `false`. That property tells Testaro whether to itemize the results of that test.
|
|
377
|
+
|
|
378
|
+
Any `test` command can also (in addition to the requirements in `commands.js`) contain an `expect` requirement. If it does, that requirement has a different format: an array of any non-0 length. The items in that array specify expectations about the results of the test.
|
|
379
|
+
|
|
380
|
+
For example, a `test` command might have this `expect` property:
|
|
381
|
+
|
|
382
|
+
```json
|
|
383
|
+
"expect": [
|
|
384
|
+
["total.links", "=", 5],
|
|
385
|
+
["total.links.underlined", "<", 6],
|
|
386
|
+
["total.links.outlined"],
|
|
387
|
+
["docLang", "!", "es-ES]
|
|
388
|
+
]
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
That would state the expectation that the `result` property of the `acts` item for that test in the report will have a `total.links` property with the value 5, a `total.links.underlined` property with a value less than 6, **no** `total.links.outlined` property, and a `docLang` property with a value different from `es-ES`.
|
|
392
|
+
|
|
393
|
+
The second item in each array, if there are 3 items in the array, is an operator, drawn from:
|
|
394
|
+
- `<`: less than
|
|
395
|
+
- `=`: equal to
|
|
396
|
+
- `>`: greater than
|
|
397
|
+
- `!`: unequal to
|
|
398
|
+
|
|
399
|
+
## Batches
|
|
400
|
+
|
|
401
|
+
There are two ways to use a script to give instructions to Testaro:
|
|
402
|
+
- The script can be the complete specification of the job.
|
|
403
|
+
- The script can specify the operations to perform, and a _batch_ can specify which pages to perform them on.
|
|
404
|
+
|
|
405
|
+
A batch is a JSON file with this format:
|
|
406
|
+
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"what": "Accessibility standards",
|
|
410
|
+
"hosts": [
|
|
411
|
+
{
|
|
412
|
+
"which": "https://www.w3.org/TR/WCAG21/",
|
|
413
|
+
"what": "WCAG 2.1"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"which": "https://www.w3.org/WAI/standards-guidelines/aria/",
|
|
417
|
+
"what": "W3C WAI-ARIA"
|
|
418
|
+
}
|
|
419
|
+
]
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
When you combine a script with a batch, Testaro performs the script, replacing the `which` and `what` properties of all `url` commands with the values in the first object in the `hosts` array, then again with the values in the second object, and so on. Those replacements also occur in the inserted extra `url` commands mentioned above.
|
|
424
|
+
|
|
425
|
+
A batch offers an efficient way to perform a uniform set of commands on every host in a set of hosts. In this way you can run the same set of tests on multiple web pages.
|
|
426
|
+
|
|
427
|
+
A no-batch script offers a way to carry out a complex operation, which can include navigating from one host to another, which is not possible with a batch. Any `url` commands are performed as-is, without changes to their URLs.
|
|
428
|
+
|
|
429
|
+
## Reports
|
|
430
|
+
|
|
431
|
+
Testaro writes reports as files in JSON format. They contain detailed results.
|
|
432
|
+
|
|
433
|
+
Testaro also writes to standard output a list of the names of the files containing the reports.
|
|
434
|
+
|
|
435
|
+
## Execution
|
|
436
|
+
|
|
437
|
+
### Invocation
|
|
438
|
+
|
|
439
|
+
To run Testaro, create a Node.js file like this:
|
|
440
|
+
|
|
441
|
+
```javascript
|
|
442
|
+
const options = {
|
|
443
|
+
reports: 'path/to/reports/directory',
|
|
444
|
+
script: 'path/to/script/file.json',
|
|
445
|
+
batch: 'path/to/batch/file.json'
|
|
446
|
+
};
|
|
447
|
+
const {handleRequest} = require('path/to/index.js');
|
|
448
|
+
handleRequest(options);
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
The `batch` option is optional. If there is no batch, it is omitted.
|
|
452
|
+
|
|
453
|
+
The paths can be absolute or relative. If they are relative, they are relative to the file.
|
|
454
|
+
|
|
455
|
+
If the file name is `runTestaro.js`, execute it with the statement `node runTestaro`.
|
|
456
|
+
|
|
457
|
+
### Environment variables
|
|
458
|
+
|
|
459
|
+
If a `wave` test is included in the script, an environment variable named `WAVE_KEY` must exist, with your WAVE API key as its value.
|
|
460
|
+
|
|
461
|
+
Before executing a Testaro script, you can also set the environment variables `DEBUG` and/or `WAITS`. The effects of these variables are described in the `index.js` file.
|
|
462
|
+
|
|
463
|
+
## Contribution
|
|
464
|
+
|
|
465
|
+
You can define additional Testaro commands and functionality. Contributions are welcome.
|
|
466
|
+
|
|
467
|
+
## Accessibility principles
|
|
468
|
+
|
|
469
|
+
The rationales motivating the Testaro-defined tests and scoring procs can be found in comments within the files of those tests and procs, in the `tests` and `procs/score` directories. Unavoidably, each test is opinionated. Testaro itself, however, can accommodate other tests representing different opinions. Testaro is intended to be neutral with respect to questions such as the criteria for accessibility, the severities of accessibility issues, whether accessibility should be understcood as binary or graded, and the distinction between usability and accessibility.
|
|
470
|
+
|
|
471
|
+
### Future work
|
|
472
|
+
|
|
473
|
+
Further development is contemplated, is taking place, or is welcomed, on:
|
|
474
|
+
- links with href="#"
|
|
475
|
+
- links and buttons styled non-distinguishably
|
|
476
|
+
- first focused element not first focusable element in DOM
|
|
477
|
+
- never-visible skip links
|
|
478
|
+
- buttons with no text content
|
|
479
|
+
- modal dialogs
|
|
480
|
+
- autocomplete attributes
|
|
481
|
+
|
|
482
|
+
Additional test packages may be integratable into Testaro. The [`bbc-a11y`](https://github.com/bbc/bbc-a11y) package has been considered, but it has not been updated since 2018 and has vulnerable dependencies.
|
|
483
|
+
|
|
484
|
+
## Testing challenges
|
|
485
|
+
|
|
486
|
+
### Activation
|
|
487
|
+
|
|
488
|
+
Testing to determine what happens when a control or link is activated is straightforward, except in the context of a comprehensive set of tests of a single page. There, activating a control or link can change the page or navigate away from it, interfering with the remaining planned tests of the page.
|
|
489
|
+
|
|
490
|
+
The Playwright “Receives Events” actionability check does **not** check whether an event is dispatched on an element. It checks only whether a click on the location of the element makes the element the target of that click, rather than some other element occupying the same location.
|
|
491
|
+
|
|
492
|
+
### Test-package duplication
|
|
493
|
+
|
|
494
|
+
Test packages sometimes do redundant testing, in that two or more packages test for the same issues. But such duplications are not necessarily perfect. Therefore, the scoring procs currently made available by Testaro do not select a single package to test for a single issue. Instead, they allow all packages to test for all the issues they can test for, but decrease the weights placed on issues that multiple packages test for. The more packages test for an issue, the smaller the weight placed on each package’s finding of that issue.
|
|
495
|
+
|
|
496
|
+
## Repository exclusions
|
|
497
|
+
|
|
498
|
+
The files in the `temp` directory are presumed ephemeral and are not tracked by `git`. When tests require temporary files to be written, Testaro writes them there.
|
|
499
|
+
|
|
500
|
+
## Etymology
|
|
501
|
+
|
|
502
|
+
“Testaro” means “collection of tests” in Esperanto.
|