testaro 47.2.1 → 48.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,9 @@ The purposes of Testaro are to:
10
10
  - provide programmatic access to accessibility tests defined by several tools
11
11
  - facilitate the integration of the reports of the tools into a unified report
12
12
 
13
- Testaro is described in [Testaro: Efficient Ensemble Testing for Web Accessibility](https://arxiv.org/abs/2309.10167).
13
+ Testaro is described in two papers:
14
+ - [How to run a thousand accessibility tests](https://medium.com/cvs-health-tech-blog/how-to-run-a-thousand-accessibility-tests-63692ad120c3)
15
+ - [Testaro: Efficient Ensemble Testing for Web Accessibility](https://arxiv.org/abs/2309.10167)
14
16
 
15
17
  The need for multi-tool integration, and its costs, are discussed in [Accessibility Metatesting: Comparing Nine Testing Tools](https://arxiv.org/abs/2304.07591).
16
18
 
@@ -729,13 +731,11 @@ A job can be immediately executed as follows:
729
731
 
730
732
  ```javascript
731
733
  const {doJob} = require('./run');
732
- doJob(report)
733
- .then(() => …);
734
+ doJob(job)
735
+ .then(report => …);
734
736
  ```
735
737
 
736
- The `report` variable here references a copy of a job to be used as a report.
737
-
738
- Testaro will run the job and modify the `report` object. When Testaro finishes, the `acts` and `jobData` properties of `report` will contain the results. The final statement can further process the `report` object as desired in the `then` callback.
738
+ Testaro will run the job and return a modified `report` object. When Testaro finishes, the `acts` and `jobData` properties of `report` will contain the results. The final statement can further process the `report` object as desired in the `then` callback.
739
739
 
740
740
  The Testilo package contains functions that can create jobs from scripts and add scores and explanations to reports.
741
741
 
@@ -865,7 +865,7 @@ The rationales motivating the Testaro-defined tests can be found in comments wit
865
865
 
866
866
  On some occasions a test throws an error that cannot be handled with a `try`-`catch` structure. It has been observed, for example, that the `ibm` test does this when the page content, rather than the page URL, is given to `getCompliance()` and the target is `https://globalsolutions.org`, `https://monsido.com`, or `https://www.ambetterhealth.com/`.
867
867
 
868
- Some tools take apparently infinite time to perform their tests on some pages. To handle such stalling, Testaro subjects most tools to time limits. Further testing will be required before it can be determined whether this time limitation is robust. As currently implemented (without child processes), it may allow tool testing processes to continue and to write indefinitely to the response.
868
+ Some tools take apparently infinite time to perform their tests on some pages. To handle such stalling, Testaro subjects all tools to time limits. The limitation is implemented with forked child processes. Specifically, the `procs/doTestAct.js` module is run as a forked process with a `timeout` option for each of the 11 tools.
869
869
 
870
870
  ### Activation
871
871
 
@@ -902,7 +902,7 @@ Testaro would become more reliable if the behavior of its tools were monitored f
902
902
 
903
903
  ## Repository exclusions
904
904
 
905
- The files in the `temp` directory are presumed ephemeral and are not tracked by `git`.
905
+ The files in the `temp` directory are presumed ephemeral and are not tracked by `git`. The above-mentioned `procs/doTestAct.js` module stores temporary reports in that directory.
906
906
 
907
907
  ## Related packages
908
908
 
package/call.js CHANGED
@@ -75,7 +75,7 @@ const callRun = async jobIDStart => {
75
75
  report.observe = false;
76
76
  report.sendReportTo = '';
77
77
  // Run it.
78
- await doJob(report);
78
+ report = await doJob(report);
79
79
  // Archive it.
80
80
  await fs.rename(`${todoDir}/${jobFileName}`, `${jobDir}/done/${jobFileName}`);
81
81
  // Save the report.
package/dirWatch.js CHANGED
@@ -45,8 +45,6 @@ const reportDir = process.env.REPORTDIR;
45
45
 
46
46
  // ########## FUNCTIONS
47
47
 
48
- // Gets a segment of a timestamp.
49
- const tsPart = (timeStamp, startIndex) => timeStamp.slice(startIndex, startIndex + 2);
50
48
  // Returns a string representing the date and time.
51
49
  const nowString = () => (new Date()).toISOString().slice(2, 16);
52
50
  // Writes a directory report.
@@ -115,7 +113,7 @@ exports.dirWatch = async (isForever, intervalInSeconds) => {
115
113
  const jobJSON = await fs.readFile(`${jobDir}/todo/${jobFileNames[0]}`, 'utf8');
116
114
  try {
117
115
  const job = JSON.parse(jobJSON);
118
- const report = JSON.parse(jobJSON);
116
+ let report = JSON.parse(jobJSON);
119
117
  // Ensure it has no server properties.
120
118
  job.observe = false;
121
119
  job.sendReportTo = '';
@@ -123,12 +121,12 @@ exports.dirWatch = async (isForever, intervalInSeconds) => {
123
121
  report.sendReportTo = '';
124
122
  const {id} = job;
125
123
  console.log(`\n\nDirectory job ${id} ready to do (${nowString()})`);
126
- // Perform it.
127
- await doJob(report);
124
+ // Perform it, adding to the report.
125
+ report = await doJob(report);
128
126
  console.log(`Job ${id} finished (${nowString()})`);
129
- // Report it.
127
+ // Save the report.
130
128
  await writeDirReport(report);
131
- // Archive it.
129
+ // Archive the job.
132
130
  await archiveJob(job, true);
133
131
  }
134
132
  catch(error) {
package/netWatch.js CHANGED
@@ -164,7 +164,7 @@ exports.netWatch = async (isForever, intervalInSeconds, isCertTolerant = true) =
164
164
  // Perform the job, adding result data to it.
165
165
  console.log(`${logStart}job ${id} (${nowString()})`);
166
166
  console.log(`>> It will send report to ${sendReportTo}`);
167
- await doJob(contentObj);
167
+ contentObj = await doJob(contentObj);
168
168
  let reportJSON = JSON.stringify(contentObj, null, 2);
169
169
  console.log(`Job ${id} finished (${nowString()})`);
170
170
  // Send the report to the specified server.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "47.2.1",
3
+ "version": "48.0.2",
4
4
  "description": "Run 1000 web accessibility tests from 11 tools and get a standardized report",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,121 @@
1
+ /*
2
+ © 2024 CVS Health and/or one of its affiliates. All rights reserved.
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+ */
24
+
25
+ /*
26
+ doTestAct
27
+ Performs the tests of an act.
28
+ */
29
+
30
+ // IMPORTS
31
+
32
+ // Module to perform file operations.
33
+ const fs = require('fs/promises');
34
+ const {launch} = require(`${__dirname}/../run`);
35
+
36
+ // CONSTANTS
37
+
38
+ // Set DEBUG environment variable to 'true' to add debugging features.
39
+ const debug = process.env.DEBUG === 'true';
40
+ // Set WAITS environment variable to a positive number to insert delays (in ms).
41
+ const waits = Number.parseInt(process.env.WAITS) || 0;
42
+
43
+ // VARIABLES
44
+
45
+ const actIndex = Number.parseInt(process.argv[2]);
46
+
47
+ const doTestAct = async () => {
48
+ const reportPath = `${__dirname}/../temp/report.json`;
49
+ // Get the saved report.
50
+ const reportJSON = await fs.readFile(reportPath, 'utf8');
51
+ const report = JSON.parse(reportJSON);
52
+ // Get the act.
53
+ const act = report.acts[actIndex];
54
+ // Get the tool name.
55
+ const {which} = act;
56
+ // Launch a browser, navigate to the URL, and redefine the page of the run module.
57
+ await launch(
58
+ report,
59
+ debug,
60
+ waits,
61
+ act.launch.browserID || report.browserID,
62
+ act.launch.target && act.launch.target.url || report.target.url
63
+ );
64
+ // If the launch aborted the job:
65
+ if (report.jobData && report.jobData.aborted) {
66
+ // Save the revised report.
67
+ const reportJSON = JSON.stringify(report);
68
+ await fs.writeFile(reportPath, reportJSON);
69
+ // Report this.
70
+ process.send('ERROR: Job aborted');
71
+ }
72
+ // Otherwise, i.e. if the launch did not abort the job:
73
+ else {
74
+ // Get the redefined page.
75
+ const {page} = require('../run');
76
+ // If it exists:
77
+ if (page) {
78
+ try {
79
+ // If the page prevents the tool from testing:
80
+ if (page.prevented) {
81
+ // Report this.
82
+ process.send('ERROR: Page prevented testing');
83
+ }
84
+ // Otherwise, i.e. if the page permits testing:
85
+ else {
86
+ // Wait for the act reporter to perform the specified tests of the tool.
87
+ const actReport = await require(`../tests/${which}`).reporter(page, report, actIndex, 65);
88
+ // Add the data and result to the act.
89
+ act.data = actReport.data;
90
+ act.result = actReport.result;
91
+ // If the tool reported that the page prevented testing:
92
+ if (actReport.data && actReport.data.prevented) {
93
+ // Add prevention data to the job data.
94
+ report.jobData.preventions[which] = act.data.error;
95
+ }
96
+ const reportJSON = JSON.stringify(report);
97
+ // Save the revised report.
98
+ await fs.writeFile(reportPath, reportJSON);
99
+ // Send a completion message.
100
+ process.send('Act completed');
101
+ }
102
+ }
103
+ // If the tool invocation failed:
104
+ catch(error) {
105
+ // Save the revised report.
106
+ const reportJSON = JSON.stringify(report);
107
+ await fs.writeFile(reportPath, reportJSON);
108
+ // Report the failure.
109
+ const message = error.message.slice(0, 400);
110
+ console.log(`ERROR: Test act ${act.which} failed (${message})`);
111
+ process.send('ERROR performing the act');
112
+ };
113
+ }
114
+ // Otherwise, i.e. if the page does not exist:
115
+ else {
116
+ process.send('ERROR: No page');
117
+ }
118
+ }
119
+ };
120
+
121
+ doTestAct();