testaro 6.0.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/watch.js +81 -122
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "description": "Automation of accessibility testing",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/watch.js CHANGED
@@ -1,54 +1,53 @@
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 jobDirFileNames = await fs.readdir(watchDir);
40
41
  const jobFileNames = jobDirFileNames.filter(fileName => fileName.endsWith('.json'));
41
42
  if (jobFileNames.length) {
42
- const firstJobID = jobFileNames[0].slice(0, -5);
43
- const jobJSON = await fs.readFile(`${jobDir}/${jobFileNames[0]}`, 'utf8');
43
+ const scriptJSON = await fs.readFile(`${watchDir}/${jobFileNames[0]}`, 'utf8');
44
44
  try {
45
- const job = JSON.parse(jobJSON, null, 2);
46
- job.jobID = firstJobID;
47
- return job;
45
+ const script = JSON.parse(scriptJSON, null, 2);
46
+ return script;
48
47
  }
49
48
  catch(error) {
50
49
  return {
51
- error: 'ERROR: Job was not JSON',
50
+ error: 'ERROR: Script was not JSON',
52
51
  message: error.message
53
52
  };
54
53
  }
@@ -59,8 +58,8 @@ const checkDirJob = async () => {
59
58
  };
60
59
  // Checks for a network job.
61
60
  const checkNetJob = async () => {
62
- const job = await new Promise(resolve => {
63
- const wholeURL = `${process.env.PROTOCOL}://${jobURL}?authCode=${authCode}`;
61
+ const script = await new Promise(resolve => {
62
+ const wholeURL = `${process.env.PROTOCOL}://${jobURL}?worker=${worker}`;
64
63
  const request = client.request(wholeURL, response => {
65
64
  const chunks = [];
66
65
  response.on('data', chunk => {
@@ -68,18 +67,10 @@ const checkNetJob = async () => {
68
67
  });
69
68
  response.on('end', () => {
70
69
  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
- }
70
+ const scriptJSON = chunks.join('');
71
+ const script = JSON.parse(scriptJSON);
72
+ // Return it.
73
+ resolve(script);
83
74
  }
84
75
  catch(error) {
85
76
  resolve({
@@ -92,20 +83,21 @@ const checkNetJob = async () => {
92
83
  });
93
84
  request.end();
94
85
  });
95
- return job;
86
+ return script;
96
87
  };
97
88
  // Writes a directory report.
98
89
  const writeDirReport = async report => {
99
- const {id, jobID} = report;
100
- if (id && jobID) {
101
- const reportJSON = JSON.stringify(report, null, 2);
90
+ const scriptID = report && report.script && report.script.id;
91
+ if (scriptID) {
102
92
  try {
103
- await fs.writeFile(`${reportDir}/${id}.json`, reportJSON);
104
- console.log(`Report ${id}.json saved`);
93
+ const reportJSON = JSON.stringify(report, null, 2);
94
+ const reportName = `${report.timeStamp}-${scriptID}.json`;
95
+ await fs.writeFile(`${reportDir}/${reportName}`, reportJSON);
96
+ console.log(`Report ${reportName} saved`);
105
97
  return true;
106
98
  }
107
99
  catch(error) {
108
- console.log(`ERROR: Failed to write report ${id} for job ${jobID}`);
100
+ console.log(`ERROR: Failed to write report (${error.message})`);
109
101
  return false;
110
102
  }
111
103
  }
@@ -113,7 +105,7 @@ const writeDirReport = async report => {
113
105
  // Submits a network report.
114
106
  const writeNetReport = async report => {
115
107
  const ack = await new Promise(resolve => {
116
- const wholeURL = `${process.env.PROTOCOL}://${reportURL}?authCode=${authCode}`;
108
+ const wholeURL = `${process.env.PROTOCOL}://${reportURL}?worker=${worker}`;
117
109
  const request = client.request(wholeURL, {method: 'POST'}, response => {
118
110
  const chunks = [];
119
111
  response.on('data', chunk => {
@@ -134,15 +126,15 @@ const writeNetReport = async report => {
134
126
  });
135
127
  request.write(JSON.stringify(report, null, 2));
136
128
  request.end();
137
- console.log(`Report with ID ${report.id} submitted`);
129
+ console.log(`Report ${report.timeStamp}-${report.script.id} submitted`);
138
130
  });
139
131
  return ack;
140
132
  };
141
133
  // 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`);
134
+ const archiveJob = async script => {
135
+ const jobJSON = JSON.stringify(script, null, 2);
136
+ await fs.writeFile(`${doneDir}/${script.timeStamp}-${script.id}.json`, jobJSON);
137
+ await fs.rm(`${watchDir}/${script.id}.json`);
146
138
  };
147
139
  // Waits.
148
140
  const wait = ms => {
@@ -152,117 +144,84 @@ const wait = ms => {
152
144
  }, ms);
153
145
  });
154
146
  };
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;
147
+ // Runs a script, time-stamps it, and returns a report.
148
+ const runJob = async script => {
149
+ const {id} = script;
150
+ if (id) {
151
+ try {
152
+ // Identify the start time and a time stamp.
153
+ const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
154
+ script.timeStamp = timeStamp;
155
+ // Initialize a report.
156
+ const report = {
157
+ log: [],
158
+ script,
159
+ acts: []
160
+ };
161
+ await doJob(report);
162
+ if (watchType === 'dir') {
163
+ return await writeDirReport(report);
164
+ }
165
+ else {
166
+ const ack = await writeNetReport(report);
167
+ if (ack.error) {
168
+ console.log(JSON.stringify(ack, null, 2));
169
+ return false;
203
170
  }
204
- // Otherwise, i.e. if there is no batch:
205
171
  else {
206
- // Run the script and submit a report with a timestamp ID.
207
- return await runHost(jobID, timeStamp, timeStamp, script);
172
+ return true;
208
173
  }
209
174
  }
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
175
  }
217
- else {
218
- console.log('ERROR: no script specified');
176
+ catch(error) {
177
+ console.log(`ERROR: ${error.message}\n${error.stack}`);
219
178
  return {
220
- error: 'ERROR: no script specified'
179
+ error: `ERROR: ${error.message}\n${error.stack}`
221
180
  };
222
181
  }
223
182
  }
224
183
  else {
225
- console.log('ERROR: no job ID property in job');
184
+ console.log('ERROR: script has no id');
226
185
  return {
227
- error: 'ERROR: no job ID property in job'
186
+ error: 'ERROR: script has no id'
228
187
  };
229
188
  }
230
189
  };
231
- // Repeatedly checks for jobs, runs them, and submits reports.
190
+ // Checks for a job, performs it, and submits a report, once or repeatedly.
232
191
  const cycle = async forever => {
233
- const intervalMS = Number.parseInt(interval);
192
+ const intervalMS = 1000 * Number.parseInt(interval);
234
193
  let statusOK = true;
235
194
  let empty = false;
236
195
  console.log(`Watching started with intervals of ${interval} seconds when idle`);
237
196
  while (statusOK) {
238
197
  if (empty) {
239
- await wait(1000 * intervalMS);
198
+ await wait(intervalMS);
240
199
  }
241
200
  // Check for a job.
242
- let job;
201
+ let script;
243
202
  if (watchType === 'dir') {
244
- job = await checkDirJob();
203
+ script = await checkDirJob();
245
204
  }
246
205
  else if (watchType === 'net') {
247
- job = await checkNetJob();
206
+ script = await checkNetJob();
248
207
  }
249
208
  else {
250
- job = {};
209
+ script = {};
251
210
  console.log('ERROR: invalid WATCH_TYPE environment variable');
252
211
  statusOK = false;
253
212
  }
254
213
  // 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}`);
214
+ if (script.id) {
215
+ // Run it, add a timestamp to it, and save a report.
216
+ console.log(`Running script ${script.id}`);
217
+ statusOK = await runJob(script);
218
+ console.log(`Job ${script.id} finished with time stamp ${script.timeStamp}`);
260
219
  if (statusOK) {
261
- // If the job was a file:
220
+ // If the script was in a directory:
262
221
  if (watchType === 'dir') {
263
- // Archive it.
264
- await exifyJob(job);
265
- console.log(`Job archived as ${job.timeStamp}.json`);
222
+ // Archive the script.
223
+ await archiveJob(script);
224
+ console.log(`Script ${script.id}.json archived as ${script.timeStamp}-${script.id}.json`);
266
225
  }
267
226
  // If watching was specified for only 1 job, stop.
268
227
  statusOK = forever;