testaro 2.0.4 → 2.1.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.md CHANGED
@@ -413,33 +413,28 @@ A batch offers an efficient way to perform a uniform set of operations on every
413
413
 
414
414
  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.
415
415
 
416
- ## Reports
417
-
418
- Testaro writes reports as files in JSON format. They contain detailed results.
419
-
420
- Testaro also writes to standard output a list of the names of the files containing the reports.
421
-
422
416
  ## Execution
423
417
 
424
418
  ### Invocation
425
419
 
426
- To run Testaro, create an _invocation_ file like this:
420
+ To run Testaro, create an options object like this:
427
421
 
428
422
  ```javascript
429
- const options = {
430
- reports: `${__readdir}/path/to/reports/directory`,
431
- batch: `${__readdir}/path/to/batch/file.json`,
432
- script: `${__readdir}/path/to/script/file.json`
433
- };
434
- const {handleRequest} = require('testaro');
435
- handleRequest(options);
423
+ {
424
+ log: [],
425
+ reports: [],
426
+ script: {abc},
427
+ batch: {def}
428
+ }
436
429
  ```
437
430
 
438
- The `batch` option is optional. If there is no batch, omit it.
431
+ Replace `{abc}` with a script object, like the example script shown above.
432
+
433
+ Replace `{def}` with a batch object, like the example batch shown above, or omit the `batch` property if there is no batch.
439
434
 
440
- The paths are relative to the directory containing the file. So, if the script file is `script.json` and is in the same directory as the invocation file, the path would be `${__readdir}/script.json`.
435
+ Then execute the statement `require('testaro').handleRequest(ghi)`, where `ghi` is replaced with the name of the options object. That statement will run Testaro.
441
436
 
442
- If the invocation file is named `runTestaro.js`, execute it with the statement `node runTestaro`.
437
+ While it runs, Testaro will populate the `log` and `reports` arrays of the options object. When Testaro finishes, the `log` and `reports` arrays will contain its results.
443
438
 
444
439
  ### Environment variables
445
440
 
package/commands.js CHANGED
@@ -215,12 +215,6 @@ exports.commands = {
215
215
  withItems: [true, 'boolean']
216
216
  }
217
217
  ],
