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.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +502 -0
  3. package/aceconfig.js +7 -0
  4. package/commands.js +249 -0
  5. package/index.js +1248 -0
  6. package/package.json +39 -0
  7. package/procs/score/asp09.js +555 -0
  8. package/procs/test/allText.js +76 -0
  9. package/procs/test/allVis.js +17 -0
  10. package/procs/test/linksByType.js +90 -0
  11. package/procs/test/textOf.txt +73 -0
  12. package/scoring/correlation.js +74 -0
  13. package/scoring/correlations.json +327 -0
  14. package/scoring/data.json +26021 -0
  15. package/scoring/dupCounts.js +39 -0
  16. package/scoring/dupCounts.json +112 -0
  17. package/scoring/duplications.json +253 -0
  18. package/scoring/issues.json +304 -0
  19. package/scoring/packageData.js +171 -0
  20. package/scoring/packageIssues.js +34 -0
  21. package/scoring/rulesetData.json +15 -0
  22. package/tests/aatt.js +64 -0
  23. package/tests/alfa.js +107 -0
  24. package/tests/axe.js +109 -0
  25. package/tests/bulk.js +21 -0
  26. package/tests/embAc.js +36 -0
  27. package/tests/focAll.js +62 -0
  28. package/tests/focInd.js +99 -0
  29. package/tests/focOp.js +132 -0
  30. package/tests/hover.js +195 -0
  31. package/tests/ibm.js +89 -0
  32. package/tests/labClash.js +157 -0
  33. package/tests/linkUl.js +65 -0
  34. package/tests/menuNav.js +254 -0
  35. package/tests/motion.js +115 -0
  36. package/tests/radioSet.js +87 -0
  37. package/tests/role.js +164 -0
  38. package/tests/styleDiff.js +146 -0
  39. package/tests/tabNav.js +282 -0
  40. package/tests/wave.js +44 -0
  41. package/tests/zIndex.js +49 -0
  42. package/validation/batches/sample.json +13 -0
  43. package/validation/executors/sample.js +11 -0
  44. package/validation/scripts/app/sample.json +21 -0
  45. package/validation/scripts/test/bulk.json +39 -0
  46. package/validation/scripts/test/embAc.json +45 -0
  47. package/validation/scripts/test/focAll.json +59 -0
  48. package/validation/scripts/test/focInd.json +55 -0
  49. package/validation/scripts/test/focOp.json +53 -0
  50. package/validation/scripts/test/hover.json +47 -0
  51. package/validation/scripts/test/labClash.json +43 -0
  52. package/validation/scripts/test/linkUl.json +62 -0
  53. package/validation/scripts/test/menuNav.json +97 -0
  54. package/validation/scripts/test/motion.json +53 -0
  55. package/validation/scripts/test/radioSet.json +43 -0
  56. package/validation/scripts/test/role.json +42 -0
  57. package/validation/scripts/test/styleDiff.json +61 -0
  58. package/validation/scripts/test/tabNav.json +97 -0
  59. package/validation/scripts/test/zIndex.json +40 -0
  60. package/validation/targets/bulk/bad.html +48 -0
  61. package/validation/targets/bulk/good.html +15 -0
  62. package/validation/targets/embAc/bad.html +21 -0
  63. package/validation/targets/embAc/good.html +15 -0
  64. package/validation/targets/focAll/good.html +15 -0
  65. package/validation/targets/focAll/less.html +15 -0
  66. package/validation/targets/focAll/more.html +16 -0
  67. package/validation/targets/focInd/bad.html +31 -0
  68. package/validation/targets/focInd/good.html +22 -0
  69. package/validation/targets/focOp/bad.html +18 -0
  70. package/validation/targets/focOp/good.html +15 -0
  71. package/validation/targets/hover/bad.html +19 -0
  72. package/validation/targets/hover/good.html +15 -0
  73. package/validation/targets/labClash/bad.html +20 -0
  74. package/validation/targets/labClash/good.html +18 -0
  75. package/validation/targets/linkUl/bad.html +16 -0
  76. package/validation/targets/linkUl/good.html +30 -0
  77. package/validation/targets/linkUl/na.html +20 -0
  78. package/validation/targets/menuNav/bad.html +106 -0
  79. package/validation/targets/menuNav/bad.js +348 -0
  80. package/validation/targets/menuNav/good.html +106 -0
  81. package/validation/targets/menuNav/good.js +365 -0
  82. package/validation/targets/menuNav/style.css +22 -0
  83. package/validation/targets/motion/bad.css +15 -0
  84. package/validation/targets/motion/bad.html +16 -0
  85. package/validation/targets/motion/good.html +15 -0
  86. package/validation/targets/radioSet/bad.html +34 -0
  87. package/validation/targets/radioSet/good.html +27 -0
  88. package/validation/targets/role/bad.html +26 -0
  89. package/validation/targets/role/good.html +22 -0
  90. package/validation/targets/styleDiff/bad.html +35 -0
  91. package/validation/targets/styleDiff/good.html +36 -0
  92. package/validation/targets/tabNav/bad.html +51 -0
  93. package/validation/targets/tabNav/bad.js +35 -0
  94. package/validation/targets/tabNav/good.html +53 -0
  95. package/validation/targets/tabNav/good.js +83 -0
  96. package/validation/targets/tabNav/goodMoz.js +206 -0
  97. package/validation/targets/tabNav/style.css +34 -0
  98. package/validation/targets/zIndex/bad.html +17 -0
  99. 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.
package/aceconfig.js ADDED
@@ -0,0 +1,7 @@
1
+ module.exports = {
2
+ reportLevels: [
3
+ 'violation',
4
+ 'recommendation'
5
+ ],
6
+ outputFolder: 'temp/ibm'
7
+ };