testaro 6.0.0 → 6.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/watch.js +94 -130
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "Automation of accessibility testing",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/watch.js CHANGED
@@ -1,66 +1,70 @@
1
1
  /*
2
2
  watch.js
3
3
  Watches for a script and runs it.
4
+ Arguments:
5
+ 0. Watch type: 'dir' or 'net'.
6
+ 1. How long to watch: 'once' or 'forever'.
7
+ 2. How often to check in seconds.
8
+ Usage example: node watch dir once 15
4
9
  */
5
10
 
6
11
  // ########## IMPORTS
7
12
 
8
13
  // Module to keep secrets local.
9
- // require('dotenv').config({override: true});
10
14
  require('dotenv').config();
11
15
  // Module to read and write files.
12
16
  const fs = require('fs/promises');
13
17
  // Module to perform tests.
14
18
  const {doJob} = require('./run');
15
- // Module to convert a script and a batch to a batch-based array of scripts.
16
- const {batchify} = require('./batchify');
17
19
 
18
20
  // ########## CONSTANTS
19
21
 
20
- const watchType = process.env.WATCH_TYPE;
22
+ const watchType = process.argv[2];
23
+ const watchForever = process.argv[3] === 'forever';
24
+ const interval = Number.parseInt(process.argv[4]);
21
25
  let client;
22
26
  if (watchType === 'net') {
23
27
  client = require(process.env.PROTOCOL || 'https');
24
28
  }
25
29
  const jobURL = process.env.JOB_URL;
26
- const authCode = process.env.AUTH_CODE;
27
- const jobDir = process.env.JOBDIR;
28
- const exJobDir = process.env.EXJOBDIR;
30
+ const worker = process.env.WORKER;
31
+ const watchDir = process.env.WATCHDIR;
32
+ const doneDir = process.env.DONEDIR;
29
33
  const reportURL = process.env.REPORT_URL;
30
34
  const reportDir = process.env.REPORTDIR;
31
- const interval = process.env.INTERVAL;
32
- // Values of process.env properties are coerced to strings.
33
- const watchForever = process.env.WATCH_FOREVER == 'true';
34
35
 
35
36
  // ########## FUNCTIONS
36
37
 
37
38
  // Checks for a directory job.