218
- roleList: [
219
- 'Perform a roleList test',
220
- {
221
- withItems: [true, 'boolean']
222
- }
223
- ],
224
218
  styleDiff: [
225
219
  'Perform a styleDiff test',
226
220
  {
package/index.js CHANGED
@@ -1068,7 +1068,7 @@ const doActs = async (report, actIndex, page) => {
1068
1068
  await doActs(report, actIndex + 1, page);
1069
1069
  }
1070
1070
  };
1071
- // Performs the commands in a script and returns a report.
1071
+ // Performs the commands in a script.
1072
1072
  const doScript = async (options, report) => {
1073
1073
  // Reinitialize the log statistics.
1074
1074
  logCount = logSize = prohibitedCount = visitTimeoutCount = visitRejectionCount= 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro",
3
- "version": "2.0.4",
3
+ "version": "2.1.1",
4
4
  "description": "Automation of accessibility testing",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,508 @@
1
+ /*
2
+ asp09
3
+ Autotest score proc 9
4
+ Computes and reports a score from 4 packages and 16 custom tests, with discounts.
5
+ */
6
+ exports.scorer = acts => {
7
+ // CONSTANTS
8
+ // Define the configuration disclosures.
9
+ // Configure log scoring as active and set its weights.
10
+ const logWeights = {
11
+ count: 0.5,
12
+ size: 0.01,
13
+ prohibited: 15,
14
+ visitTimeout: 10,
15
+ visitRejection: 10
16
+ };
17
+ const rules = {
18
+ aatt: '',
19
+ alfa:'',
20
+ axe: '',
21
+ bulk: '',
22
+ embAc: '',
23
+ focAll: '',
24
+ focInd: '',
25
+ focOp: '',
26
+ hover: '',
27
+ ibm: '',
28
+ labClash: '',
29
+ linkUl: '',
30
+ log: 'multiply log items by respective logWeights; sum',
31
+ menuNav: '',
32
+ motion: '',
33
+ radioSet: '',
34
+ role: '',
35
+ styleDiff: '',
36
+ tabNav: '',
37
+ zIndex: ''
38
+ };
39
+ let duplications = {};
40
+ const diffStyles = [
41
+ 'borderStyle',
42
+ 'borderWidth',
43
+ 'fontStyle',
44
+ 'fontWeight',
45
+ 'lineHeight',
46
+ 'maxHeight',
47
+ 'maxWidth',
48
+ 'minHeight',
49
+ 'minWidth',
50
+ 'opacity',
51
+ 'outlineOffset',
52
+ 'outlineStyle',
53
+ 'outlineWidth',
54
+ 'textDecorationLine',
55
+ 'textDecorationStyle',
56
+ 'textDecorationThickness'
57
+ ];
58
+ // Initialize the score.
59
+ const inferences = {};
60
+ let deficit = {
61
+ total: 0,
62
+ aatt: null,
63
+ alfa: null,
64
+ axe: null,
65
+ bulk: null,
66
+ embAc: null,
67
+ focAll: null,
68
+ focInd: null,
69
+ focOp: null,
70
+ hover: null,
71
+ ibm: null,
72
+ labClash: null,
73
+ linkUl: null,
74
+ log: null,
75
+ menuNav: null,
76
+ motion: null,
77
+ radioSet: null,
78
+ role: null,
79
+ styleDiff: null,
80
+ tabNav: null,
81
+ zIndex: null
82
+ };
83
+ // VARIABLES
84
+ let facts;
85
+ // If there are any acts:
86
+ if (Array.isArray(acts)) {
87
+ // If any of them are tests:
88
+ const tests = acts.filter(act => act.type === 'test');
89
+ if (tests.length) {
90
+ // CONSTANTS
91
+ // Empirically derived counts of duplications of package rules.
92
+ duplications = {
93
+ 'aatt': {
94
+ 'e:F77': 1,
95
+ 'e:H36': 4,
96
+ 'e:H37': 2,
97
+ 'e:H57': 3,
98
+ 'e:H58': 2,
99
+ 'w:G141': 3,
100
+ 'w:H98': 1,
101
+ 'e:ARIA6+H53': 1,
102
+ 'e:H24': 2,
103
+ 'e:G1+G123+G124': 1,
104
+ 'w:G90': 1,
105
+ 'w:H44': 1
106
+ },
107
+ 'alfa': {
108
+ 'r3': 2,
109
+ 'r28': 4,
110
+ 'r2': 2,
111
+ 'r4': 3,
112
+ 'r7': 2,
113
+ 'r53': 3,
114
+ 'r10': 1,
115
+ 'r11': 1,
116
+ 'r12': 2,
117
+ 'r20': 1,
118
+ 'r42': 1,
119
+ 'r43': 1,
120
+ 'r47': 1,
121
+ 'r5': 2,
122
+ 'r68': 1,
123
+ 'r93': 1,
124
+ 'r13': 1
125
+ },
126
+ 'axe': {
127
+ 'input-image-alt': 4,
128
+ 'html-has-lang': 3,
129
+ 'valid-lang': 2,
130
+ 'heading-order': 3,
131
+ 'link-name': 2,
132
+ 'aria-command-name': 2,
133
+ 'dlitem': 1,
134
+ 'image-alt': 2,
135
+ 'duplicate-id': 1,
136
+ 'aria-required-parent': 1,
137
+ 'svg-img-alt': 1,
138
+ 'meta-viewport': 1,
139
+ 'html-lang-valid': 2,
140
+ 'aria-required-children': 1,
141
+ 'avoid-inline-spacing': 1,
142
+ 'area-alt': 2,
143
+ 'aria-allowed-role': 1,
144
+ 'aria-required-attr': 1,
145
+ 'aria-valid-attr': 1,
146
+ 'autocomplete-valid': 1,
147
+ 'color-contrast': 1,
148
+ 'empty-heading': 2,
149
+ 'frame-title': 1,
150
+ 'image-redundant-alt': 1,
151
+ 'landmark-complementary-is-top-level': 2,
152
+ 'landmark-no-duplicate-banner': 1,
153
+ 'landmark-no-duplicate-main': 2,
154
+ 'document-title': 1,
155
+ 'object-alt': 1,
156
+ 'page-has-heading-one': 1,
157
+ 'select-name': 1
158
+ },
159
+ 'ibm': {
160
+ 'v:WCAG20_Object_HasText': 1,
161
+ 'v:WCAG20_Area_HasAlt': 2,
162
+ 'v:WCAG20_Input_ExplicitLabelImage': 4,
163
+ 'v:WCAG20_Frame_HasTitle': 2,
164
+ 'v:WCAG20_Elem_Lang_Valid': 2,
165
+ 'v:HAAC_Img_UsemapAlt': 1,
166
+ 'v:aria_semantics_role': 1,
167
+ 'v:Rpt_Aria_RequiredProperties': 1,
168
+ 'v:Rpt_Aria_ValidProperty': 1,
169
+ 'v:WCAG21_Input_Autocomplete': 1,
170
+ 'v:IBMA_Color_Contrast_WCAG2AA': 2,
171
+ 'v:RPT_Header_HasContent': 2,
172
+ 'v:WCAG20_Img_HasAlt': 2,
173
+ 'v:WCAG20_Img_LinkTextNotRedundant': 1,
174
+ 'v:Rpt_Aria_ComplementaryRequiredLabel_Implicit': 1,
175
+ 'v:Rpt_Aria_MultipleComplementaryLandmarks_Implicit': 1,
176
+ 'v:Rpt_Aria_MultipleBannerLandmarks_Implicit': 1,
177
+ 'r:Rpt_Aria_MultipleMainsVisibleLabel_Implicit': 1,
178
+ 'v:Rpt_Aria_MultipleMainsRequireLabel_Implicit_2': 1,
179
+ 'v:WCAG20_A_HasText': 1,
180
+ 'v:Rpt_Aria_ValidIdRef': 1,
181
+ 'v:WCAG20_Elem_UniqueAccessKey': 1,
182
+ 'v:WCAG20_Input_RadioChkInFieldSet': 1
183
+ }
184
+ };
185
+ // FUNCTIONS
186
+ // Adds the actual or inferred score of a test to the total score.
187
+ const increment = test => {
188
+ deficit.total += typeof deficit[test] === 'number' ? deficit[test] : inferences[test];
189
+ };
190
+ // OPERATION
191
+ // For each test:
192
+ tests.forEach(test => {
193
+ const {which} = test;
194
+ // Compute its score.
195
+ if (which === 'alfa') {
196
+ facts = test.result;
197
+ if (facts && Array.isArray(facts)) {
198
+ rules.alfa = 'multiply cantTell by 2*, failed by 4* (*discounted); sum';
199
+ deficit.alfa = Math.round(facts.reduce((total, issue) => {
200
+ const rawScore = [4, 2][['failed', 'cantTell'].indexOf(issue.verdict)] || 0;
201
+ const divisor = duplications.alfa[issue.rule.ruleID] + 1 || 1;
202
+ return total + rawScore / divisor;
203
+ }, 0));
204
+ deficit.total += deficit.alfa;
205
+ }
206
+ }
207
+ else if (which === 'aatt') {
208
+ facts = test.result;
209
+ if (facts && Array.isArray(facts)) {
210
+ rules.aatt = 'multiply warning by 2*, error by 4* (*discounted); sum';
211
+ const issues = facts.filter(fact => fact.type);
212
+ deficit.aatt = Math.round(issues.reduce((total, issue) => {
213
+ const rawScore = [4, 2][['error', 'warning'].indexOf(issue.type)] || 0;
214
+ const divisor = duplications.aatt[`${issue.type.slice(0, 1)}:${issue.id}`] + 1 || 1;
215
+ return total + rawScore / divisor;
216
+ }, 0));
217
+ deficit.total += deficit.aatt;
218
+ }
219
+ }
220
+ else if (which === 'axe') {
221
+ facts = test.result && test.result.items;
222
+ if (facts) {
223
+ rules.axe = 'multiply minor by 2*, moderate by 3*, serious by 4*, critical by 5* (*discounted); sum';
224
+ deficit.axe = Math.round(facts.reduce((total, item) => {
225
+ const rawScore = item.elements.length * (
226
+ [5, 4, 3, 2][['critical', 'serious', 'moderate', 'minor'].indexOf(item.impact)] || 0
227
+ );
228
+ const divisor = duplications.axe[item.rule] + 1 || 1;
229
+ return total + rawScore / divisor;
230
+ }, 0));
231
+ deficit.total += deficit.axe;
232
+ }
233
+ }
234
+ else if (which === 'ibm') {
235
+ facts = test.result;
236
+ if (facts && facts.content && facts.url && (facts.content.totals || facts.url.totals)) {
237
+ rules.ibm = 'multiply violations by 4*, recommendations by 2* (*discounted); sum';
238
+ const scores = {
239
+ content: null,
240
+ url: null
241
+ };
242
+ ['content', 'url'].forEach(type => {
243
+ const totals = facts[type].totals;
244
+ if (totals) {
245
+ const items = facts[type].items || [];
246
+ scores[type] = Math.round(items.reduce((total, item) => {
247
+ const {ruleId, level} = item;
248
+ const rawScore = [4, 2][['violation', 'recommendation'].indexOf(level)] || 0;
249
+ const divisor = duplications.ibm[`${level.slice(0, 1)}:${ruleId}`] + 1 || 1;
250
+ return total + rawScore / divisor;
251
+ }, 0));
252
+ }
253
+ });
254
+ if (scores.content !== null || scores.url !== null) {
255
+ deficit.ibm = Math.max(scores.content || 0, scores.url || 0);
256
+ deficit.total += deficit.ibm;
257
+ }
258
+ }
259
+ }
260
+ else if (which === 'bulk') {
261
+ facts = test.result && test.result.visibleElements;
262
+ if (typeof facts === 'number') {
263
+ rules.bulk = 'subtract 250 from visible elements; make 0 if negative; raise to 0.9th power; multiply by 0.15';
264
+ // Deficit: 15% of the excess, to the 0.9th power, of the element count over 250.
265
+ deficit.bulk = Math.floor(0.15 * Math.pow(Math.max(0, facts - 250), 0.9));
266
+ }
267
+ else {
268
+ inferences.bulk = 100;
269
+ }
270
+ increment('bulk');
271
+ }
272
+ else if (which === 'embAc') {
273
+ facts = test.result && test.result.totals;
274
+ if (facts) {
275
+ rules.embAc = 'multiply link- or button-contained links, buttons, inputs, and selects by 3 (discounted)';
276
+ deficit.embAc = 3 * (facts.links + facts.buttons + facts.inputs + facts.selects);
277
+ }
278
+ else {
279
+ inferences.embAc = 150;
280
+ }
281
+ increment('embAc');
282
+ }
283
+ else if (which === 'focAll') {
284
+ facts = test.result;
285
+ if (facts && typeof facts === 'object') {
286
+ rules.focAll= 'multiply discrepancy between focusable and focused element counts by 3';
287
+ deficit.focAll = 3 * Math.abs(facts.discrepancy);
288
+ }
289
+ else {
290
+ inferences.focAll = 150;
291
+ }
292
+ increment('focAll');
293
+ }
294
+ else if (which === 'focInd') {
295
+ facts = test.result && test.result.totals;
296
+ facts = facts ? facts.types : null;
297
+ if (facts) {
298
+ rules.focInd = 'multiply indicatorless-when-focused elements by 5';
299
+ deficit.focInd = 5 * facts.indicatorMissing.total + 3 * facts.nonOutlinePresent.total;
300
+ }
301
+ else {
302
+ inferences.focInd = 150;
303
+ }
304
+ increment('focInd');
305
+ }
306
+ else if (which === 'focOl') {
307
+ facts = test.result && test.result.totals;
308
+ facts = facts ? facts.types : null;
309
+ facts = facts ? facts.outlineMissing : null;
310
+ if (facts) {
311
+ rules.focOl = 'multiply non-outline focus indicators by 3, missing focus indicators by 5; sum';
312
+ deficit.focOl = 3 * facts.total;
313
+ }
314
+ else {
315
+ inferences.focOl = 100;
316
+ }
317
+ increment('focOl');
318
+ }
319
+ else if (which === 'focOp') {
320
+ facts = test.result && test.result.totals;
321
+ if (facts) {
322
+ rules.focOp = 'multiply nonfocusable operable elements by 4, nonoperable focusable by 1; sum';
323
+ deficit.focOp
324
+ = 4 * facts.types.onlyOperable.total + 1 * facts.types.onlyFocusable.total;
325
+ }
326
+ else {
327
+ inferences.focOp = 150;
328
+ }
329
+ increment('focOp');
330
+ }
331
+ else if (which === 'hover') {
332
+ facts = test.result && test.result.totals;
333
+ if (facts) {
334
+ rules.hover = 'multiply elements changing page on hover by 4, made visible by 2, with directly changed opacity by 0.1, with indirectly changed opacity by 0.2, unhoverable by 2; sum';
335
+ deficit.hover
336
+ = 4 * facts.triggers
337
+ + 2 * facts.madeVisible
338
+ + Math.floor(0.1 * facts.opacityChanged)
339
+ + Math.floor(0.2 * facts.opacityAffected)
340
+ + 2 * facts.unhoverables;
341
+ }
342
+ else {
343
+ inferences.hover = 150;
344
+ }
345
+ increment('hover');
346
+ }
347
+ else if (which === 'labClash') {
348
+ facts = test.result && test.result.totals;
349
+ if (facts) {
350
+ rules.labClash = 'multiply conflictually labeled elements by 2, unlabeled elements by 2; sum';
351
+ // Unlabeled elements discounted.
352
+ deficit.labClash = 2 * facts.mislabeled + 2 * facts.unlabeled;
353
+ }
354
+ else {
355
+ inferences.labClash = 100;
356
+ }
357
+ increment('labClash');
358
+ }
359
+ else if (which === 'linkUl') {
360
+ facts = test.result && test.result.totals;
361
+ facts = facts ? facts.inline : null;
362
+ if (facts) {
363
+ rules.linkUl = 'multiply nonunderlined inline links by 3';
364
+ deficit.linkUl = 3 * (facts.total - facts.underlined);
365
+ }
366
+ else {
367
+ inferences.linkUl = 150;
368
+ }
369
+ increment('linkUl');
370
+ }
371
+ else if (which === 'menuNav') {
372
+ facts = test.result && test.result.totals && test.result.totals.navigations;
373
+ if (facts) {
374
+ rules.menuNav = 'multiply Home and End errors by 1 and other key-navigation errors by 3; sum';
375
+ deficit.menuNav
376
+ = 3 * facts.all.incorrect
377
+ - 2 * (facts.specific.home.incorrect + facts.specific.end.incorrect);
378
+ }
379
+ else {
380
+ inferences.menuNav = 150;
381
+ }
382
+ increment('menuNav');
383
+ }
384
+ else if (which === 'motion') {
385
+ facts = test.result;
386
+ if (facts && facts.bytes) {
387
+ rules.motion = 'get PNG screenshot sizes (sss); get differing-pixel counts between adjacent PNG screenshots (pd); “sssd” = sss difference ÷ smaller sss - 1; multiply mean adjacent sssd by 5, maximum adjacent sssd by 2, maximum over-all ssd by 1; divide mean pd by 10,000, maximum pd by 25,000; multiply count of non-0 pd by 30; sum';
388
+ deficit.motion = Math.floor(
389
+ 5 * (facts.meanLocalRatio - 1)
390
+ + 2 * (facts.maxLocalRatio - 1)
391
+ + facts.globalRatio - 1
392
+ + facts.meanPixelChange / 10000
393
+ + facts.maxPixelChange / 25000
394
+ + 30 * facts.changeFrequency
395
+ );
396
+ }
397
+ else {
398
+ inferences.motion = 150;
399
+ }
400
+ increment('motion');
401
+ }
402
+ else if (which === 'radioSet') {
403
+ facts = test.result && test.result.totals;
404
+ if (facts) {
405
+ rules.radioSet = 'multiply radio buttons not in fieldsets with legends and no other-name radio buttons by 2';
406
+ // Defects discounted.
407
+ deficit.radioSet = 2 * (facts.total - facts.inSet);
408
+ }
409
+ else {
410
+ inferences.radioSet = 100;
411
+ }
412
+ increment('radioSet');
413
+ }
414
+ else if (which === 'role') {
415
+ facts = test.result && test.result.badRoleElements;
416
+ if (typeof facts === 'number') {
417
+ rules.role = 'multiple role attributes with invalid or native-HTML-equivalent values by 2';
418
+ // Defects discounted.
419
+ deficit.role = 2 * facts;
420
+ }
421
+ else {
422
+ inferences.role = 100;
423
+ }
424
+ increment('role');
425
+ }
426
+ else if (which === 'styleDiff') {
427
+ facts = test.result && test.result.totals;
428
+ if (facts) {
429
+ rules.styleDiff = 'for each of element classes block a, inline a, button, h1, h2, h3, h4, h5, and h6, get diffStyles-distinct styles; multiply their count minus 1 by 2; multiply count of elements with non-plurality styles by 0.2; sum';
430
+ // Identify objects having the tag-name totals and style distributions as properties.
431
+ const tagNameCounts = Object.values(facts);
432
+ // Identify an array of pairs of counts of excess styles and nonplurality elements.
433
+ const deficits = tagNameCounts.map(
434
+ item => {
435
+ const subtotals = item.subtotals ? item.subtotals : [item.total];
436
+ return [subtotals.length - 1, item.total - subtotals[0]];
437
+ }
438
+ );
439
+ // Deficit: 2 per excess style + 0.2 per nonplurality element.
440
+ deficit.styleDiff = Math.floor(deficits.reduce(
441
+ (total, currentPair) => total + 2 * currentPair[0] + 0.2 * currentPair[1], 0
442
+ ));
443
+ }
444
+ else {
445
+ inferences.styleDiff = 100;
446
+ }
447
+ increment('styleDiff');
448
+ }
449
+ else if (which === 'tabNav') {
450
+ facts = test.result && test.result.totals && test.result.totals.navigations;
451
+ if (facts) {
452
+ rules.tabNav = 'multiply Home and End errors by 1 and other key-navigation errors by 3; sum';
453
+ deficit.tabNav
454
+ = 3 * facts.all.incorrect
455
+ - 2 * (facts.specific.home.incorrect + facts.specific.end.incorrect);
456
+ }
457
+ else {
458
+ inferences.tabNav = 150;
459
+ }
460
+ increment('tabNav');
461
+ }
462
+ else if (which === 'zIndex') {
463
+ facts = test.result && test.result.totals;
464
+ if (facts) {
465
+ rules.zIndex = 'multiply non-auto z indexes by 3';
466
+ deficit.zIndex = 3 * facts.total;
467
+ }
468
+ else {
469
+ inferences.zIndex = 100;
470
+ }
471
+ increment('zIndex');
472
+ }
473
+ });
474
+ // Compute the inferred scores of package tests that failed and adjust the total score.
475
+ const estimate = (tests, penalty) => {
476
+ const packageScores = tests.map(test => deficit[test]).filter(score => score !== null);
477
+ const scoreCount = packageScores.length;
478
+ let meanScore;
479
+ if (scoreCount) {
480
+ meanScore = Math.floor(
481
+ packageScores.reduce((sum, current) => sum + current) / packageScores.length
482
+ );
483
+ }
484
+ else {
485
+ meanScore = 100;
486
+ }
487
+ tests.forEach(test => {
488
+ if (deficit[test] === null) {
489
+ inferences[test] = meanScore + penalty;
490
+ deficit.total += inferences[test];
491
+ }
492
+ });
493
+ };
494
+ estimate(['aatt', 'axe', 'ibm'], 100);
495
+ }
496
+ }
497
+ // Return the score facts, except for the log test.
498
+ return {
499
+ scoreProc: 'asp',
500
+ version: '9',
501
+ duplications,
502
+ rules,
503
+ diffStyles,
504
+ logWeights,
505
+ inferences,
506
+ deficit
507
+ };
508
+ };
@@ -5,9 +5,9 @@
5
5
  */
6
6
  const fs = require('fs');
7
7
  const compile = () => {
8
- const issuesJSON = fs.readFileSync('scoring/package/issues.json', 'utf8');
8
+ const issuesJSON = fs.readFileSync(`${__dirname}/scoring/package/issues.json`, 'utf8');
9
9
  const issues = JSON.parse(issuesJSON);
10
- const dataJSON = fs.readFileSync('scoring/package/data.json', 'utf8');
10
+ const dataJSON = fs.readFileSync(`${__dirname}/scoring/package/data.json`, 'utf8');
11
11
  const reportData = JSON.parse(dataJSON);
12
12
  const reports = Object.values(reportData);
13
13
  // Initialize the list.
@@ -71,4 +71,6 @@ const compile = () => {
71
71
  });
72
72
  return data;
73
73
  };
74
- fs.writeFileSync('scoring/package/correlations.json', JSON.stringify(compile(), null, 2));
74
+ fs.writeFileSync(
75
+ `${__dirname}/scoring/package/correlations.json`, JSON.stringify(compile(), null, 2)
76
+ );
@@ -7,7 +7,7 @@
7
7
  */
8
8
  const fs = require('fs');
9
9
  const compile = () => {
10
- const dupsJSON = fs.readFileSync('scoring/package/duplications.json', 'utf8');
10
+ const dupsJSON = fs.readFileSync(`${__dirname}/scoring/package/duplications.json`, 'utf8');
11
11
  const dups = JSON.parse(dupsJSON);
12
12
  // Initialize the object.
13
13
  const data = {
@@ -36,4 +36,4 @@ const compile = () => {
36
36
  });
37
37
  return data;
38
38
  };
39
- fs.writeFileSync('scoring/package/dupCounts.json', JSON.stringify(compile(), null, 2));
39
+ fs.writeFileSync(`${__dirname}/scoring/package/dupCounts.json`, JSON.stringify(compile(), null, 2));
@@ -120,7 +120,7 @@ const compilers = {
120
120
  };
121
121
  const repo = process.argv[2];
122
122
  const compile = repo => {
123
- const dirPath = `../${repo}/reports/script`;
123
+ const dirPath = `${__dirname}/../${repo}/reports/script`;
124
124
  const batchDirNames = fs
125
125
  .readdirSync(dirPath, {withFileTypes: true})
126
126
  .filter(dirEnt => dirEnt.isDirectory())
@@ -168,4 +168,4 @@ const compile = repo => {
168
168
  });
169
169
  return data;
170
170
  };
