testilo 2.0.3 → 3.1.0

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.
@@ -0,0 +1,381 @@
1
+ /*
2
+ index: digester for procedure tsp09.
3
+ Creator of parameters for substitution into index.html.
4
+ */
5
+ exports.makeQuery = (report, query) => {
6
+ // Makes strings HTML-safe.
7
+ const htmlEscape = textOrNumber => textOrNumber
8
+ .toString()
9
+ .replace(/&/g, '&')
10
+ .replace(/</g, '&lt;');
11
+ // Newlines with indentations.
12
+ const joiner = '\n ';
13
+ const innerJoiner = '\n ';
14
+ // Create an HTML identification of the host report.
15
+ const {id, script, acts, host, score} = report;
16
+ // Creates a packaged-test success message.
17
+ const packageSucceedText = package =>
18
+ `<p>The page <strong>passed</strong> the <code>${package}</code> test.</p>`;
19
+ // Creates a packaged-test failure message.
20
+ const packageFailText = (score, package, failures) =>
21
+ `<p>The page <strong>did not pass</strong> the <code>${package}</code> test and received a score of ${score} on <code>${package}</code>. The details are in the appended report, in the section starting with <code>"which": "${package}"</code>. There was at least one failure of:</p>${joiner}<ul>${innerJoiner}${failures}${joiner}</ul>`;
22
+ // Creates a custom-test success message.
23
+ const customSucceedText =
24
+ test => `<p>The page <strong>passed</strong> the <code>${test}</code> test.</p>`;
25
+ // Creates a custom-test failure message.
26
+ const customFailText = (score, test) =>
27
+ `<p>The page <strong>did not pass</strong> the <code>${test}</code> test and received a score of ${score} on <code>${test}</code>. The details are in the appended report, in the section starting with <code>"which": "${test}"</code>.</p>`;
28
+ // Creates a test unperformability message.
29
+ const testCrashText = (score, test) => `<p>The <code>${test}</code> test could not be performed. The page received an inferred score of ${score} on <code>${test}</code>.</p>`;
30
+ // Creates the HTML items in a list of a custom test’s failures.
31
+ const customFailures = failObj => Object
32
+ .entries(failObj)
33
+ .map(entry => `<li>${entry[0]}: ${entry[1]}</li>`)
34
+ .join(innerJoiner);
35
+ // Creates an HTML summary of the details of a custom test’s failures.
36
+ const customFailMore = failures =>
37
+ `<p>Summary of the details:</p>${joiner}<ul>${innerJoiner}${failures}${joiner}</ul>`;
38
+ // Creates a combined HTML summary of a custom test’s failure result.
39
+ const customResult = (score, test, failures) =>
40
+ `${customFailText(score, test)}${joiner}${customFailMore(failures)}`;
41
+ // Returns the act of a test.
42
+ const actOf = testName => {
43
+ const matches = report.acts.filter(act => act.type === 'test' && act.which === testName);
44
+ if (matches.length) {
45
+ return matches[0];
46
+ }
47
+ else {
48
+ return null;
49
+ }
50
+ };
51
+ // Add the job data to the query.
52
+ query.dateISO = report.endTime.slice(0, 10);
53
+ query.dateSlash = query.dateISO.replace(/-/g, '/');
54
+ if (host) {
55
+ query.org = host.what;
56
+ query.url = host.which;
57
+ }
58
+ else {
59
+ const firstURLCommand = script.commands.find(command => command.type === 'url');
60
+ query.org = firstURLCommand.what;
61
+ query.url = firstURLCommand.which;
62
+ }
63
+ const {inferences, scores} = score;
64
+ query.totalScore = scores.total;
65
+ // Create rows of an HTML table of net scores.
66
+ const netScores = Object.assign({}, scores, inferences);
67
+ const scoreSources = Object.keys(netScores);
68
+ query.scoreRows = scoreSources
69
+ .sort((a, b) => netScores[b] - netScores[a])
70
+ .map(source => `<tr><th>${source}</th><td>${netScores[source]}</td></tr>`)
71
+ .join(innerJoiner);
72
+ // Get package-test result messages.
73
+ // aatt
74
+ if (scores.aatt) {
75
+ const testAct = actOf('aatt');
76
+ const aattWarnings = new Set(testAct.result.filter(item => item.type === 'warning')
77
+ .map(item => `warning: ${item.msg}`));
78
+ const aattErrors = new Set(testAct.result.filter(item => item.type === 'error')
79
+ .map(item => `error: ${item.msg}`));
80
+ const aattBoth = Array.from(aattWarnings).concat(Array.from(aattErrors));
81
+ const aattIssues = aattBoth.map(item => `<li>${htmlEscape(item)}</li>`).join(innerJoiner);
82
+ query.aattResult = packageFailText(scores.aatt, 'aatt', aattIssues);
83
+ }
84
+ else if (inferences.aatt) {
85
+ query.aattResult = testCrashText(inferences.aatt, 'aatt');
86
+ }
87
+ else {
88
+ query.aattResult = packageSucceedText('aatt');
89
+ }
90
+ // alfa
91
+ if (scores.alfa) {
92
+ const testAct = actOf('alfa');
93
+ const alfaWarnings = new Set(testAct.result.filter(item => item.verdict === 'cantTell')
94
+ .map(item => `warning: ${item.rule.ruleSummary}`));
95
+ const alfaErrors = new Set(testAct.result.filter(item => item.verdict === 'failed')
96
+ .map(item => `error: ${item.rule.ruleSummary}`));
97
+ const alfaBoth = Array.from(alfaWarnings).concat(Array.from(alfaErrors));
98
+ const alfaIssues = alfaBoth.map(item => `<li>${htmlEscape(item)}</li>`).join(innerJoiner);
99
+ query.alfaResult = packageFailText(scores.alfa, 'alfa', alfaIssues);
100
+ }
101
+ else if (inferences.alfa) {
102
+ query.alfaResult = testCrashText(inferences.alfa, 'alfa');
103
+ }
104
+ else {
105
+ query.alfaResult = packageSucceedText('alfa');
106
+ }
107
+ // axe
108
+ if (scores.axe) {
109
+ const testAct = actOf('axe');
110
+ const axeFailures = testAct.result.items.map(
111
+ item => `<li>${item.rule}: ${htmlEscape(item.description)}</li>`
112
+ ).join(innerJoiner);
113
+ query.axeResult = packageFailText(scores.axe, 'axe', axeFailures);
114
+ }
115
+ else if (inferences.axe) {
116
+ query.axeResult = testCrashText(inferences.axe, 'axe');
117
+ }
118
+ else {
119
+ query.axeResult = packageSucceedText('axe');
120
+ }
121
+ // ibm
122
+ if (scores.ibm) {
123
+ const testAct = actOf('ibm');
124
+ const {result} = testAct;
125
+ const contentItems = result.content.items;
126
+ const urlItems = result.url.items;
127
+ const items = [];
128
+ if (contentItems) {
129
+ items.push(...contentItems);
130
+ }
131
+ if (urlItems) {
132
+ items.push(...urlItems);
133
+ }
134
+ const ibmFailures = Array.from(new Set(items.map(
135
+ item => `<li>${item.ruleId}: ${htmlEscape(item.message)}</li>`
136
+ )).values()).join(innerJoiner);
137
+ query.ibmResult = packageFailText(scores.ibm, 'ibm', ibmFailures);
138
+ }
139
+ else if (inferences.ibm) {
140
+ query.ibmResult = testCrashText(inferences.ibm, 'ibm');
141
+ }
142
+ else {
143
+ query.ibmResult = packageSucceedText('ibm');
144
+ }
145
+ // wave
146
+ if (scores.wave) {
147
+ const testAct = actOf('wave');
148
+ const waveResult = testAct.result.categories;
149
+ const waveItems = [];
150
+ ['error', 'contrast', 'alert'].forEach(category => {
151
+ waveItems.push(
152
+ ... Object
153
+ .entries(waveResult[category].items)
154
+ .map(entry => `<li>${category}/${entry[0]}: ${entry[1].description}</li>`)
155
+ );
156
+ });
157
+ const waveFailures = waveItems.join(innerJoiner);
158
+ query.waveResult = packageFailText(scores.wave, 'wave', waveFailures);
159
+ }
160
+ else if (inferences.wave) {
161
+ query.waveResult = testCrashText(inferences.wave, 'wave');
162
+ }
163
+ else {
164
+ query.waveResult = packageSucceedText('wave');
165
+ }
166
+ // Get custom-test result messages.
167
+ if (scores.bulk) {
168
+ const testAct = actOf('bulk');
169
+ query.bulkResult = `The page <strong>did not pass</strong> the <code>bulk</code> test. The count of visible elements in the page was ${testAct.result.visibleElements}, resulting in a score of ${scores.bulk} on <code>bulk</code>.`;
170
+ }
171
+ else if (inferences.bulk) {
172
+ query.bulkResult = testCrashText(inferences.bulk, 'bulk');
173
+ }
174
+ else {
175
+ query.bulkResult = customSucceedText('bulk');
176
+ }
177
+ if (scores.embAc) {
178
+ const testAct = actOf('embAc');
179
+ const failures = customFailures(testAct.result.totals);
180
+ query.embAcResult = customResult(scores.embAc, 'embAc', failures);
181
+ }
182
+ else if (inferences.embAc) {
183
+ query.embAcResult = testCrashText(inferences.ebmAc, 'ebmAc');
184
+ }
185
+ else {
186
+ query.embAcResult = customSucceedText('embAc');
187
+ }
188
+ if (scores.focAll) {
189
+ const testAct = actOf('focAll');
190
+ const failures = customFailures(testAct.result);
191
+ query.focAllResult = customResult(scores.focAll, 'focAll', failures);
192
+ }
193
+ else if (inferences.focAll) {
194
+ query.focAllResult = testCrashText(inferences.focAll, 'focAll');
195
+ }
196
+ else {
197
+ query.focAllResult = customSucceedText('focAll');
198
+ }
199
+ if (scores.focInd) {
200
+ const testAct = actOf('focInd');
201
+ const failSource = testAct.result.totals.types;
202
+ const failObj = {
203
+ indicatorMissing: failSource.indicatorMissing.total,
204
+ nonOutlinePresent: failSource.nonOutlinePresent.total
205
+ };
206
+ const failures = customFailures(failObj);
207
+ query.focIndResult = customResult(scores.focInd, 'focInd', failures);
208
+ }
209
+ else if (inferences.focInd) {
210
+ query.focIndResult = testCrashText(inferences.focInd, 'focInd');
211
+ }
212
+ else {
213
+ query.focIndResult = customSucceedText('focInd');
214
+ }
215
+ if (scores.focOp) {
216
+ const testAct = actOf('focOp');
217
+ const failSource = testAct.result.totals.types;
218
+ const failObj = {
219
+ onlyFocusable: failSource.onlyFocusable.total,
220
+ onlyOperable: failSource.onlyOperable.total
221
+ };
222
+ const failures = customFailures(failObj);
223
+ query.focOpResult = customResult(scores.focOp, 'focOp', failures);
224
+ }
225
+ else if (inferences.focOp) {
226
+ query.focOpResult = testCrashText(inferences.focOp, 'focOp');
227
+ }
228
+ else {
229
+ query.focOpResult = customSucceedText('focOp');
230
+ }
231
+ if (scores.hover) {
232
+ const testAct = actOf('hover');
233
+ const failures = customFailures(testAct.result.totals);
234
+ query.hoverResult = customResult(scores.hover, 'hover', failures);
235
+ }
236
+ else if (inferences.hover) {
237
+ query.hoverResult = testCrashText(inferences.hover, 'hover');
238
+ }
239
+ else {
240
+ query.hoverResult = customSucceedText('hover');
241
+ }
242
+ if (scores.labClash) {
243
+ const testAct = actOf('labClash');
244
+ const {totals} = testAct.result;
245
+ delete totals.wellLabeled;
246
+ const failures = customFailures(totals);
247
+ query.labClashResult = customResult(scores.labClash, 'labClash', failures);
248
+ }
249
+ else if (inferences.labClash) {
250
+ query.labClashResult = testCrashText(inferences.labClash, 'labClash');
251
+ }
252
+ else {
253
+ query.labClashResult = customSucceedText('labClash');
254
+ }
255
+ if (scores.linkUl) {
256
+ const testAct = actOf('linkUl');
257
+ const failures = customFailures(testAct.result.totals.inline);
258
+ query.linkUlResult = customResult(scores.linkUl, 'linkUl', failures);
259
+ }
260
+ else if (inferences.linkUl) {
261
+ query.linkUlResult = testCrashText(inferences.linkUl, 'linkUl');
262
+ }
263
+ else {
264
+ query.linkUlResult = customSucceedText('linkUl');
265
+ }
266
+ if (scores.log) {
267
+ const {logCount, logSize, visitRejectionCount, prohibitedCount, visitTimeoutCount} = report;
268
+ const logData = {logCount, logSize, visitRejectionCount, prohibitedCount, visitTimeoutCount};
269
+ const failures = customFailures(logData);
270
+ query.logResult = customResult(scores.log, 'log', failures);
271
+ }
272
+ else if (inferences.log) {
273
+ query.logResult = testCrashText(inferences.log, 'log');
274
+ }
275
+ else {
276
+ query.logResult = customSucceedText('log');
277
+ }
278
+ if (scores.menuNav) {
279
+ const testAct = actOf('menuNav');
280
+ const failSource = testAct.result.totals;
281
+ const failObj = {
282
+ navigations: failSource.navigations.all.incorrect,
283
+ menuItems: failSource.menuItems.incorrect,
284
+ menus: failSource.menus.incorrect
285
+ };
286
+ const failures = customFailures(failObj);
287
+ query.menuNavResult = customResult(scores.menuNav, 'menuNav', failures);
288
+ }
289
+ else if (inferences.menuNav) {
290
+ query.menuNavResult = testCrashText(inferences.menuNav, 'menuNav');
291
+ }
292
+ else {
293
+ query.menuNavResult = customSucceedText('menuNav');
294
+ }
295
+ if (scores.motion) {
296
+ const testAct = actOf('motion');
297
+ const {result} = testAct;
298
+ result.bytes = result.bytes.join(', ');
299
+ result.localRatios = result.localRatios.join(', ');
300
+ result.pixelChanges = result.pixelChanges.join(', ');
301
+ const failures = customFailures(result);
302
+ query.motionResult = customResult(scores.motion, 'motion', failures);
303
+ }
304
+ else if (inferences.motion) {
305
+ query.motionResult = testCrashText(inferences.motion, 'motion');
306
+ }
307
+ else {
308
+ query.motionResult = customSucceedText('motion');
309
+ }
310
+ if (scores.radioSet) {
311
+ const testAct = actOf('radioSet');
312
+ const failures = customFailures(testAct.result.totals);
313
+ query.radioSetResult = customResult(scores.radioSet, 'radioSet', failures);
314
+ }
315
+ else if (inferences.radioSet) {
316
+ query.radioSetResult = testCrashText(inferences.radioSet, 'radioSet');
317
+ }
318
+ else {
319
+ query.radioSetResult = customSucceedText('radioSet');
320
+ }
321
+ if (scores.role) {
322
+ const testAct = actOf('role');
323
+ const {result} = testAct;
324
+ delete result.tagNames;
325
+ const failures = customFailures(result);
326
+ query.roleResult = customResult(scores.role, 'role', failures);
327
+ }
328
+ else if (inferences.role) {
329
+ query.roleResult = testCrashText(inferences.role, 'role');
330
+ }
331
+ else {
332
+ query.roleResult = customSucceedText('role');
333
+ }
334
+ if (scores.styleDiff) {
335
+ const testAct = actOf('styleDiff');
336
+ const {totals} = testAct.result;
337
+ const styleCounts = {};
338
+ Object.keys(totals).forEach(key => {
339
+ const data = totals[key];
340
+ const count = data.subtotals ? data.subtotals.length : 1;
341
+ styleCounts[key] = `${count} ${count === 1 ? 'style' : 'different styles'}`;
342
+ });
343
+ const failures = customFailures(styleCounts);
344
+ query.styleDiffResult = customResult(scores.styleDiff, 'styleDiff', failures);
345
+ }
346
+ else if (inferences.styleDiff) {
347
+ query.styleDiffResult = testCrashText(inferences.styleDiff, 'styleDiff');
348
+ }
349
+ else {
350
+ query.roleResult = customSucceedText('role');
351
+ }
352
+ if (scores.tabNav) {
353
+ const testAct = actOf('tabNav');
354
+ const failSource = testAct.result.totals;
355
+ const failObj = {
356
+ navigations: failSource.navigations.all.incorrect,
357
+ tabElements: failSource.tabElements.incorrect,
358
+ tabLists: failSource.tabLists.incorrect
359
+ };
360
+ const failures = customFailures(failObj);
361
+ query.tabNavResult = customResult(scores.tabNav, 'tabNav', failures);
362
+ }
363
+ else if (inferences.tabNav) {
364
+ query.tabNavResult = testCrashText(inferences.tabNav, 'tabNav');
365
+ }
366
+ else {
367
+ query.tabNavResult = customSucceedText('tabNav');
368
+ }
369
+ if (scores.zIndex) {
370
+ const testAct = actOf('zIndex');
371
+ const {tagNames} = testAct.result.totals;
372
+ const failures = customFailures(tagNames);
373
+ query.zIndexResult = customResult(scores.zIndex, 'zIndex', failures);
374
+ }
375
+ else if (inferences.zIndex) {
376
+ query.zIndexResult = testCrashText(inferences.zIndex, 'zIndex');
377
+ }
378
+ else {
379
+ query.zIndexResult = customSucceedText('zIndex');
380
+ }
381
+ };