testaro 36.6.2 → 37.0.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.
- package/README.md +3 -7
- package/netWatch.js +1 -3
- package/package.json +1 -1
- package/run.js +0 -3
- package/testaro/headingAmb.js +6 -7
- package/testaro/styleDiff.js +2 -1
- package/testaro/tabNav.js +106 -70
- package/validation/tests/jobs/adbID.json +4 -5
- package/validation/tests/jobs/allCaps.json +4 -5
- package/validation/tests/jobs/allHidden.json +4 -5
- package/validation/tests/jobs/allSlanted.json +4 -5
- package/validation/tests/jobs/altScheme.json +4 -5
- package/validation/tests/jobs/attVal.json +4 -5
- package/validation/tests/jobs/autocomplete.json +4 -5
- package/validation/tests/jobs/bulk.json +4 -5
- package/validation/tests/jobs/buttonMenu.json +5 -6
- package/validation/tests/jobs/captionLoc.json +4 -5
- package/validation/tests/jobs/datalistRef.json +4 -5
- package/validation/tests/jobs/distortion.json +4 -5
- package/validation/tests/jobs/docType.json +4 -5
- package/validation/tests/jobs/dupAtt.json +4 -5
- package/validation/tests/jobs/elements.json +4 -6
- package/validation/tests/jobs/embAc.json +4 -5
- package/validation/tests/jobs/filter.json +4 -5
- package/validation/tests/jobs/focAll.json +4 -5
- package/validation/tests/jobs/focInd.json +4 -5
- package/validation/tests/jobs/focOp.json +4 -5
- package/validation/tests/jobs/focVis.json +4 -5
- package/validation/tests/jobs/headEl.json +4 -5
- package/validation/tests/jobs/headingAmb.json +9 -10
- package/validation/tests/jobs/hovInd.json +4 -5
- package/validation/tests/jobs/hover.json +4 -5
- package/validation/tests/jobs/hr.json +4 -5
- package/validation/tests/jobs/imageLink.json +4 -5
- package/validation/tests/jobs/labClash.json +4 -5
- package/validation/tests/jobs/legendLoc.json +4 -5
- package/validation/tests/jobs/lineHeight.json +4 -5
- package/validation/tests/jobs/linkAmb.json +4 -5
- package/validation/tests/jobs/linkExt.json +4 -5
- package/validation/tests/jobs/linkOldAtt.json +4 -5
- package/validation/tests/jobs/linkTitle.json +4 -5
- package/validation/tests/jobs/linkTo.json +4 -5
- package/validation/tests/jobs/linkUl.json +4 -5
- package/validation/tests/jobs/miniText.json +4 -5
- package/validation/tests/jobs/motion.json +4 -5
- package/validation/tests/jobs/nonTable.json +4 -5
- package/validation/tests/jobs/opFoc.json +4 -5
- package/validation/tests/jobs/optRoleSel.json +4 -5
- package/validation/tests/jobs/phOnly.json +4 -5
- package/validation/tests/jobs/pseudoP.json +4 -5
- package/validation/tests/jobs/radioSet.json +4 -5
- package/validation/tests/jobs/role.json +4 -5
- package/validation/tests/jobs/secHeading.json +4 -5
- package/validation/tests/jobs/styleDiff.json +4 -5
- package/validation/tests/jobs/tabNav.json +5 -13
- package/validation/tests/jobs/targetSize.json +4 -5
- package/validation/tests/jobs/textNodes.json +4 -6
- package/validation/tests/jobs/textSem.json +4 -5
- package/validation/tests/jobs/title.json +4 -6
- package/validation/tests/jobs/titledEl.json +4 -5
- package/validation/tests/jobs/zIndex.json +4 -5
- package/validation/tests/targets/headingAmb/index.html +2 -2
- package/validation/validateTest.js +2 -2
package/README.md
CHANGED
|
@@ -190,16 +190,12 @@ Job properties:
|
|
|
190
190
|
- `observe`: `true` or `false`, indicating whether tool and Testaro-rule invocations are to be reported to the server as they occur, so that the server can update a waiting client.
|
|
191
191
|
- `timeStamp`: a string in `yymmddThhMM` format, specifying a date and time before which the job is not to be performed.
|
|
192
192
|
- `creationTimeStamp`: a string in `yymmddThhMM` format, describing when the job was created.
|
|
193
|
-
- `sources`: an object describing where the job came from
|
|
194
|
-
- `script`: the ID of the script (as used by Testilo) from which the job was made, or an empty string if none.
|
|
195
|
-
- `batch` : the ID of the batch (as used by Testilo) from which the target of this job was drawn, or an empty string if none.
|
|
196
|
-
- `lastTarget`: whether the the target was drawn from a batch and is the last target in the batch.
|
|
197
|
-
- `target`: an object whose `id`, `what`, and `which` properties describe the target being tested by this job, or, if there was no batch, have empty strings as values.
|
|
198
|
-
- `requester`: the email address that can receive a notice of completion of the job, or an empty string if no notice is to be sent.
|
|
193
|
+
- `sources`: an object describing where the job came from. It may be an empty object, or an object containing any properties required by the job creator.
|
|
199
194
|
- `creationTimeStamp`: the date and time in `yymmddThhMM` format when the job was created.
|
|
200
195
|
- `timeStamp`: the date and time in `yymmddThhMM` format before which the job is not to be assigned.
|
|
201
196
|
- `sendReportTo`: the URL to which the report of the job is to be sent, or an empty string if the report is not to be sent to a server.
|
|
202
|
-
|
|
197
|
+
|
|
198
|
+
The job creator may add other properties (such as `mergeID` in this example) to a job.
|
|
203
199
|
|
|
204
200
|
### Reports
|
|
205
201
|
|
package/netWatch.js
CHANGED
|
@@ -149,7 +149,7 @@ exports.netWatch = async (isForever, intervalInSeconds, isCertTolerant = true) =
|
|
|
149
149
|
resolve(true);
|
|
150
150
|
}
|
|
151
151
|
// Otherwise, if the server sent a valid job:
|
|
152
|
-
else if (id && sources
|
|
152
|
+
else if (id && sources) {
|
|
153
153
|
// Restart the cycle.
|
|
154
154
|
cycleIndex = -1;
|
|
155
155
|
// Prevent further watching, if unwanted.
|
|
@@ -159,9 +159,7 @@ exports.netWatch = async (isForever, intervalInSeconds, isCertTolerant = true) =
|
|
|
159
159
|
// If the job specifies a report destination:
|
|
160
160
|
if (sendReportTo) {
|
|
161
161
|
// Perform the job, adding result data to it.
|
|
162
|
-
const target = sources.target.which;
|
|
163
162
|
console.log(`${logStart}job ${id} (${nowString()})`);
|
|
164
|
-
console.log(`>> It will test ${target}`);
|
|
165
163
|
console.log(`>> It will send report to ${sendReportTo}`);
|
|
166
164
|
await doJob(contentObj);
|
|
167
165
|
let reportJSON = JSON.stringify(contentObj, null, 2);
|
package/package.json
CHANGED
package/run.js
CHANGED
|
@@ -295,9 +295,6 @@ const isValidReport = report => {
|
|
|
295
295
|
if (! sources || typeof sources !== 'object') {
|
|
296
296
|
return 'Bad report sources';
|
|
297
297
|
}
|
|
298
|
-
if (typeof sources.script !== 'string') {
|
|
299
|
-
return 'Bad source script';
|
|
300
|
-
}
|
|
301
298
|
if (
|
|
302
299
|
! (creationTimeStamp && typeof creationTimeStamp === 'string' && dateOf(creationTimeStamp))
|
|
303
300
|
) {
|
package/testaro/headingAmb.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
2
|
+
© 2023–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -49,12 +49,11 @@ exports.reporter = async (page, withItems) => {
|
|
|
49
49
|
// For each heading:
|
|
50
50
|
headings.forEach((heading, index) => {
|
|
51
51
|
// Get its level.
|
|
52
|
-
const level = heading.
|
|
53
|
-
// If there are prior non-inferior headings and the last one has the same-level and text:
|
|
52
|
+
const level = heading.tagName[1];
|
|
54
53
|
// Get the prior headings.
|
|
55
54
|
const priorHeadings = headings.slice(0, index);
|
|
56
55
|
// Get the non-inferior ones among them.
|
|
57
|
-
const nonInferiors = priorHeadings.filter(priorHeading => priorHeading.
|
|
56
|
+
const nonInferiors = priorHeadings.filter(priorHeading => priorHeading.tagName[1] <= level);
|
|
58
57
|
// If there are any:
|
|
59
58
|
const nonInferiorCount = nonInferiors.length;
|
|
60
59
|
if (nonInferiorCount) {
|
|
@@ -85,7 +84,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
85
84
|
// Add a standard instance.
|
|
86
85
|
standardInstances.push({
|
|
87
86
|
ruleID: 'headingAmb',
|
|
88
|
-
what: 'Heading has the same text as
|
|
87
|
+
what: 'Heading has the same text as the prior same-level sibling heading',
|
|
89
88
|
ordinalSeverity: 1,
|
|
90
89
|
tagName: elData.tagName,
|
|
91
90
|
id: elData.id,
|
|
@@ -96,7 +95,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
96
95
|
// Otherwise, i.e. if it does not exist:
|
|
97
96
|
else {
|
|
98
97
|
// Report this.
|
|
99
|
-
console.log('ERROR: Reportedly same-text sibling heading not found');
|
|
98
|
+
console.log('ERROR: Reportedly same-text adjacent sibling heading not found');
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
101
|
}
|
|
@@ -105,7 +104,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
105
104
|
// Add a summary instance.
|
|
106
105
|
standardInstances.push({
|
|
107
106
|
ruleID: 'headingAmb',
|
|
108
|
-
what: '
|
|
107
|
+
what: 'Adjacent sibling same-level headings have the same text',
|
|
109
108
|
ordinalSeverity: 1,
|
|
110
109
|
count: totals[1],
|
|
111
110
|
tagName: '',
|
package/testaro/styleDiff.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
© 2021–
|
|
2
|
+
© 2021–2024 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
5
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -273,6 +273,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
});
|
|
276
|
+
// Return the result.
|
|
276
277
|
return {
|
|
277
278
|
data,
|
|
278
279
|
totals,
|
package/testaro/tabNav.js
CHANGED
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
Standards are based on https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
+
// CONSTANTS
|
|
30
|
+
|
|
31
|
+
const data = {};
|
|
32
|
+
|
|
29
33
|
// FUNCTIONS
|
|
30
34
|
|
|
31
35
|
// Returns the text associated with an element.
|
|
@@ -105,7 +109,7 @@ const allText = async (page, elementHandle) => await page.evaluate(element => {
|
|
|
105
109
|
return textChain;
|
|
106
110
|
}, elementHandle);
|
|
107
111
|
// Returns the index of the focused tab in an array of tabs.
|
|
108
|
-
const focusedTab = async tabs => await page.evaluate(tabs => {
|
|
112
|
+
const focusedTab = async (tabs, page) => await page.evaluate(tabs => {
|
|
109
113
|
const focus = document.activeElement;
|
|
110
114
|
return tabs.indexOf(focus);
|
|
111
115
|
}, tabs)
|
|
@@ -115,7 +119,7 @@ const focusedTab = async tabs => await page.evaluate(tabs => {
|
|
|
115
119
|
});
|
|
116
120
|
// Tests a navigation on a tab element.
|
|
117
121
|
const testKey = async (
|
|
118
|
-
tabs, tabElement, keyName, keyProp, goodIndex, elementIsCorrect, itemData
|
|
122
|
+
tabs, tabElement, keyName, keyProp, goodIndex, elementIsCorrect, itemData, withItems, page
|
|
119
123
|
) => {
|
|
120
124
|
let pressed = true;
|
|
121
125
|
// Click the tab element, to make the focus on it effective.
|
|
@@ -153,7 +157,7 @@ const testKey = async (
|
|
|
153
157
|
// If the refocus and keypress succeeded:
|
|
154
158
|
if (pressed) {
|
|
155
159
|
// Identify which tab element is now focused, if any.
|
|
156
|
-
const focusIndex = await focusedTab(tabs);
|
|
160
|
+
const focusIndex = await focusedTab(tabs, page);
|
|
157
161
|
// If the focus is correct:
|
|
158
162
|
if (focusIndex === goodIndex) {
|
|
159
163
|
// Increment the counts of correct navigations and correct key navigations.
|
|
@@ -230,7 +234,7 @@ const arrowTarget = (startIndex, tabCount, orientation, direction) => {
|
|
|
230
234
|
Recursively tests tablist tab elements (per
|
|
231
235
|
https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel)
|
|
232
236
|
*/
|
|
233
|
-
const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
237
|
+
const testTabs = async (tabs, index, listOrientation, listIsCorrect, withItems, page) => {
|
|
234
238
|
const tabCount = tabs.length;
|
|
235
239
|
// If any tab elements remain to be tested:
|
|
236
240
|
if (index < tabCount) {
|
|
@@ -263,7 +267,17 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
263
267
|
}
|
|
264
268
|
}
|
|
265
269
|
// Test the element with each navigation key.
|
|
266
|
-
isCorrect = await testKey(
|
|
270
|
+
isCorrect = await testKey(
|
|
271
|
+
tabs,
|
|
272
|
+
currentTab,
|
|
273
|
+
'Tab',
|
|
274
|
+
'tab',
|
|
275
|
+
-1,
|
|
276
|
+
isCorrect,
|
|
277
|
+
itemData,
|
|
278
|
+
withItems,
|
|
279
|
+
page
|
|
280
|
+
);
|
|
267
281
|
isCorrect = await testKey(
|
|
268
282
|
tabs,
|
|
269
283
|
currentTab,
|
|
@@ -271,7 +285,9 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
271
285
|
'left',
|
|
272
286
|
arrowTarget(index, tabCount, listOrientation, 'left'),
|
|
273
287
|
isCorrect,
|
|
274
|
-
itemData
|
|
288
|
+
itemData,
|
|
289
|
+
withItems,
|
|
290
|
+
page
|
|
275
291
|
);
|
|
276
292
|
isCorrect = await testKey(
|
|
277
293
|
tabs,
|
|
@@ -280,7 +296,9 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
280
296
|
'right',
|
|
281
297
|
arrowTarget(index, tabCount, listOrientation, 'right'),
|
|
282
298
|
isCorrect,
|
|
283
|
-
itemData
|
|
299
|
+
itemData,
|
|
300
|
+
withItems,
|
|
301
|
+
page
|
|
284
302
|
);
|
|
285
303
|
isCorrect = await testKey(
|
|
286
304
|
tabs,
|
|
@@ -289,7 +307,9 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
289
307
|
'up',
|
|
290
308
|
arrowTarget(index, tabCount, listOrientation, 'up'),
|
|
291
309
|
isCorrect,
|
|
292
|
-
itemData
|
|
310
|
+
itemData,
|
|
311
|
+
withItems,
|
|
312
|
+
page
|
|
293
313
|
);
|
|
294
314
|
isCorrect = await testKey(
|
|
295
315
|
tabs,
|
|
@@ -298,11 +318,23 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
298
318
|
'down',
|
|
299
319
|
arrowTarget(index, tabCount, listOrientation, 'down'),
|
|
300
320
|
isCorrect,
|
|
301
|
-
itemData
|
|
321
|
+
itemData,
|
|
322
|
+
withItems,
|
|
323
|
+
page
|
|
324
|
+
);
|
|
325
|
+
isCorrect = await testKey(
|
|
326
|
+
tabs,
|
|
327
|
+
currentTab,
|
|
328
|
+
'Home',
|
|
329
|
+
'home',
|
|
330
|
+
0,
|
|
331
|
+
isCorrect,
|
|
332
|
+
itemData,
|
|
333
|
+
withItems,
|
|
334
|
+
page
|
|
302
335
|
);
|
|
303
|
-
isCorrect = await testKey(tabs, currentTab, 'Home', 'home', 0, isCorrect, itemData);
|
|
304
336
|
isCorrect = await testKey(
|
|
305
|
-
tabs, currentTab, 'End', 'end', tabCount - 1, isCorrect, itemData
|
|
337
|
+
tabs, currentTab, 'End', 'end', tabCount - 1, isCorrect, itemData, withItems, page
|
|
306
338
|
);
|
|
307
339
|
// Update the tablist status (Node 14 does not support the ES 2021 &&= operator).
|
|
308
340
|
listIsCorrect = listIsCorrect && isCorrect;
|
|
@@ -312,7 +344,7 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
312
344
|
data.tabElements[isCorrect ? 'correct' : 'incorrect'].push(itemData);
|
|
313
345
|
}
|
|
314
346
|
// Process the next tab element.
|
|
315
|
-
return await testTabs(tabs, index + 1, listOrientation, listIsCorrect);
|
|
347
|
+
return await testTabs(tabs, index + 1, listOrientation, listIsCorrect, withItems, page);
|
|
316
348
|
}
|
|
317
349
|
// Otherwise, i.e. if all tab elements have been tested:
|
|
318
350
|
else {
|
|
@@ -321,7 +353,7 @@ const testTabs = async (tabs, index, listOrientation, listIsCorrect) => {
|
|
|
321
353
|
}
|
|
322
354
|
};
|
|
323
355
|
// Recursively tests tablists.
|
|
324
|
-
const testTabLists = async tabLists => {
|
|
356
|
+
const testTabLists = async (tabLists, withItems, page) => {
|
|
325
357
|
// If any tablists remain to be tested:
|
|
326
358
|
if (tabLists.length) {
|
|
327
359
|
const firstTabList = tabLists[0];
|
|
@@ -341,12 +373,12 @@ const testTabLists = async tabLists => {
|
|
|
341
373
|
// If the tablist contains at least 2 tab elements:
|
|
342
374
|
if (tabs.length > 1) {
|
|
343
375
|
// Test them.
|
|
344
|
-
const isCorrect = await testTabs(tabs, 0, orientation, true);
|
|
376
|
+
const isCorrect = await testTabs(tabs, 0, orientation, true, withItems, page);
|
|
345
377
|
// Increment the data.
|
|
346
378
|
data.totals.tabLists.total++;
|
|
347
379
|
data.totals.tabLists[isCorrect ? 'correct' : 'incorrect']++;
|
|
348
380
|
// Process the remaining tablists.
|
|
349
|
-
await testTabLists(tabLists.slice(1));
|
|
381
|
+
await testTabLists(tabLists.slice(1), withItems, page);
|
|
350
382
|
}
|
|
351
383
|
}
|
|
352
384
|
}
|
|
@@ -354,62 +386,60 @@ const testTabLists = async tabLists => {
|
|
|
354
386
|
// Tests tab-list navigation and reports results.
|
|
355
387
|
exports.reporter = async (page, withItems) => {
|
|
356
388
|
// Initialize the results.
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
389
|
+
data.totals = {
|
|
390
|
+
navigations: {
|
|
391
|
+
all: {
|
|
392
|
+
total: 0,
|
|
393
|
+
correct: 0,
|
|
394
|
+
incorrect: 0
|
|
395
|
+
},
|
|
396
|
+
specific: {
|
|
397
|
+
tab: {
|
|
398
|
+
total: 0,
|
|
399
|
+
correct: 0,
|
|
400
|
+
incorrect: 0
|
|
401
|
+
},
|
|
402
|
+
left: {
|
|
403
|
+
total: 0,
|
|
404
|
+
correct: 0,
|
|
405
|
+
incorrect: 0
|
|
406
|
+
},
|
|
407
|
+
right: {
|
|
361
408
|
total: 0,
|
|
362
409
|
correct: 0,
|
|
363
410
|
incorrect: 0
|
|
364
411
|
},
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
incorrect: 0
|
|
385
|
-
},
|
|
386
|
-
down: {
|
|
387
|
-
total: 0,
|
|
388
|
-
correct: 0,
|
|
389
|
-
incorrect: 0
|
|
390
|
-
},
|
|
391
|
-
home: {
|
|
392
|
-
total: 0,
|
|
393
|
-
correct: 0,
|
|
394
|
-
incorrect: 0
|
|
395
|
-
},
|
|
396
|
-
end: {
|
|
397
|
-
total: 0,
|
|
398
|
-
correct: 0,
|
|
399
|
-
incorrect: 0
|
|
400
|
-
}
|
|
412
|
+
up: {
|
|
413
|
+
total: 0,
|
|
414
|
+
correct: 0,
|
|
415
|
+
incorrect: 0
|
|
416
|
+
},
|
|
417
|
+
down: {
|
|
418
|
+
total: 0,
|
|
419
|
+
correct: 0,
|
|
420
|
+
incorrect: 0
|
|
421
|
+
},
|
|
422
|
+
home: {
|
|
423
|
+
total: 0,
|
|
424
|
+
correct: 0,
|
|
425
|
+
incorrect: 0
|
|
426
|
+
},
|
|
427
|
+
end: {
|
|
428
|
+
total: 0,
|
|
429
|
+
correct: 0,
|
|
430
|
+
incorrect: 0
|
|
401
431
|
}
|
|
402
|
-
},
|
|
403
|
-
tabElements: {
|
|
404
|
-
total: 0,
|
|
405
|
-
correct: 0,
|
|
406
|
-
incorrect: 0
|
|
407
|
-
},
|
|
408
|
-
tabLists: {
|
|
409
|
-
total: 0,
|
|
410
|
-
correct: 0,
|
|
411
|
-
incorrect: 0
|
|
412
432
|
}
|
|
433
|
+
},
|
|
434
|
+
tabElements: {
|
|
435
|
+
total: 0,
|
|
436
|
+
correct: 0,
|
|
437
|
+
incorrect: 0
|
|
438
|
+
},
|
|
439
|
+
tabLists: {
|
|
440
|
+
total: 0,
|
|
441
|
+
correct: 0,
|
|
442
|
+
incorrect: 0
|
|
413
443
|
}
|
|
414
444
|
};
|
|
415
445
|
if (withItems) {
|
|
@@ -421,7 +451,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
421
451
|
// Get an array of element handles for the visible tablists.
|
|
422
452
|
const tabLists = await page.$$('[role=tablist]:visible');
|
|
423
453
|
if (tabLists.length) {
|
|
424
|
-
await testTabLists(tabLists);
|
|
454
|
+
await testTabLists(tabLists, withItems, page);
|
|
425
455
|
// Reload the page, because keyboard navigation may have triggered content changes.
|
|
426
456
|
try {
|
|
427
457
|
await page.reload({timeout: 15000});
|
|
@@ -430,21 +460,24 @@ exports.reporter = async (page, withItems) => {
|
|
|
430
460
|
console.log('ERROR: page reload timed out');
|
|
431
461
|
}
|
|
432
462
|
}
|
|
463
|
+
// Get the totals of navigation errors, bad tabs, and bad tab lists.
|
|
433
464
|
const totals = data.totals ? [
|
|
434
465
|
data.totals.navigations.all.incorrect,
|
|
435
466
|
data.totals.tabElements.incorrect,
|
|
436
467
|
data.totals.tabLists.incorrect,
|
|
437
468
|
0
|
|
438
469
|
] : [];
|
|
470
|
+
// Initialize the standard instances.
|
|
439
471
|
const standardInstances = [];
|
|
440
|
-
|
|
472
|
+
// If itemization is required:
|
|
473
|
+
if (withItems) {
|
|
474
|
+
// For each bad tab:
|
|
441
475
|
data.tabElements.incorrect.forEach(item => {
|
|
476
|
+
// Create a standard instance.
|
|
442
477
|
standardInstances.push({
|
|
443
478
|
ruleID: 'tabNav',
|
|
444
|
-
what:
|
|
445
|
-
`Tab responds nonstandardly to ${item.navigationErrors.join(', ')}`,
|
|
479
|
+
what: `Tab responds nonstandardly to ${item.navigationErrors.join(', ')}`,
|
|
446
480
|
ordinalSeverity: 1,
|
|
447
|
-
count: item.navigationErrors.length,
|
|
448
481
|
tagName: item.tagName,
|
|
449
482
|
id: item.id,
|
|
450
483
|
location: {
|
|
@@ -456,7 +489,9 @@ exports.reporter = async (page, withItems) => {
|
|
|
456
489
|
});
|
|
457
490
|
});
|
|
458
491
|
}
|
|
492
|
+
// Otherwise, if navigation is not required and any navigations are bad:
|
|
459
493
|
else if (data.totals.navigations.all.incorrect) {
|
|
494
|
+
// Create a standard instance.
|
|
460
495
|
standardInstances.push({
|
|
461
496
|
ruleID: 'tabNav',
|
|
462
497
|
what: 'Tab lists have nonstandard navigation',
|
|
@@ -472,6 +507,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
472
507
|
excerpt: ''
|
|
473
508
|
});
|
|
474
509
|
}
|
|
510
|
+
// Return the result.
|
|
475
511
|
return {
|
|
476
512
|
data,
|
|
477
513
|
totals,
|
|
@@ -131,10 +131,9 @@
|
|
|
131
131
|
}
|
|
132
132
|
],
|
|
133
133
|
"sources": {
|
|
134
|
-
"script": "",
|
|
135
|
-
"host": {},
|
|
136
|
-
"requester": ""
|
|
137
134
|
},
|
|
138
|
-
"
|
|
139
|
-
"
|
|
135
|
+
"standard": "only",
|
|
136
|
+
"observe": false,
|
|
137
|
+
"timeStamp": "240101T1500",
|
|
138
|
+
"creationTimeStamp": "240101T1200"
|
|
140
139
|
}
|
|
@@ -136,10 +136,9 @@
|
|
|
136
136
|
}
|
|
137
137
|
],
|
|
138
138
|
"sources": {
|
|
139
|
-
"script": "",
|
|
140
|
-
"host": {},
|
|
141
|
-
"requester": ""
|
|
142
139
|
},
|
|
143
|
-
"
|
|
144
|
-
"
|
|
140
|
+
"standard": "only",
|
|
141
|
+
"observe": false,
|
|
142
|
+
"timeStamp": "240101T1500",
|
|
143
|
+
"creationTimeStamp": "240101T1200"
|
|
145
144
|
}
|
|
@@ -309,10 +309,9 @@
|
|
|
309
309
|
}
|
|
310
310
|
],
|
|
311
311
|
"sources": {
|
|
312
|
-
"script": "",
|
|
313
|
-
"host": {},
|
|
314
|
-
"requester": ""
|
|
315
312
|
},
|
|
316
|
-
"
|
|
317
|
-
"
|
|
313
|
+
"standard": "only",
|
|
314
|
+
"observe": false,
|
|
315
|
+
"timeStamp": "240101T1500",
|
|
316
|
+
"creationTimeStamp": "240101T1200"
|
|
318
317
|
}
|
|
@@ -131,10 +131,9 @@
|
|
|
131
131
|
}
|
|
132
132
|
],
|
|
133
133
|
"sources": {
|
|
134
|
-
"script": "",
|
|
135
|
-
"host": {},
|
|
136
|
-
"requester": ""
|
|
137
134
|
},
|
|
138
|
-
"
|
|
139
|
-
"
|
|
135
|
+
"standard": "only",
|
|
136
|
+
"observe": false,
|
|
137
|
+
"timeStamp": "240101T1500",
|
|
138
|
+
"creationTimeStamp": "240101T1200"
|
|
140
139
|
}
|
|
@@ -146,10 +146,9 @@
|
|
|
146
146
|
}
|
|
147
147
|
],
|
|
148
148
|
"sources": {
|
|
149
|
-
"script": "",
|
|
150
|
-
"host": {},
|
|
151
|
-
"requester": ""
|
|
152
149
|
},
|
|
153
|
-
"
|
|
154
|
-
"
|
|
150
|
+
"standard": "only",
|
|
151
|
+
"observe": false,
|
|
152
|
+
"timeStamp": "240101T1500",
|
|
153
|
+
"creationTimeStamp": "240101T1200"
|
|
155
154
|
}
|
|
@@ -182,10 +182,9 @@
|
|
|
182
182
|
}
|
|
183
183
|
],
|
|
184
184
|
"sources": {
|
|
185
|
-
"script": "",
|
|
186
|
-
"host": {},
|
|
187
|
-
"requester": ""
|
|
188
185
|
},
|
|
189
|
-
"
|
|
190
|
-
"
|
|
186
|
+
"standard": "only",
|
|
187
|
+
"observe": false,
|
|
188
|
+
"timeStamp": "240101T1500",
|
|
189
|
+
"creationTimeStamp": "240101T1200"
|
|
191
190
|
}
|
|
@@ -146,10 +146,9 @@
|
|
|
146
146
|
}
|
|
147
147
|
],
|
|
148
148
|
"sources": {
|
|
149
|
-
"script": "",
|
|
150
|
-
"host": {},
|
|
151
|
-
"requester": ""
|
|
152
149
|
},
|
|
153
|
-
"
|
|
154
|
-
"
|
|
150
|
+
"standard": "only",
|
|
151
|
+
"observe": false,
|
|
152
|
+
"timeStamp": "240101T1500",
|
|
153
|
+
"creationTimeStamp": "240101T1200"
|
|
155
154
|
}
|
|
@@ -81,10 +81,9 @@
|
|
|
81
81
|
}
|
|
82
82
|
],
|
|
83
83
|
"sources": {
|
|
84
|
-
"script": "",
|
|
85
|
-
"host": {},
|
|
86
|
-
"requester": ""
|
|
87
84
|
},
|
|
88
|
-
"
|
|
89
|
-
"
|
|
85
|
+
"standard": "only",
|
|
86
|
+
"observe": false,
|
|
87
|
+
"timeStamp": "240101T1500",
|
|
88
|
+
"creationTimeStamp": "240101T1200"
|
|
90
89
|
}
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
[
|
|
190
190
|
"standardResult.instances.0.what",
|
|
191
191
|
"i",
|
|
192
|
-
"
|
|
192
|
+
"behave nonstandardly"
|
|
193
193
|
],
|
|
194
194
|
[
|
|
195
195
|
"standardResult.instances.0.ordinalSeverity",
|
|
@@ -209,10 +209,9 @@
|
|
|
209
209
|
}
|
|
210
210
|
],
|
|
211
211
|
"sources": {
|
|
212
|
-
"script": "",
|
|
213
|
-
"host": {},
|
|
214
|
-
"requester": ""
|
|
215
212
|
},
|
|
216
|
-
"
|
|
217
|
-
"
|
|
213
|
+
"standard": "only",
|
|
214
|
+
"observe": false,
|
|
215
|
+
"timeStamp": "240101T1500",
|
|
216
|
+
"creationTimeStamp": "240101T1200"
|
|
218
217
|
}
|
|
@@ -131,10 +131,9 @@
|
|
|
131
131
|
}
|
|
132
132
|
],
|
|
133
133
|
"sources": {
|
|
134
|
-
"script": "",
|
|
135
|
-
"host": {},
|
|
136
|
-
"requester": ""
|
|
137
134
|
},
|
|
138
|
-
"
|
|
139
|
-
"
|
|
135
|
+
"standard": "only",
|
|
136
|
+
"observe": false,
|
|
137
|
+
"timeStamp": "240101T1500",
|
|
138
|
+
"creationTimeStamp": "240101T1200"
|
|
140
139
|
}
|
|
@@ -121,10 +121,9 @@
|
|
|
121
121
|
}
|
|
122
122
|
],
|
|
123
123
|
"sources": {
|
|
124
|
-
"script": "",
|
|
125
|
-
"host": {},
|
|
126
|
-
"requester": ""
|
|
127
124
|
},
|
|
128
|
-
"
|
|
129
|
-
"
|
|
125
|
+
"standard": "only",
|
|
126
|
+
"observe": false,
|
|
127
|
+
"timeStamp": "240101T1500",
|
|
128
|
+
"creationTimeStamp": "240101T1200"
|
|
130
129
|
}
|
|
@@ -106,10 +106,9 @@
|
|
|
106
106
|
}
|
|
107
107
|
],
|
|
108
108
|
"sources": {
|
|
109
|
-
"script": "",
|
|
110
|
-
"host": {},
|
|
111
|
-
"requester": ""
|
|
112
109
|
},
|
|
113
|
-
"
|
|
114
|
-
"
|
|
110
|
+
"standard": "only",
|
|
111
|
+
"observe": false,
|
|
112
|
+
"timeStamp": "240101T1500",
|
|
113
|
+
"creationTimeStamp": "240101T1200"
|
|
115
114
|
}
|
|
@@ -86,10 +86,9 @@
|
|
|
86
86
|
}
|
|
87
87
|
],
|
|
88
88
|
"sources": {
|
|
89
|
-
"script": "",
|
|
90
|
-
"host": {},
|
|
91
|
-
"requester": ""
|
|
92
89
|
},
|
|
93
|
-
"
|
|
94
|
-
"
|
|
90
|
+
"standard": "only",
|
|
91
|
+
"observe": false,
|
|
92
|
+
"timeStamp": "240101T1500",
|
|
93
|
+
"creationTimeStamp": "240101T1200"
|
|
95
94
|
}
|