testaro 5.19.0 → 6.0.1
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/README-mixed.md +707 -0
- package/README.md +95 -115
- package/commands.js +19 -19
- package/high.js +63 -4
- package/package.json +1 -1
- package/run.js +1 -1
- package/{runHost.js → runScript.js} +9 -12
- package/samples/{scripts/simple.json → simple.json} +1 -0
- package/samples/{scripts/tp18.json → tp18.json} +3 -3
- package/tests/titledEl.js +2 -2
- package/validation/executors/debug.js +2 -2
- package/validation/executors/high.js +57 -0
- package/validation/executors/low.js +2 -2
- package/validation/executors/tenon.js +2 -2
- package/validation/executors/test.js +2 -2
- package/validation/executors/tests.js +2 -2
- package/watch.js +83 -124
- package/batchify.js +0 -25
- package/create.js +0 -172
- package/samples/batches/eurail.json +0 -11
- package/samples/batches/railpass.json +0 -11
- package/samples/batches/weborgs.json +0 -16
- package/samples/scripts/tp15.json +0 -173
- package/samples/scripts/tp16.json +0 -211
- package/validation/executors/high1.js +0 -32
- package/validation/executors/high2.js +0 -37
package/README.md
CHANGED
|
@@ -8,9 +8,22 @@ Testaro is a collection of collections of web accessibility tests.
|
|
|
8
8
|
|
|
9
9
|
The purpose of Testaro is to provide programmatic access to accessibility tests defined in several test packages and in Testaro itself.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Testaro launches and controls web browsers, performing operations, conducting tests, and recording results.
|
|
12
|
+
|
|
13
|
+
Testaro is designed to be a workstation-based agent. Testaro can be installed on a workstation running under OS X or Windows, or potentially Ubuntu Linux. The software that uses Testaro can be installed on the same workstation or any other workstation or server. Such other software can perform functions that do not require workstation features, such as:
|
|
14
|
+
- Test scheduling
|
|
15
|
+
- Monitoring
|
|
16
|
+
- Management of clusters of workstations sharing workloads
|
|
17
|
+
- Allocation of responsibilities among workstations
|
|
18
|
+
- Receiving and fulfilling requests from users for testing
|
|
19
|
+
- Converting user specifications into instructions for workstations
|
|
20
|
+
- Allocating testing responsibilities to human testers
|
|
21
|
+
- Combining reports from workstations and human testers
|
|
22
|
+
- Analyzing and summarizing test results
|
|
23
|
+
- Sending notifications
|
|
24
|
+
- Publishing reports
|
|
25
|
+
|
|
26
|
+
One software product that performs some such functions is [Testilo](https://www.npmjs.com/package/testilo).
|
|
14
27
|
|
|
15
28
|
## Dependencies
|
|
16
29
|
|
|
@@ -58,6 +71,10 @@ The main directories containing code files are:
|
|
|
58
71
|
- `procs`: shared procedures
|
|
59
72
|
- `validation`: code and artifacts for the validation of Testaro
|
|
60
73
|
|
|
74
|
+
## System requirements
|
|
75
|
+
|
|
76
|
+
Version 14 or later of [Node.js](https://nodejs.org/en/).
|
|
77
|
+
|
|
61
78
|
## Installation
|
|
62
79
|
|
|
63
80
|
Some of the dependencies of Testaro are published as Github packages. Installing Testaro therefore requires you to be authorized to read Github packages. If you do not yet have that authorization, you can give it to yourself as follows:
|
|
@@ -82,27 +99,27 @@ Some of the dependencies of Testaro are published as Github packages. Installing
|
|
|
82
99
|
|
|
83
100
|
Once you have done that, you can install Testaro as you would install any `npm` package.
|
|
84
101
|
|
|
85
|
-
However, if the Playwright dependency is ever updated to a newer version, you must also reinstall its
|
|
102
|
+
However, if the Playwright dependency is ever updated to a newer version, you must also reinstall its browsers by executing the statement `npx playwright install`.
|
|
86
103
|
|
|
87
104
|
## Payment
|
|
88
105
|
|
|
89
106
|
All of the tests that Testaro can perform are free of cost, except those in the Tenon and WAVE packages. The owner of each of those packages gives new registrants a free allowance of credits before it becomes necessary to pay for use of the API of the package. The required environment variables for authentication and payment are described below under “Environment variables”.
|
|
90
107
|
|
|
91
|
-
##
|
|
108
|
+
## Jobs
|
|
92
109
|
|
|
93
|
-
|
|
110
|
+
A request to a workstation to do some work is a _job_.
|
|
94
111
|
|
|
95
112
|
## Scripts
|
|
96
113
|
|
|
97
114
|
### Introduction
|
|
98
115
|
|
|
99
|
-
|
|
116
|
+
A file containing specifications for a job is a _script_. Thus, creating a job means asking a workstation to have Testaro run a particular script.
|
|
100
117
|
|
|
101
|
-
|
|
118
|
+
Every script is a JSON-format file representing a JavaScript object. Its properties are:
|
|
102
119
|
|
|
103
120
|
```json
|
|
104
121
|
{
|
|
105
|
-
"id": "string consisting of
|
|
122
|
+
"id": "string consisting of alphanumeric ASCII characters and hyphen-minus (-)",
|
|
106
123
|
"what": "string: description of the script",
|
|
107
124
|
"strict": "boolean: whether redirections should be treated as failures",
|
|
108
125
|
"timeLimit": "number: limit in seconds on the execution of this script",
|
|
@@ -112,6 +129,10 @@ A script is a JSON file with the properties:
|
|
|
112
129
|
|
|
113
130
|
The `timeLimit` property is optional. If it is omitted, a default of 300 seconds (5 minutes) is set.
|
|
114
131
|
|
|
132
|
+
### Processing
|
|
133
|
+
|
|
134
|
+
When Testaro starts performing a job, it initializes a report. The report is a JavaScript object. It has a `script` property, which is a copy of the script, and an `acts` property, which is a copy of the `commands` property of the script. Initially, the `commands` and `acts` arrays are identical. During processing, Testaro adds content to the `acts` array. In the resulting report, the `commands` array shows what you asked Testaro to do, and the `acts` array shows what Testaro actually did and the results. Testaro also gives values to some other properties describing the job session.
|
|
135
|
+
|
|
115
136
|
### Example
|
|
116
137
|
|
|
117
138
|
Here is an example of a script:
|
|
@@ -142,7 +163,7 @@ Here is an example of a script:
|
|
|
142
163
|
}
|
|
143
164
|
```
|
|
144
165
|
|
|
145
|
-
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.
|
|
166
|
+
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, within 65 seconds.
|
|
146
167
|
|
|
147
168
|
### Strictness
|
|
148
169
|
|
|
@@ -152,29 +173,13 @@ If the `strict` property is `true`, Testaro will accept redirections that add or
|
|
|
152
173
|
|
|
153
174
|
#### Introduction
|
|
154
175
|
|
|
155
|
-
The `commands` property’s value is an array of command objects.
|
|
176
|
+
The `commands` property’s value is an array of commands (command objects).
|
|
156
177
|
|
|
157
178
|
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`.
|
|
158
179
|
|
|
159
180
|
#### Command sequence
|
|
160
181
|
|
|
161
|
-
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.
|
|
162
|
-
|
|
163
|
-
```json
|
|
164
|
-
{
|
|
165
|
-
"type": "launch",
|
|
166
|
-
"which": "chromium",
|
|
167
|
-
"what": "Open a page in a Chromium browser"
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
```json
|
|
172
|
-
{
|
|
173
|
-
"type": "url",
|
|
174
|
-
"which": "https://en.wikipedia.org/wiki/Main_Page",
|
|
175
|
-
"what": "English Wikipedia home page"
|
|
176
|
-
}
|
|
177
|
-
```
|
|
182
|
+
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.
|
|
178
183
|
|
|
179
184
|
#### Command types
|
|
180
185
|
|
|
@@ -210,7 +215,7 @@ An example of a **navigation** is the command of type `url` above.
|
|
|
210
215
|
|
|
211
216
|
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.
|
|
212
217
|
|
|
213
|
-
However, some tests modify web pages. In those cases, Testaro inserts additional `url`
|
|
218
|
+
However, some tests modify web pages. In those cases, Testaro inserts additional `url` acts into the `acts` array, after those tests, to ensure that changes made by one test do not affect subsequent acts.
|
|
214
219
|
|
|
215
220
|
Another navigation example is:
|
|
216
221
|
|
|
@@ -241,8 +246,6 @@ This command causes Testaro to alter the `display` and `visibility` style proper
|
|
|
241
246
|
|
|
242
247
|
###### Introduction
|
|
243
248
|
|
|
244
|
-
The possible commands of type `test` are enumerated in the `tests` object defined in the `index.js` file.
|
|
245
|
-
|
|
246
249
|
A test performs operations and reports results. The results may or may not directly indicate that a page passes or fails requirements. Typically, accessibility tests report successes and failures. But a test in Testaro is defined less restrictively, so it can report any results. As one example, the Testaro `elements` test reports facts about certain elements on a page, without asserting that those facts are successes or failures.
|
|
247
250
|
|
|
248
251
|
The term “test” has two meanings for Testaro:
|
|
@@ -251,6 +254,28 @@ The term “test” has two meanings for Testaro:
|
|
|
251
254
|
|
|
252
255
|
Thus, if a command of type `test` runs Continuum, Continuum performs multiple tests and reports their results.
|
|
253
256
|
|
|
257
|
+
###### Configuration
|
|
258
|
+
|
|
259
|
+
Every test in Testaro must have:
|
|
260
|
+
- a property in the `tests` object defined in the `run.js` file, where the property name is the name of the test and the value is a description of the test
|
|
261
|
+
- a `.js` file in the `tests` directory, whose name base is the name of the test
|
|
262
|
+
|
|
263
|
+
The `commands.js` file (described in detail below) contains this specification for any `test` command:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
test: [
|
|
267
|
+
'Perform a test',
|
|
268
|
+
{
|
|
269
|
+
which: [true, 'string', 'isTest', 'test name'],
|
|
270
|
+
what: [false, 'string', 'hasLength', 'comment']
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
That means that a test (i.e. a command with a `type` property having the value `'test'`) must have a string-valued `which` property and may optionally have a string-valued `what` property.
|
|
276
|
+
|
|
277
|
+
If a particular test either must have or may have any other properties, those properties must be specified in the `tests` property in `commands.js`.
|
|
278
|
+
|
|
254
279
|
###### Examples
|
|
255
280
|
|
|
256
281
|
An example of a **packaged test** is:
|
|
@@ -321,6 +346,8 @@ In case you want to perform more than one `tenon` test with the same script, you
|
|
|
321
346
|
|
|
322
347
|
Tenon recommends giving it a public URL rather than giving it the content of a page, if possible. So, it is best to give the `withNewContent` property of the `tenonRequest` command the value `true`, unless the page is not public.
|
|
323
348
|
|
|
349
|
+
If a `tenon` test is included in a script, environment variables named `TENON_USER` and `TENON_PASSWORD` must exist, with your Tenon username and password, respectively, as their values. You can obtain those from [Tenon](https://tenon.io/documentation/overview).
|
|
350
|
+
|
|
324
351
|
###### Continuum
|
|
325
352
|
|
|
326
353
|
The `continuum` test makes use of the files in the `continuum` directory. The test inserts the contents of all three files into the page as scripts and then uses them to perform the tests of the Continuum package.
|
|
@@ -359,6 +386,10 @@ The changes in `htmlcs/HTMLCS.js` are:
|
|
|
359
386
|
> );
|
|
360
387
|
```
|
|
361
388
|
|
|
389
|
+
###### WAVE
|
|
390
|
+
|
|
391
|
+
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. You can get it from [WebAIM](https://wave.webaim.org/api/).
|
|
392
|
+
|
|
362
393
|
###### BBC Accessibility Standards Checker
|
|
363
394
|
|
|
364
395
|
The BBC Accessibility Standards Checker has obsolete dependencies with security vulnerabilities. Therefore, it is not used as a dependency of Testaro. Instead, 6 of its tests are reimplemented, in some cases with revisions, as Testaro tests. They are drawn from the 18 automated tests of the Checker. The other 12 tests were found too duplicative of other tests to justify reimplementation.
|
|
@@ -420,7 +451,7 @@ In most cases, the array has length 4:
|
|
|
420
451
|
- 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.
|
|
421
452
|
- 1. What format must the property value have (`'string'`, `'array'`, `'boolean'`, or `'number'`)?
|
|
422
453
|
- 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.
|
|
423
|
-
- 3. Description of the property.
|
|
454
|
+
- 3. Description of the property. In this example, the description says that the value of `which` must be a 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.
|
|
424
455
|
|
|
425
456
|
The validity criterion named in item 2 may be any of these:
|
|
426
457
|
- `'hasLength'`: is not a blank string
|
|
@@ -432,9 +463,7 @@ The validity criterion named in item 2 may be any of these:
|
|
|
432
463
|
- `'isWaitable'`: is `'url'`, `'title'`, or `'body'`
|
|
433
464
|
- `'areStrings'`: is an array of strings
|
|
434
465
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
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.
|
|
466
|
+
Any `test` command can also (in addition to the requirements in `commands.js`) contain an `expect` property. If it does, the value of that property must be an array of arrays. Each array specifies expectations about the results of the test.
|
|
438
467
|
|
|
439
468
|
For example, a `test` command might have this `expect` property:
|
|
440
469
|
|
|
@@ -464,33 +493,9 @@ The third item in each array, if there are 3 items in the array, is the criterio
|
|
|
464
493
|
|
|
465
494
|
A typical use for an `expect` property is checking the correctness of a Testaro test. Thus, the validation scripts in the `validation/tests/scripts` directory all contain `test` commands with `expect` properties. See the “Validation” section below.
|
|
466
495
|
|
|
467
|
-
## Batches
|
|
468
|
-
|
|
469
|
-
You may wish to have Testaro perform the same sequence of tests on multiple web pages. In that case, you can create a _batch_, with the following structure:
|
|
470
|
-
|
|
471
|
-
```json
|
|
472
|
-
{
|
|
473
|
-
what: "Web leaders",
|
|
474
|
-
hosts: {
|
|
475
|
-
id: "w3c",
|
|
476
|
-
which: "https://www.w3.org/",
|
|
477
|
-
what: "W3C"
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
id: "wikimedia",
|
|
481
|
-
which: "https://www.wikimedia.org/",
|
|
482
|
-
what: "Wikimedia"
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
With a batch, you can execute a single statement to run a script multiple times, one per host. On each call, Testaro takes one of the hosts in the batch and substitutes it for each host specified in a `url` command of the script. The result is a _host script_. Testaro sequentially runs all of those host scripts.
|
|
488
|
-
|
|
489
|
-
Therefore, you cannot use a batch with a script that changes URLs.
|
|
490
|
-
|
|
491
496
|
## Samples
|
|
492
497
|
|
|
493
|
-
The `
|
|
498
|
+
The `sampleScripts` directory contains examples of scripts. If you wish to use any of them, you can give `SCRIPTDIR` the value `'sampleScripts'`. Then execute `node high sss` to run the `sss` script. The `high` module will create a job, run the script, and save the report in the directory that you have specified with the `REPORTDIR` environment variable.
|
|
494
499
|
|
|
495
500
|
## Execution
|
|
496
501
|
|
|
@@ -508,12 +513,12 @@ const report = {
|
|
|
508
513
|
log: [],
|
|
509
514
|
acts: []
|
|
510
515
|
};
|
|
511
|
-
const {
|
|
512
|
-
|
|
516
|
+
const {doJob} = require('./run');
|
|
517
|
+
doJob(report)
|
|
513
518
|
.then(() => …);
|
|
514
519
|
```
|
|
515
520
|
|
|
516
|
-
Replace `{…}` with a script object, like the example script shown above.
|
|
521
|
+
Replace `{…}` with a script object, like the example script shown above.
|
|
517
522
|
|
|
518
523
|
The argument of `require` is a path relative to the directory of the module in which this code appears. If the module is in a subdirectory, `./run` will need to be revised. In an executor within `validation/executors`, it must be revised to `../../run`.
|
|
519
524
|
|
|
@@ -523,33 +528,29 @@ Testaro will run the script and modify the properties of the `report` object. Wh
|
|
|
523
528
|
|
|
524
529
|
#### High-level
|
|
525
530
|
|
|
531
|
+
High-level invocation allows you to run Testaro with a one-line command.
|
|
532
|
+
|
|
526
533
|
Make sure that you have defined these environment variables, with absolute or relative paths to directories as their values:
|
|
527
534
|
- `SCRIPTDIR`
|
|
528
|
-
- `BATCHDIR`
|
|
529
535
|
- `REPORTDIR`
|
|
530
536
|
|
|
531
537
|
Relative paths must be relative to the Testaro project directory. For example, if the script directory is `scripts` in a `testing` directory that is a sibling of the Testaro directory, then a relative-path `SCRIPTDIR` must have the value `../testing/scripts`.
|
|
532
538
|
|
|
533
539
|
Also ensure that Testaro can read all those directories and write to `REPORTDIR`.
|
|
534
540
|
|
|
535
|
-
Place a script into `SCRIPTDIR
|
|
536
|
-
|
|
537
|
-
Then execute the statement `node high scriptID` or `node high scriptID batchID`, replacing `scriptID` and `batchID` with the `id` values of the script and the batch, respectively.
|
|
541
|
+
Place a script into `SCRIPTDIR`. It should be named with a `.json` extension.
|
|
538
542
|
|
|
539
|
-
|
|
543
|
+
Then execute the statement `node high scriptID`, replacing `scriptID` with the `id` value of the script, which must also be the base of the name of the script file.
|
|
540
544
|
|
|
541
|
-
|
|
542
|
-
- `enp46j-wikipedia.json`
|
|
543
|
-
- `enp45j-wiktionary.json`
|
|
544
|
-
- `enp45j-wikidata.json`
|
|
545
|
+
The `high` module will call the `runJob` function of the `create` module, which in turn will call the `doJob` function of the `run` module. The result will be saved in a report file in the `REPORTDIR` directory. The report file will be named with a unique timestamp and suffixed with a `.json` extension. The base of the report file’s name will be the same timestamp, suffixed with `--scriptID`, where `scriptID` is the value of the `id` property of the script. For example, if you execute `node high tp18-wiktionary`, you might get a report named `enp45j-tp18-wiktionary.json` file deposited into `REPORTDIR`.
|
|
545
546
|
|
|
546
547
|
#### Watch
|
|
547
548
|
|
|
548
|
-
In watch mode, Testaro periodically checks for a
|
|
549
|
+
In watch mode, Testaro periodically checks for a script to be run by it. When such a script exists, Testaro runs it, produces a report in JSON format, and disposes of the report as specified.
|
|
549
550
|
|
|
550
551
|
Testaro checks periodically. The interval between checks, in seconds, is specified by an `INTERVAL` environment variable.
|
|
551
552
|
|
|
552
|
-
After Testaro starts watching, its behavior depends on the environment variable `WATCH_FOREVER`. If its value is `true`, watching continues indefinitely. If its value is `false` or it has no value, watching stops after the first
|
|
553
|
+
After Testaro starts watching, its behavior depends on the environment variable `WATCH_FOREVER`. If its value is `true`, watching continues indefinitely. If its value is `false` or it has no value, watching stops after the first script is found and run.
|
|
553
554
|
|
|
554
555
|
To make Testaro start watching, execute the statement `node watch`.
|
|
555
556
|
|
|
@@ -557,59 +558,43 @@ There are two ways for Testaro to watch for jobs.
|
|
|
557
558
|
|
|
558
559
|
##### Directory watch
|
|
559
560
|
|
|
560
|
-
With directory watch, Testaro checks whether
|
|
561
|
+
With directory watch, Testaro checks whether the watch directory (`WATCHDIR`) in its host’s filesystem contains a script.
|
|
561
562
|
|
|
562
|
-
|
|
563
|
-
{
|
|
564
|
-
"script": {…},
|
|
565
|
-
"batch": {…}
|
|
566
|
-
}
|
|
567
|
-
```
|
|
563
|
+
When Testaro finds one or more scripts in the watch directory, Testaro runs the first script, writes the report into the report directory, and moves the script into the done directory (`DONEDIR`).
|
|
568
564
|
|
|
569
|
-
|
|
565
|
+
Testaro suspends checking while it is running a script. Therefore, even though the currently running script file remains in thde watch directory, Testaro will not try to run it again.
|
|
570
566
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
Testaro suspends checking while it is running any job. Therefore, even though the currently running job file remains in `JOBDIR`, Testaro will not try to run it again.
|
|
574
|
-
|
|
575
|
-
Since Testaro runs the first job (i.e. the job whose name is first in ASCII order), whoever populates the directory with job files has control over the order in which Testaro runs them. For example, to force a new job to be run before the already waiting jobs, one can give it a filename that comes before that of the first waiting job.
|
|
567
|
+
Since Testaro runs the first script (i.e. the script whose name is first in ASCII order), whoever populates the directory with script files has control over the order in which Testaro runs them. For example, to force a new script to be run before the already waiting scripts, one can give it a filename that comes before that of the first waiting script.
|
|
576
568
|
|
|
577
569
|
In order to make directory watching possible, you must define these environment variables:
|
|
578
570
|
- `WATCH_TYPE=dir`
|
|
579
571
|
- `INTERVAL`
|
|
580
572
|
- `WATCH_FOREVER` (`=true` or `=false`)
|
|
581
573
|
- `REPORTDIR`
|
|
582
|
-
- `
|
|
583
|
-
- `
|
|
574
|
+
- `WATCHDIR`
|
|
575
|
+
- `DONEDIR`
|
|
584
576
|
|
|
585
577
|
##### Network watch
|
|
586
578
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
When the API receives the reports, it can dispose of them as desired. Each report is a JSON representation of an object, which has these identification properties:
|
|
592
|
-
- `jobID`
|
|
593
|
-
- `timeStamp`
|
|
594
|
-
- `id`
|
|
579
|
+
Network watching is based on these assumptions:
|
|
580
|
+
- A managing server may be able to give work to multiple workstations that run Testaro.
|
|
581
|
+
- A workstation running Testaro can contact a managing server, but the server may not be able to contact a workstation.
|
|
582
|
+
- The functions of Testaro are limited to those requiring workstation features.
|
|
595
583
|
|
|
596
|
-
|
|
584
|
+
Given these assumptions, with network watch, the initiator of an interaction is Testaro. When Testaro is available, it requests a script from a server. If the response is a JSON representation of a script, Testaro runs the script and sends the report to the server.
|
|
597
585
|
|
|
598
586
|
In order to make network watching possible, you must define these environment variables:
|
|
599
587
|
- `WATCH_TYPE=net`
|
|
600
588
|
- `INTERVAL`
|
|
601
589
|
- `WATCH_FOREVER` (`=true` or `=false`)
|
|
602
590
|
- `PROTOCOL` (`=http` or `=https`)
|
|
603
|
-
- `
|
|
604
|
-
- `REPORT_URL`
|
|
591
|
+
- `WATCH_URL`
|
|
592
|
+
- `REPORT_URL`
|
|
593
|
+
- `TESTARO_ID`
|
|
605
594
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
As mentioned above, using the high-level method to run Testaro jobs requires `SCRIPTDIR`, `BATCHDIR`, and `REPORTDIR` environment variables.
|
|
595
|
+
If multiple workstations run Testaro and do work for the same server, each must have a different `TESTARO_ID`.
|
|
609
596
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
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. You can get it from [WebAIM](https://wave.webaim.org/api/).
|
|
597
|
+
### Environment variables
|
|
613
598
|
|
|
614
599
|
The `text` command can interpolate the value of an environment variable into text that it enters on a page, as documented in the `commands.js` file.
|
|
615
600
|
|
|
@@ -632,9 +617,9 @@ The executors are:
|
|
|
632
617
|
- `watchNet`: validates network watching
|
|
633
618
|
- `tests`: validates all the custom tests (not the test packages)
|
|
634
619
|
|
|
635
|
-
To validate any single Testaro
|
|
620
|
+
To validate any single Testaro test `xyz`, enter the statement `npm run test1 xyz`.
|
|
636
621
|
|
|
637
|
-
To validate all of the Testaro
|
|
622
|
+
To validate all of the Testaro tests, enter the statement `npm test`.
|
|
638
623
|
|
|
639
624
|
To execute any executor `xyz` other than `test` or `tests`, call it with the statement `node validation/executors/xyz`.
|
|
640
625
|
|
|
@@ -656,12 +641,6 @@ The rationales motivating the Testaro-defined tests can be found in comments wit
|
|
|
656
641
|
|
|
657
642
|
On rare occasions a test throws an error that terminates the Node process and cannot be handled with a `try`-`catch` structure. It has been observed, for example, that the `ibm` test does this when run on the host at `https://zenythgroup.com/index` or `https://monsido.com`.
|
|
658
643
|
|
|
659
|
-
If a single process performed all of the commands in a batch-based script, the process could perform tens of thousands of commands, and such an error could stop the process at any point.
|
|
660
|
-
|
|
661
|
-
To handle this risk, Testaro processes batch-based jobs by forking a new process for each host. If such an error occurs, it crashes the child process, preventing a report for that host from being written. The parent process waits for the report to appear in the `REPORTDIR` directory until the time limit. When it fails to appear, the parent process continues to the next host.
|
|
662
|
-
|
|
663
|
-
If you are using high-level invocation, your terminal will show the standard output of the parent process and, if there is a batch, the current child process, too. If you interrupt the process with `CTRL-c`, you will send a `SIGINT` signal to the parent process, which will handle it by sending a message to the child process telling it to terminate itself, and then the parent process will terminate by skipping the remaining hosts.
|
|
664
|
-
|
|
665
644
|
### Activation
|
|
666
645
|
|
|
667
646
|
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.
|
|
@@ -672,7 +651,7 @@ The Playwright “Receives Events” actionability check does **not** check whet
|
|
|
672
651
|
|
|
673
652
|
Test packages sometimes do redundant testing, in that two or more packages test for the same issues, although such duplications are not necessarily perfect. This fact creates three problems:
|
|
674
653
|
- One cannot be confident in excluding some tests of some packages on the assumption that they perfectly duplicate tests of other packages.
|
|
675
|
-
- The Testaro report from a script documents each package’s results separately, so a single
|
|
654
|
+
- The Testaro report from a script documents each package’s results separately, so a single defect may be documented in multiple locations within the report, making the consumption of the report inefficient.
|
|
676
655
|
- An effort to aggregate the results into a single score may distort the scores by inflating the weights of defects that happen to be discovered by multiple packages.
|
|
677
656
|
|
|
678
657
|
The tests provided with Testaro do not exclude any apparently duplicative tests from packages.
|
|
@@ -691,6 +670,7 @@ The files in the `temp` directory are presumed ephemeral and are not tracked by
|
|
|
691
670
|
## Related packages
|
|
692
671
|
|
|
693
672
|
[Testilo](https://www.npmjs.com/package/testilo) is an application that:
|
|
673
|
+
- merges batches of hosts into scripts to produce multiple scripts
|
|
694
674
|
- produces scores and adds them to the JSON report files of Testaro
|
|
695
675
|
- produces human-oriented HTML digests from scored reports
|
|
696
676
|
- produces human-oriented HTML reports comparing the scores of hosts
|
package/commands.js
CHANGED
|
@@ -72,7 +72,7 @@ exports.commands = {
|
|
|
72
72
|
which: [false, 'array', 'areStrings', 'substrings any of which matches element text'],
|
|
73
73
|
text: [false, 'string', 'hasLength', 'text to enter after reaching element'],
|
|
74
74
|
action: [false, 'string', 'hasLength', 'name of key to press, after text entry if any'],
|
|
75
|
-
withItems: [true, 'boolean']
|
|
75
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
76
76
|
}
|
|
77
77
|
],
|
|
78
78
|
radio: [
|
|
@@ -170,13 +170,13 @@ exports.commands = {
|
|
|
170
170
|
embAc: [
|
|
171
171
|
'Perform an embAc test',
|
|
172
172
|
{
|
|
173
|
-
withItems: [true, 'boolean']
|
|
173
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
174
174
|
}
|
|
175
175
|
],
|
|
176
176
|
filter: [
|
|
177
177
|
'Perform a filter test',
|
|
178
178
|
{
|
|
179
|
-
withItems: [true, 'boolean']
|
|
179
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
180
180
|
}
|
|
181
181
|
],
|
|
182
182
|
focInd: [
|
|
@@ -184,32 +184,32 @@ exports.commands = {
|
|
|
184
184
|
{
|
|
185
185
|
revealAll: [true, 'boolean', '', 'whether to make all elements visible first'],
|
|
186
186
|
allowedDelay: [true, 'number', '', 'milliseconds to wait for an outline'],
|
|
187
|
-
withItems: [true, 'boolean']
|
|
187
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
188
188
|
}
|
|
189
189
|
],
|
|
190
190
|
focOp: [
|
|
191
191
|
'Perform a focOp test',
|
|
192
192
|
{
|
|
193
|
-
withItems: [true, 'boolean']
|
|
193
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
194
194
|
}
|
|
195
195
|
],
|
|
196
196
|
focVis: [
|
|
197
197
|
'Perform a focVis test',
|
|
198
198
|
{
|
|
199
|
-
withItems: [true, 'boolean']
|
|
199
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
200
200
|
}
|
|
201
201
|
],
|
|
202
202
|
hover: [
|
|
203
203
|
'Perform a hover test',
|
|
204
204
|
{
|
|
205
205
|
sampleSize: [false, 'number', '', 'limit on sample size of triggers, if any'],
|
|
206
|
-
withItems: [true, 'boolean']
|
|
206
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
207
207
|
}
|
|
208
208
|
],
|
|
209
209
|
ibm: [
|
|
210
210
|
'Perform an IBM Equal Access test',
|
|
211
211
|
{
|
|
212
|
-
withItems: [true, 'boolean'],
|
|
212
|
+
withItems: [true, 'boolean', '', 'itemize'],
|
|
213
213
|
withNewContent: [
|
|
214
214
|
false, 'boolean', '', 'true: use a URL; false: use page content; omitted: both'
|
|
215
215
|
]
|
|
@@ -218,31 +218,31 @@ exports.commands = {
|
|
|
218
218
|
labClash: [
|
|
219
219
|
'Perform a labClash test',
|
|
220
220
|
{
|
|
221
|
-
withItems: [true, 'boolean']
|
|
221
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
222
222
|
}
|
|
223
223
|
],
|
|
224
224
|
linkTo: [
|
|
225
225
|
'Perform a linkTo test',
|
|
226
226
|
{
|
|
227
|
-
withItems: [true, 'boolean']
|
|
227
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
228
228
|
}
|
|
229
229
|
],
|
|
230
230
|
linkUl: [
|
|
231
231
|
'Perform a linkUl test',
|
|
232
232
|
{
|
|
233
|
-
withItems: [true, 'boolean']
|
|
233
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
234
234
|
}
|
|
235
235
|
],
|
|
236
236
|
menuNav: [
|
|
237
237
|
'Perform a menuNav test',
|
|
238
238
|
{
|
|
239
|
-
withItems: [true, 'boolean']
|
|
239
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
240
240
|
}
|
|
241
241
|
],
|
|
242
242
|
miniText: [
|
|
243
243
|
'Perform a miniText test',
|
|
244
244
|
{
|
|
245
|
-
withItems: [true, 'boolean']
|
|
245
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
246
246
|
}
|
|
247
247
|
],
|
|
248
248
|
motion: [
|
|
@@ -256,25 +256,25 @@ exports.commands = {
|
|
|
256
256
|
nonTable: [
|
|
257
257
|
'Perform a nonTable test',
|
|
258
258
|
{
|
|
259
|
-
withItems: [true, 'boolean']
|
|
259
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
260
260
|
}
|
|
261
261
|
],
|
|
262
262
|
radioSet: [
|
|
263
263
|
'Perform a radioSet test',
|
|
264
264
|
{
|
|
265
|
-
withItems: [true, 'boolean']
|
|
265
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
266
266
|
}
|
|
267
267
|
],
|
|
268
268
|
styleDiff: [
|
|
269
269
|
'Perform a styleDiff test',
|
|
270
270
|
{
|
|
271
|
-
withItems: [true, 'boolean']
|
|
271
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
272
272
|
}
|
|
273
273
|
],
|
|
274
274
|
tabNav: [
|
|
275
275
|
'Perform a tabNav test',
|
|
276
276
|
{
|
|
277
|
-
withItems: [true, 'boolean']
|
|
277
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
278
278
|
}
|
|
279
279
|
],
|
|
280
280
|
tenon: [
|
|
@@ -293,7 +293,7 @@ exports.commands = {
|
|
|
293
293
|
titledEl: [
|
|
294
294
|
'Perform a titledEl test',
|
|
295
295
|
{
|
|
296
|
-
withItems: [true, 'boolean']
|
|
296
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
297
297
|
}
|
|
298
298
|
],
|
|
299
299
|
wave: [
|
|
@@ -305,7 +305,7 @@ exports.commands = {
|
|
|
305
305
|
zIndex: [
|
|
306
306
|
'Perform a zIndex test',
|
|
307
307
|
{
|
|
308
|
-
withItems: [true, 'boolean']
|
|
308
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
309
309
|
}
|
|
310
310
|
]
|
|
311
311
|
}
|
package/high.js
CHANGED
|
@@ -1,10 +1,69 @@
|
|
|
1
1
|
/*
|
|
2
2
|
high.js
|
|
3
3
|
Invokes Testaro with the high-level method.
|
|
4
|
-
Usage example: node high
|
|
4
|
+
Usage example: node high script454
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// ########## IMPORTS
|
|
8
|
+
|
|
9
|
+
// Module to keep secrets.
|
|
10
|
+
require('dotenv').config();
|
|
11
|
+
// Module to read and write files.
|
|
12
|
+
const fs = require('fs/promises');
|
|
13
|
+
// Module to run scripts and report results.
|
|
14
|
+
const {doJob} = require('./run');
|
|
15
|
+
|
|
16
|
+
// ########## CONSTANTS
|
|
17
|
+
|
|
18
|
+
const scriptDir = process.env.SCRIPTDIR;
|
|
19
|
+
const reportDir = process.env.REPORTDIR;
|
|
8
20
|
const scriptID = process.argv[2];
|
|
9
|
-
|
|
10
|
-
|
|
21
|
+
|
|
22
|
+
// ########## VARIABLES
|
|
23
|
+
|
|
24
|
+
// Set 5 minutes as a default time limit.
|
|
25
|
+
let timeLimit = 300;
|
|
26
|
+
|
|
27
|
+
// ########## FUNCTIONS
|
|
28
|
+
|
|
29
|
+
// Performs a file-based job and writes a report file.
|
|
30
|
+
const runJob = async scriptID => {
|
|
31
|
+
try {
|
|
32
|
+
const scriptJSON = await fs.readFile(`${scriptDir}/${scriptID}.json`, 'utf8');
|
|
33
|
+
const script = JSON.parse(scriptJSON);
|
|
34
|
+
// Change the time limit to the script-specified one, if any.
|
|
35
|
+
if (! script.timeLimit) {
|
|
36
|
+
script.timeLimit = timeLimit;
|
|
37
|
+
}
|
|
38
|
+
// Identify the start time and a timestamp.
|
|
39
|
+
const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
|
|
40
|
+
// Run the script and record the report with the timestamp as name base.
|
|
41
|
+
const id = `${timeStamp}-${scriptID}`;
|
|
42
|
+
const report = {
|
|
43
|
+
id,
|
|
44
|
+
log: [],
|
|
45
|
+
script,
|
|
46
|
+
acts: []
|
|
47
|
+
};
|
|
48
|
+
await doJob(report);
|
|
49
|
+
const reportJSON = JSON.stringify(report, null, 2);
|
|
50
|
+
await fs.writeFile(`${reportDir}/${id}.json`, reportJSON);
|
|
51
|
+
console.log(`Report ${timeStamp}-${scriptID}.json recorded in ${process.env.REPORTDIR}`);
|
|
52
|
+
}
|
|
53
|
+
catch(error) {
|
|
54
|
+
console.log(`ERROR running job (${error.message})\n${error.stack}`);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// ########## OPERATION
|
|
59
|
+
|
|
60
|
+
// If this module was called with a scriptID argument:
|
|
61
|
+
if (scriptID) {
|
|
62
|
+
// Run the script and write a report.
|
|
63
|
+
runJob(scriptID);
|
|
64
|
+
}
|
|
65
|
+
// Otherwise, i.e. if it was required by another module:
|
|
66
|
+
else {
|
|
67
|
+
// Export runJob so the other module can call it.
|
|
68
|
+
exports.runJob = runJob;
|
|
69
|
+
}
|