171
- fs.writeFileSync('scoring/package/data.json', JSON.stringify(compile(repo), null, 2));
171
+ fs.writeFileSync(`${__dirname}/scoring/package/data.json`, JSON.stringify(compile(repo), null, 2));
@@ -4,7 +4,7 @@
4
4
  */
5
5
  const fs = require('fs');
6
6
  const compile = () => {
7
- const dataJSON = fs.readFileSync('scoring/package/data.json', 'utf8');
7
+ const dataJSON = fs.readFileSync(`${__dirname}/scoring/package/data.json`, 'utf8');
8
8
  const reportData = JSON.parse(dataJSON);
9
9
  const reports = Object.values(reportData);
10
10
  const data = {
@@ -31,4 +31,4 @@ const compile = () => {
31
31
  wave: Array.from(data.wave).sort()
32
32
  };
33
33
  };
34
- fs.writeFileSync('scoring/package/issues.json', JSON.stringify(compile(), null, 2));
34
+ fs.writeFileSync(`${__dirname}/scoring/package/issues.json`, JSON.stringify(compile(), null, 2));
package/tests/radioSet.js CHANGED
@@ -12,7 +12,7 @@ exports.reporter = async (page, withItems) => {
12
12
  // If itemization is required:
13
13
  if (withItems) {
14
14
  // Add the body of the textOf function as a string to the array.
15
- const textOfBody = await fs.readFile('procs/test/textOf.txt', 'utf8');
15
+ const textOfBody = await fs.readFile(`${__dirname}/procs/test/textOf.txt`, 'utf8');
16
16
  args.push(textOfBody);
17
17
  }
18
18
  // Get the result data.