38
39
  const checkDirJob = async () => {
39
- const jobDirFileNames = await fs.readdir(jobDir);
40
- const jobFileNames = jobDirFileNames.filter(fileName => fileName.endsWith('.json'));
41
- if (jobFileNames.length) {
42
- const firstJobID = jobFileNames[0].slice(0, -5);
43
- const jobJSON = await fs.readFile(`${jobDir}/${jobFileNames[0]}`, 'utf8');
44
- try {
45
- const job = JSON.parse(jobJSON, null, 2);
46
- job.jobID = firstJobID;
47
- return job;
40
+ try {
41
+ const jobDirFileNames = await fs.readdir(watchDir);
42
+ const jobFileNames = jobDirFileNames.filter(fileName => fileName.endsWith('.json'));
43
+ if (jobFileNames.length) {
44
+ const scriptJSON = await fs.readFile(`${watchDir}/${jobFileNames[0]}`, 'utf8');
45
+ try {
46
+ const script = JSON.parse(scriptJSON, null, 2);
47
+ return script;
48
+ }
49
+ catch(error) {
50
+ return {
51
+ error: 'ERROR: Script was not JSON',
52
+ message: error.message
53
+ };
54
+ }
48
55
  }
49
- catch(error) {
50
- return {
51
- error: 'ERROR: Job was not JSON',
52
- message: error.message
53
- };
56
+ else {
57
+ return {};
54
58
  }
55
59
  }
56
- else {
60
+ catch {
57
61
  return {};
58
62
  }
59
63
  };
60
64
  // Checks for a network job.
61
65
  const checkNetJob = async () => {
62
- const job = await new Promise(resolve => {
63
- const wholeURL = `${process.env.PROTOCOL}://${jobURL}?authCode=${authCode}`;
66
+ const script = await new Promise(resolve => {
67
+ const wholeURL = `${process.env.PROTOCOL}://${jobURL}?worker=${worker}`;
64
68
  const request = client.request(wholeURL, response => {
65
69
  const chunks = [];
66
70
  response.on('data', chunk => {
@@ -68,18 +72,10 @@ const checkNetJob = async () => {
68
72
  });
69
73
  response.on('end', () => {
70
74
  try {
71
- const jobJSON = chunks.join('');
72
- const job = JSON.parse(jobJSON);
73
- // If a qualifying job was received:
74
- if (job.jobID) {
75
- // Return it.
76
- resolve(job);
77
- }
78
- // Otherwise, i.e. if there was no qualifying job:
79
- else {
80
- // Return this.
81
- resolve({});
82
- }
75
+ const scriptJSON = chunks.join('');
76
+ const script = JSON.parse(scriptJSON);
77
+ // Return it.
78
+ resolve(script);
83
79
  }
84
80
  catch(error) {
85
81
  resolve({
@@ -92,20 +88,21 @@ const checkNetJob = async () => {
92
88
  });
93
89
  request.end();
94
90
  });
95
- return job;
91
+ return script;
96
92
  };
97
93
  // Writes a directory report.
98
94
  const writeDirReport = async report => {
99
- const {id, jobID} = report;
100
- if (id && jobID) {
101
- const reportJSON = JSON.stringify(report, null, 2);
95
+ const scriptID = report && report.script && report.script.id;
96
+ if (scriptID) {
102
97
  try {
103
- await fs.writeFile(`${reportDir}/${id}.json`, reportJSON);
104
- console.log(`Report ${id}.json saved`);
98
+ const reportJSON = JSON.stringify(report, null, 2);
99
+ const reportName = `${report.timeStamp}-${scriptID}.json`;
100
+ await fs.writeFile(`${reportDir}/${reportName}`, reportJSON);
101
+ console.log(`Report ${reportName} saved`);
105
102
  return true;
106
103
  }
107
104
  catch(error) {
108
- console.log(`ERROR: Failed to write report ${id} for job ${jobID}`);
105
+ console.log(`ERROR: Failed to write report (${error.message})`);
109
106
  return false;
110
107
  }
111
108
  }
@@ -113,7 +110,7 @@ const writeDirReport = async report => {
113
110
  // Submits a network report.
114
111
  const writeNetReport = async report => {
115
112
  const ack = await new Promise(resolve => {
116
- const wholeURL = `${process.env.PROTOCOL}://${reportURL}?authCode=${authCode}`;
113
+ const wholeURL = `${process.env.PROTOCOL}://${reportURL}?worker=${worker}`;
117
114
  const request = client.request(wholeURL, {method: 'POST'}, response => {
118
115
  const chunks = [];
119
116
  response.on('data', chunk => {
@@ -134,15 +131,15 @@ const writeNetReport = async report => {
134
131
  });
135
132
  request.write(JSON.stringify(report, null, 2));
136
133
  request.end();
137
- console.log(`Report with ID ${report.id} submitted`);
134
+ console.log(`Report ${report.timeStamp}-${report.script.id} submitted`);
138
135
  });
139
136
  return ack;
140
137
  };
141
138
  // Archives a job.
142
- const exifyJob = async (job) => {
143
- const jobJSON = JSON.stringify(job, null, 2);
144
- await fs.writeFile(`${exJobDir}/${job.timeStamp}.json`, jobJSON);
145
- await fs.rm(`${jobDir}/${job.jobID}.json`);
139
+ const archiveJob = async script => {
140
+ const jobJSON = JSON.stringify(script, null, 2);
141
+ await fs.writeFile(`${doneDir}/${script.timeStamp}-${script.id}.json`, jobJSON);
142
+ await fs.rm(`${watchDir}/${script.id}.json`);
146
143
  };
147
144
  // Waits.
148
145
  const wait = ms => {
@@ -152,117 +149,84 @@ const wait = ms => {
152
149
  }, ms);
153
150
  });
154
151
  };
155
- // Runs one script and writes or sends a report.
156
- const runHost = async (jobID, timeStamp, id, script) => {
157
- const report = {
158
- jobID,
159
- timeStamp,
160
- id,
161
- log: [],
162
- script,
163
- acts: []
164
- };
165
- await doJob(report);
166
- if (watchType === 'dir') {
167
- return await writeDirReport(report);
168
- }
169
- else {
170
- const ack = await writeNetReport(report);
171
- if (ack.error) {
172
- console.log(JSON.stringify(ack, null, 2));
173
- return false;
174
- }
175
- else {
176
- return true;
177
- }
178
- }
179
- };
180
- // Runs a job and returns a report file for the script or each host.
181
- const runJob = async job => {
182
- const {jobID, script, batch} = job;
183
- if (jobID) {
184
- if (script) {
185
- try {
186
- // Identify the start time and a time stamp.
187
- const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
188
- job.timeStamp = timeStamp;
189
- // If there is a batch:
190
- if (batch) {
191
- // Convert the script to a set of host scripts.
192
- const specs = batchify(script, batch, timeStamp);
193
- // For each host script:
194
- let success = true;
195
- while (specs.length && success) {
196
- // Run it and write or submit a report with a host-suffixed time-stamp ID.
197
- const spec = specs.shift();
198
- const {id} = spec;
199
- const hostScript = spec.script;
200
- success = await runHost(jobID, timeStamp, id, hostScript);
201
- }
202
- return success;
152
+ // Runs a script, time-stamps it, and returns a report.
153
+ const runJob = async script => {
154
+ const {id} = script;
155
+ if (id) {
156
+ try {
157
+ // Identify the start time and a time stamp.
158
+ const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
159
+ script.timeStamp = timeStamp;
160
+ // Initialize a report.
161
+ const report = {
162
+ log: [],
163
+ script,
164
+ acts: []
165
+ };
166
+ await doJob(report);
167
+ if (watchType === 'dir') {
168
+ return await writeDirReport(report);
169
+ }
170
+ else {
171
+ const ack = await writeNetReport(report);
172
+ if (ack.error) {
173
+ console.log(JSON.stringify(ack, null, 2));
174
+ return false;
203
175
  }
204
- // Otherwise, i.e. if there is no batch:
205
176
  else {
206
- // Run the script and submit a report with a timestamp ID.
207
- return await runHost(jobID, timeStamp, timeStamp, script);
177
+ return true;
208
178
  }
209
179
  }
210
- catch(error) {
211
- console.log(`ERROR: ${error.message}\n${error.stack}`);
212
- return {
213
- error: `ERROR: ${error.message}\n${error.stack}`
214
- };
215
- }
216
180
  }
217
- else {
218
- console.log('ERROR: no script specified');
181
+ catch(error) {
182
+ console.log(`ERROR: ${error.message}\n${error.stack}`);
219
183
  return {
220
- error: 'ERROR: no script specified'
184
+ error: `ERROR: ${error.message}\n${error.stack}`
221
185
  };
222
186
  }
223
187
  }
224
188
  else {
225
- console.log('ERROR: no job ID property in job');
189
+ console.log('ERROR: script has no id');
226
190
  return {
227
- error: 'ERROR: no job ID property in job'
191
+ error: 'ERROR: script has no id'
228
192
  };
229
193
  }
230
194
  };
231
- // Repeatedly checks for jobs, runs them, and submits reports.
195
+ // Checks for a job, performs it, and submits a report, once or repeatedly.
232
196
  const cycle = async forever => {
233
- const intervalMS = Number.parseInt(interval);
197
+ const intervalMS = 1000 * Number.parseInt(interval);
234
198
  let statusOK = true;
235
199
  let empty = false;
236
200
  console.log(`Watching started with intervals of ${interval} seconds when idle`);
237
201
  while (statusOK) {
238
202
  if (empty) {
239
- await wait(1000 * intervalMS);
203
+ await wait(intervalMS);
240
204
  }
241
205
  // Check for a job.
242
- let job;
206
+ let script;
243
207
  if (watchType === 'dir') {
244
- job = await checkDirJob();
208
+ script = await checkDirJob();
245
209
  }
246
210
  else if (watchType === 'net') {
247
- job = await checkNetJob();
211
+ script = await checkNetJob();
248
212
  }
249
213
  else {
250
- job = {};
214
+ script = {};
251
215
  console.log('ERROR: invalid WATCH_TYPE environment variable');
252
216
  statusOK = false;
253
217
  }
254
218
  // If there was one:
255
- if (job.jobID) {
256
- // Run it.
257
- console.log(`Running job ${job.jobID}`);
258
- statusOK = await runJob(job);
259
- console.log(`Job ${job.jobID} finished with time stamp ${job.timeStamp}`);
219
+ if (script.id) {
220
+ // Run it, add a timestamp to it, and save a report.
221
+ console.log(`Running script ${script.id}`);
222
+ statusOK = await runJob(script);
223
+ console.log(`Job ${script.id} finished with time stamp ${script.timeStamp}`);
260
224
  if (statusOK) {
261
- // If the job was a file:
225
+ // If the script was in a directory:
262
226
  if (watchType === 'dir') {
263
- // Archive it.
264
- await exifyJob(job);
265
- console.log(`Job archived as ${job.timeStamp}.json`);
227
+ // Archive the script.
228
+ await archiveJob(script);
229
+ console.log(`Script ${script.id}.json archived as ${script.timeStamp}-${script.id}.json`);
266
230
  }
267
231
  // If watching was specified for only 1 job, stop.
268
232
  statusOK = forever;