testilo 13.5.0 → 13.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testilo",
3
- "version": "13.5.0",
3
+ "version": "13.6.1",
4
4
  "description": "Client that scores and digests Testaro reports",
5
5
  "main": "aim.js",
6
6
  "scripts": {
@@ -21,8 +21,7 @@ const innerJoiner = '\n ';
21
21
  const htmlEscape = textOrNumber => textOrNumber
22
22
  .toString()
23
23
  .replace(/&/g, '&')
24
- .replace(/</g, '&lt;')
25
- .replace(/"/g, '&quot;');
24
+ .replace(/</g, '&lt;');
26
25
  // Gets a row of the score-summary table.
27
26
  const getScoreRow = (componentName, score) => `<tr><th>${componentName}</th><td>${score}</td></tr>`;
28
27
  // Adds parameters to a query for a digest.
@@ -362,7 +362,7 @@ exports.issueClasses = {
362
362
  }
363
363
  },
364
364
  wave: {
365
- 'alt_input_missing': {
365
+ alt_input_missing: {
366
366
  variable: false,
367
367
  quality: 1,
368
368
  what: 'Image button has no alternative text'
@@ -379,6 +379,11 @@ exports.issueClasses = {
379
379
  variable: false,
380
380
  quality: 1,
381
381
  what: 'figure element has no associated label'
382
+ },
383
+ figure_label_exists: {
384
+ variable: false,
385
+ quality: 1,
386
+ what: 'figure element has no associated label'
382
387
  }
383
388
  }
384
389
  }
@@ -431,10 +436,20 @@ exports.issueClasses = {
431
436
  quality: 1,
432
437
  what: 'Element with an img role has no non-empty label'
433
438
  },
439
+ aria_img_labelled: {
440
+ variable: false,
441
+ quality: 1,
442
+ what: 'Element with an img role has no label or an empty label'
443
+ },
434
444
  WCAG20_Img_HasAlt: {
435
445
  variable: false,
436
446
  quality: 1,
437
447
  what: 'Image has no alt attribute conveying its meaning, or alt="" if decorative'
448
+ },
449
+ img_alt_valid: {
450
+ variable: false,
451
+ quality: 1,
452
+ what: 'Image has neither an alt attribute nor an ARIA label or title'
438
453
  }
439
454
  },
440
455
  nuVal: {
@@ -452,12 +467,12 @@ exports.issueClasses = {
452
467
  }
453
468
  },
454
469
  wave: {
455
- 'alt_missing': {
470
+ alt_missing: {
456
471
  variable: false,
457
472
  quality: 1,
458
473
  what: 'Text alternative is missing'
459
474
  },
460
- 'alt_spacer_missing': {
475
+ alt_spacer_missing: {
461
476
  variable: false,
462
477
  quality: 1,
463
478
  what: 'Spacer image has no text alternative'
@@ -576,7 +591,7 @@ exports.issueClasses = {
576
591
  weight: 1,
577
592
  tools: {
578
593
  wave: {
579
- 'alt_duplicate': {
594
+ alt_duplicate: {
580
595
  variable: false,
581
596
  quality: 1,
582
597
  what: 'Two images near each other have the same text alternative'
@@ -596,7 +611,7 @@ exports.issueClasses = {
596
611
  }
597
612
  },
598
613
  wave: {
599
- 'alt_long': {
614
+ alt_long: {
600
615
  variable: false,
601
616
  quality: 1,
602
617
  what: 'Long text alternative'
@@ -654,7 +669,7 @@ exports.issueClasses = {
654
669
  }
655
670
  },
656
671
  wave: {
657
- 'alt_suspicious': {
672
+ alt_suspicious: {
658
673
  variable: false,
659
674
  quality: 1,
660
675
  what: 'Image text alternative is suspicious'
@@ -766,7 +781,7 @@ exports.issueClasses = {
766
781
  }
767
782
  },
768
783
  wave: {
769
- 'language_missing': {
784
+ language_missing: {
770
785
  variable: false,
771
786
  quality: 1,
772
787
  what: 'Language missing or invalid'
@@ -961,7 +976,7 @@ exports.issueClasses = {
961
976
  }
962
977
  },
963
978
  wave: {
964
- 'plugin': {
979
+ plugin: {
965
980
  variable: false,
966
981
  quality: 1,
967
982
  what: 'An unidentified plugin is present'
@@ -1000,7 +1015,7 @@ exports.issueClasses = {
1000
1015
  weight: 4,
1001
1016
  tools: {
1002
1017
  wave: {
1003
- 'alt_map_missing': {
1018
+ alt_map_missing: {
1004
1019
  variable: false,
1005
1020
  quality: 1,
1006
1021
  what: 'Image that has hot spots has no alt attribute'
@@ -1046,7 +1061,7 @@ exports.issueClasses = {
1046
1061
  }
1047
1062
  },
1048
1063
  wave: {
1049
- 'alt_area_missing': {
1064
+ alt_area_missing: {
1050
1065
  variable: false,
1051
1066
  quality: 1,
1052
1067
  what: 'Image map area has no alternative text'
@@ -1119,7 +1134,7 @@ exports.issueClasses = {
1119
1134
  }
1120
1135
  },
1121
1136
  wave: {
1122
- 'event_handler': {
1137
+ event_handler: {
1123
1138
  variable: false,
1124
1139
  quality: 1,
1125
1140
  what: 'Device-dependent event handler'
@@ -1139,7 +1154,7 @@ exports.issueClasses = {
1139
1154
  }
1140
1155
  },
1141
1156
  wave: {
1142
- 'link_internal_broken': {
1157
+ link_internal_broken: {
1143
1158
  variable: false,
1144
1159
  quality: 1,
1145
1160
  what: 'Broken same-page link'
@@ -1155,7 +1170,14 @@ exports.issueClasses = {
1155
1170
  'AAA.1_3_1.H44.NotFormControl': {
1156
1171
  variable: false,
1157
1172
  quality: 1,
1158
- what: 'referent of the for attribute of the label is not a form control, so may be wrong'
1173
+ what: 'Referent of the for attribute of the label is not a form control, so may be wrong'
1174
+ }
1175
+ },
1176
+ ibm: {
1177
+ label_ref_valid: {
1178
+ variable: false,
1179
+ quality: 1,
1180
+ what: 'Value of the for attribute of the label element is not the id of a valid input element'
1159
1181
  }
1160
1182
  },
1161
1183
  nuVal: {
@@ -1259,6 +1281,11 @@ exports.issueClasses = {
1259
1281
  variable: false,
1260
1282
  quality: 1,
1261
1283
  what: 'Checkbox or radio button label precedes the input control'
1284
+ },
1285
+ input_label_after: {
1286
+ variable: false,
1287
+ quality: 1,
1288
+ what: 'Label text is located before its associated checkbox or radio button element'
1262
1289
  }
1263
1290
  },
1264
1291
  qualWeb: {
@@ -1323,7 +1350,7 @@ exports.issueClasses = {
1323
1350
  }
1324
1351
  },
1325
1352
  wave: {
1326
- 'label_orphaned': {
1353
+ label_orphaned: {
1327
1354
  variable: false,
1328
1355
  quality: 1,
1329
1356
  what: 'Orphaned form label'
@@ -1414,6 +1441,11 @@ exports.issueClasses = {
1414
1441
  variable: false,
1415
1442
  quality: 1,
1416
1443
  what: 'Hyperlink has no text description'
1444
+ },
1445
+ a_text_purpose: {
1446
+ variable: false,
1447
+ quality: 1,
1448
+ what: 'Hyperlink has no link text, label, or image with a text alternative'
1417
1449
  }
1418
1450
  },
1419
1451
  qualWeb: {
@@ -1441,12 +1473,12 @@ exports.issueClasses = {
1441
1473
  }
1442
1474
  },
1443
1475
  wave: {
1444
- 'link_empty': {
1476
+ link_empty: {
1445
1477
  variable: false,
1446
1478
  quality: 1,
1447
1479
  what: 'Link contains no text'
1448
1480
  },
1449
- 'alt_link_missing': {
1481
+ alt_link_missing: {
1450
1482
  variable: false,
1451
1483
  quality: 1,
1452
1484
  what: 'Linked image has no text alternative'
@@ -1525,7 +1557,7 @@ exports.issueClasses = {
1525
1557
  weight: 1,
1526
1558
  tools: {
1527
1559
  wave: {
1528
- 'link_pdf': {
1560
+ link_pdf: {
1529
1561
  variable: false,
1530
1562
  quality: 1,
1531
1563
  what: 'Link to PDF document'
@@ -1681,7 +1713,7 @@ exports.issueClasses = {
1681
1713
  }
1682
1714
  },
1683
1715
  wave: {
1684
- 'link_redundant': {
1716
+ link_redundant: {
1685
1717
  variable: false,
1686
1718
  quality: 1,
1687
1719
  what: 'Adjacent links go to the same URL'
@@ -1751,7 +1783,7 @@ exports.issueClasses = {
1751
1783
  weight: 1,
1752
1784
  tools: {
1753
1785
  wave: {
1754
- 'javascript_jumpmenu': {
1786
+ javascript_jumpmenu: {
1755
1787
  variable: false,
1756
1788
  quality: 1,
1757
1789
  what: 'selection change may navigate to another page without notice'
@@ -1864,7 +1896,7 @@ exports.issueClasses = {
1864
1896
  }
1865
1897
  },
1866
1898
  wave: {
1867
- 'button_empty': {
1899
+ button_empty: {
1868
1900
  variable: false,
1869
1901
  quality: 1,
1870
1902
  what: 'Button is empty or has no value text'
@@ -2137,7 +2169,7 @@ exports.issueClasses = {
2137
2169
  }
2138
2170
  },
2139
2171
  wave: {
2140
- 'text_small': {
2172
+ text_small: {
2141
2173
  variable: false,
2142
2174
  quality: 1,
2143
2175
  what: 'Text is very small'
@@ -2231,12 +2263,18 @@ exports.issueClasses = {
2231
2263
  quality: 1,
2232
2264
  what: 'Overflow is hidden or clipped if the text is enlarged'
2233
2265
  }
2234
- },
2266
+ }
2267
+ }
2268
+ },
2269
+ overflowHiddenRisk: {
2270
+ wcag: '1.4.4',
2271
+ weight: 1,
2272
+ tools: {
2235
2273
  qualWeb: {
2236
2274
  'QW-ACT-R40': {
2237
2275
  variable: false,
2238
2276
  quality: 1,
2239
- what: 'Zoomed text node is clipped by a CSS overflow declaration'
2277
+ what: 'Zoomed text node may be clipped by a CSS overflow declaration'
2240
2278
  }
2241
2279
  }
2242
2280
  }
@@ -2276,6 +2314,18 @@ exports.issueClasses = {
2276
2314
  wcag: '1.3.1',
2277
2315
  weight: 4,
2278
2316
  tools: {
2317
+ htmlcs: {
2318
+ 'AAA.2_4_8.H59.1': {
2319
+ variable: false,
2320
+ quality: 1,
2321
+ what: 'link element is not in the document head'
2322
+ },
2323
+ 'A link element with an as attribute must have a rel attribute that contains the value preload or the value modulepreload or the value prefetch.': {
2324
+ variable: false,
2325
+ quality: 1,
2326
+ what: 'link element with an as attribute has no rel attribute with preload, modulepreload, or prefetch as its value'
2327
+ }
2328
+ },
2279
2329
  nuVal: {
2280
2330
  'A link element must not appear as a descendant of a body element unless the link element has an itemprop attribute or has a rel attribute whose value contains dns-prefetch, modulepreload, pingback, preconnect, prefetch, preload, prerender, or stylesheet.': {
2281
2331
  variable: false,
@@ -2286,6 +2336,11 @@ exports.issueClasses = {
2286
2336
  variable: false,
2287
2337
  quality: 1,
2288
2338
  what: 'link element with an as attribute has no rel attribute with preload, modulepreload, or prefetch as its value'
2339
+ },
2340
+ 'A link element with an as attribute must have a rel attribute that contains the value preload or the value modulepreload.': {
2341
+ variable: false,
2342
+ quality: 1,
2343
+ what: 'link element with an as attribute has no rel attribute with preload or modulepreload as its value'
2289
2344
  }
2290
2345
  }
2291
2346
  }
@@ -2518,6 +2573,11 @@ exports.issueClasses = {
2518
2573
  }
2519
2574
  },
2520
2575
  ibm: {
2576
+ aria_role_valid: {
2577
+ variable: false,
2578
+ quality: 1,
2579
+ what: 'ARIA role is not valid for its element'
2580
+ },
2521
2581
  aria_semantics_role: {
2522
2582
  variable: false,
2523
2583
  quality: 1,
@@ -2533,11 +2593,21 @@ exports.issueClasses = {
2533
2593
  quality: 1,
2534
2594
  what: 'Element has a contentinfo role when no element has a main role'
2535
2595
  },
2596
+ aria_contentinfo_misuse: {
2597
+ variable: false,
2598
+ quality: 1,
2599
+ what: 'Element with a contentinfo role is present without an element with a main role'
2600
+ },
2536
2601
  Rpt_Aria_ValidRole: {
2537
2602
  variable: false,
2538
2603
  quality: 1,
2539
2604
  what: 'Element has an invalid role'
2540
2605
  },
2606
+ aria_eventhandler_role_valid: {
2607
+ variable: false,
2608
+ quality: 1,
2609
+ what: 'Element with an onclick, onmouseout, or onmouseover attribute has no valid ARIA role'
2610
+ },
2541
2611
  Rpt_Aria_EventHandlerMissingRole_Native_Host_Sematics: {
2542
2612
  variable: false,
2543
2613
  quality: 1,
@@ -2619,7 +2689,7 @@ exports.issueClasses = {
2619
2689
  }
2620
2690
  },
2621
2691
  testaro: {
2622
- 'role': {
2692
+ role: {
2623
2693
  variable: false,
2624
2694
  quality: 1,
2625
2695
  what: 'Invalid, native-replacing, or redundant role'
@@ -2636,6 +2706,11 @@ exports.issueClasses = {
2636
2706
  variable: false,
2637
2707
  quality: 1,
2638
2708
  what: 'dir attribute has a value other than ltr, rtl, or auto'
2709
+ },
2710
+ aria_attribute_valid: {
2711
+ variable: false,
2712
+ quality: 1,
2713
+ what: 'ARIA attribute is invalid for the role of its element'
2639
2714
  }
2640
2715
  },
2641
2716
  nuVal: {
@@ -2728,6 +2803,11 @@ exports.issueClasses = {
2728
2803
  variable: false,
2729
2804
  quality: 1,
2730
2805
  what: 'ARIA role on an element does not have a required attribute'
2806
+ },
2807
+ aria_attribute_required: {
2808
+ variable: false,
2809
+ quality: 1,
2810
+ what: 'Element does not have the ARIA attribute required by its role'
2731
2811
  }
2732
2812
  },
2733
2813
  nuVal: {
@@ -3106,7 +3186,7 @@ exports.issueClasses = {
3106
3186
  }
3107
3187
  },
3108
3188
  wave: {
3109
- 'aria_reference_broken': {
3189
+ aria_reference_broken: {
3110
3190
  variable: false,
3111
3191
  quality: 1,
3112
3192
  what: 'Broken ARIA reference'
@@ -3248,7 +3328,7 @@ exports.issueClasses = {
3248
3328
  }
3249
3329
  },
3250
3330
  wave: {
3251
- 'contrast': {
3331
+ contrast: {
3252
3332
  variable: false,
3253
3333
  quality: 1,
3254
3334
  what: 'Very low contrast'
@@ -3444,6 +3524,11 @@ exports.issueClasses = {
3444
3524
  variable: false,
3445
3525
  quality: 1,
3446
3526
  what: 'Heading element provides no descriptive text'
3527
+ },
3528
+ heading_content_exists: {
3529
+ variable: false,
3530
+ quality: 1,
3531
+ what: 'Heading element has no descriptive content'
3447
3532
  }
3448
3533
  },
3449
3534
  nuVal: {
@@ -3461,7 +3546,7 @@ exports.issueClasses = {
3461
3546
  }
3462
3547
  },
3463
3548
  wave: {
3464
- 'heading_empty': {
3549
+ heading_empty: {
3465
3550
  variable: false,
3466
3551
  quality: 1,
3467
3552
  what: 'Empty heading'
@@ -3526,7 +3611,7 @@ exports.issueClasses = {
3526
3611
  }
3527
3612
  },
3528
3613
  wave: {
3529
- 'alt_redundant': {
3614
+ alt_redundant: {
3530
3615
  variable: false,
3531
3616
  quality: 1,
3532
3617
  what: 'Redundant text alternative'
@@ -3553,7 +3638,7 @@ exports.issueClasses = {
3553
3638
  }
3554
3639
  },
3555
3640
  wave: {
3556
- 'image_title': {
3641
+ image_title: {
3557
3642
  variable: false,
3558
3643
  quality: 1,
3559
3644
  what: 'Image has a title attribute value but no alt value'
@@ -3580,7 +3665,7 @@ exports.issueClasses = {
3580
3665
  }
3581
3666
  },
3582
3667
  wave: {
3583
- 'title_redundant': {
3668
+ title_redundant: {
3584
3669
  variable: false,
3585
3670
  quality: 1,
3586
3671
  what: 'Title attribute text is the same as text or alternative text'
@@ -3699,7 +3784,7 @@ exports.issueClasses = {
3699
3784
  }
3700
3785
  },
3701
3786
  wave: {
3702
- 'title_invalid': {
3787
+ title_invalid: {
3703
3788
  variable: false,
3704
3789
  quality: 1,
3705
3790
  what: 'Missing or uninformative page title'
@@ -3726,7 +3811,7 @@ exports.issueClasses = {
3726
3811
  }
3727
3812
  },
3728
3813
  wave: {
3729
- 'heading_skipped': {
3814
+ heading_skipped: {
3730
3815
  variable: false,
3731
3816
  quality: 1,
3732
3817
  what: 'Skipped heading level'
@@ -3786,7 +3871,7 @@ exports.issueClasses = {
3786
3871
  }
3787
3872
  },
3788
3873
  wave: {
3789
- 'heading_missing': {
3874
+ heading_missing: {
3790
3875
  variable: false,
3791
3876
  quality: 1,
3792
3877
  what: 'Page has no headings'
@@ -3898,7 +3983,7 @@ exports.issueClasses = {
3898
3983
  }
3899
3984
  },
3900
3985
  wave: {
3901
- 'text_justified': {
3986
+ text_justified: {
3902
3987
  variable: false,
3903
3988
  quality: 1,
3904
3989
  what: 'Text is justified'
@@ -4025,7 +4110,7 @@ exports.issueClasses = {
4025
4110
  }
4026
4111
  },
4027
4112
  wave: {
4028
- 'heading_possible': {
4113
+ heading_possible: {
4029
4114
  variable: false,
4030
4115
  quality: 1,
4031
4116
  what: 'Possible heading'
@@ -4045,7 +4130,7 @@ exports.issueClasses = {
4045
4130
  }
4046
4131
  },
4047
4132
  wave: {
4048
- 'underline': {
4133
+ underline: {
4049
4134
  variable: false,
4050
4135
  quality: 1,
4051
4136
  what: 'CSS underline on text that is not a link'
@@ -4139,7 +4224,7 @@ exports.issueClasses = {
4139
4224
  }
4140
4225
  },
4141
4226
  wave: {
4142
- 'list_possible': {
4227
+ list_possible: {
4143
4228
  variable: false,
4144
4229
  quality: 1,
4145
4230
  what: 'List may fail to be coded as such'
@@ -4211,7 +4296,7 @@ exports.issueClasses = {
4211
4296
  }
4212
4297
  },
4213
4298
  wave: {
4214
- 'select_missing_label': {
4299
+ select_missing_label: {
4215
4300
  variable: false,
4216
4301
  quality: 1,
4217
4302
  what: 'Select element has no label'
@@ -4245,6 +4330,19 @@ exports.issueClasses = {
4245
4330
  }
4246
4331
  }
4247
4332
  },
4333
+ noOptionFocusable: {
4334
+ wcag: '2.1.1',
4335
+ weight: 1,
4336
+ tools: {
4337
+ ibm: {
4338
+ aria_child_tabbable: {
4339
+ variable: false,
4340
+ quality: 1,
4341
+ what: 'No descendent element with an option role is tabbable'
4342
+ }
4343
+ }
4344
+ }
4345
+ },
4248
4346
  accessKeyDuplicate: {
4249
4347
  wcag: '1.3.1',
4250
4348
  weight: 3,
@@ -4271,7 +4369,7 @@ exports.issueClasses = {
4271
4369
  }
4272
4370
  },
4273
4371
  wave: {
4274
- 'accesskey': {
4372
+ accesskey: {
4275
4373
  variable: false,
4276
4374
  quality: 1,
4277
4375
  what: 'Accesskey'
@@ -4298,7 +4396,7 @@ exports.issueClasses = {
4298
4396
  }
4299
4397
  },
4300
4398
  wave: {
4301
- 'fieldset_missing': {
4399
+ fieldset_missing: {
4302
4400
  variable: false,
4303
4401
  quality: 1,
4304
4402
  what: 'fieldset element is missing'
@@ -4354,7 +4452,12 @@ exports.issueClasses = {
4354
4452
  WCAG20_Fieldset_HasLegend: {
4355
4453
  variable: false,
4356
4454
  quality: 1,
4357
- what: 'fieldset element has no single, non-empty legend as a label'
4455
+ what: 'fieldset element has no single, non-empty legend element as a label'
4456
+ },
4457
+ fieldset_legend_valid: {
4458
+ variable: false,
4459
+ quality: 1,
4460
+ what: 'fieldset element does not have a legend element'
4358
4461
  }
4359
4462
  },
4360
4463
  qualWeb: {
@@ -4365,7 +4468,7 @@ exports.issueClasses = {
4365
4468
  }
4366
4469
  },
4367
4470
  wave: {
4368
- 'legend_missing': {
4471
+ legend_missing: {
4369
4472
  variable: false,
4370
4473
  quality: 1,
4371
4474
  what: 'fieldset has no legend element'
@@ -4396,6 +4499,11 @@ exports.issueClasses = {
4396
4499
  variable: false,
4397
4500
  quality: 1,
4398
4501
  what: 'Groups with nested inputs has no unique accessible name'
4502
+ },
4503
+ fieldset_label_valid: {
4504
+ variable: false,
4505
+ quality: 1,
4506
+ what: 'Group or fieldset has no accessible name'
4399
4507
  }
4400
4508
  }
4401
4509
  }
@@ -4424,7 +4532,7 @@ exports.issueClasses = {
4424
4532
  }
4425
4533
  },
4426
4534
  wave: {
4427
- 'table_layout': {
4535
+ table_layout: {
4428
4536
  variable: false,
4429
4537
  quality: 1,
4430
4538
  what: 'table element is misused to arrange content'
@@ -4651,7 +4759,7 @@ exports.issueClasses = {
4651
4759
  weight: 2,
4652
4760
  tools: {
4653
4761
  wave: {
4654
- 'th_empty': {
4762
+ th_empty: {
4655
4763
  variable: false,
4656
4764
  quality: 1,
4657
4765
  what: 'th (table header) contains no text'
@@ -4695,6 +4803,11 @@ exports.issueClasses = {
4695
4803
  variable: false,
4696
4804
  quality: 1,
4697
4805
  what: 'Form control has no associated label'
4806
+ },
4807
+ input_label_exists: {
4808
+ variable: false,
4809
+ quality: 1,
4810
+ what: 'Element with the role of a form control has no associated label'
4698
4811
  }
4699
4812
  },
4700
4813
  qualWeb: {
@@ -4705,7 +4818,7 @@ exports.issueClasses = {
4705
4818
  }
4706
4819
  },
4707
4820
  wave: {
4708
- 'label_missing': {
4821
+ label_missing: {
4709
4822
  variable: false,
4710
4823
  quality: 1,
4711
4824
  what: 'form element has no label'
@@ -4731,7 +4844,7 @@ exports.issueClasses = {
4731
4844
  weight: 3,
4732
4845
  tools: {
4733
4846
  wave: {
4734
- 'label_title': {
4847
+ label_title: {
4735
4848
  variable: false,
4736
4849
  quality: 1,
4737
4850
  what: 'Form control has a title but no label'
@@ -4968,7 +5081,7 @@ exports.issueClasses = {
4968
5081
  }
4969
5082
  },
4970
5083
  testaro: {
4971
- 'focInd': {
5084
+ focInd: {
4972
5085
  variable: false,
4973
5086
  quality: 1,
4974
5087
  what: 'Focused element displays a nonstandard or no focus indicator'
@@ -5021,7 +5134,7 @@ exports.issueClasses = {
5021
5134
  weight: 2,
5022
5135
  tools: {
5023
5136
  wave: {
5024
- 'region_missing': {
5137
+ region_missing: {
5025
5138
  variable: false,
5026
5139
  quality: 1,
5027
5140
  what: 'Page has no regions or ARIA landmarks'
@@ -5182,6 +5295,13 @@ exports.issueClasses = {
5182
5295
  quality: 1,
5183
5296
  what: 'Multiple elements with a banner role are on the page'
5184
5297
  }
5298
+ },
5299
+ qualWeb: {
5300
+ 'QW-BP20': {
5301
+ variable: false,
5302
+ quality: 1,
5303
+ what: 'Document has more than 1 banner landmark'
5304
+ }
5185
5305
  }
5186
5306
  }
5187
5307
  },
@@ -5195,6 +5315,13 @@ exports.issueClasses = {
5195
5315
  quality: 1,
5196
5316
  what: 'banner landmark is contained in another landmark'
5197
5317
  }
5318
+ },
5319
+ qualWeb: {
5320
+ 'QW-BP19': {
5321
+ variable: false,
5322
+ quality: 1,
5323
+ what: 'banner landmark is not at the top level'
5324
+ }
5198
5325
  }
5199
5326
  }
5200
5327
  },
@@ -5278,6 +5405,11 @@ exports.issueClasses = {
5278
5405
  variable: false,
5279
5406
  quality: 1,
5280
5407
  what: 'Element with a form role has no unique purpose label among the form-role elements'
5408
+ },
5409
+ aria_form_label_unique: {
5410
+ variable: false,
5411
+ quality: 1,
5412
+ what: 'Multiple elements with a form role do not have unique labels'
5281
5413
  }
5282
5414
  }
5283
5415
  }
@@ -5362,6 +5494,11 @@ exports.issueClasses = {
5362
5494
  variable: false,
5363
5495
  quality: 1,
5364
5496
  what: 'Element with a region role has no unique label among the region-role elements'
5497
+ },
5498
+ aria_region_label_unique: {
5499
+ variable: false,
5500
+ quality: 1,
5501
+ what: 'Multiple elements with a region role do not have unique labels'
5365
5502
  }
5366
5503
  }
5367
5504
  }
@@ -5437,6 +5574,11 @@ exports.issueClasses = {
5437
5574
  variable: false,
5438
5575
  quality: 1,
5439
5576
  what: 'label element has no non-empty purpose-descriptive text'
5577
+ },
5578
+ label_content_exists: {
5579
+ variable: false,
5580
+ quality: 1,
5581
+ what: 'label element has no descriptive text identifying the expected input'
5440
5582
  }
5441
5583
  }
5442
5584
  }
@@ -5446,7 +5588,7 @@ exports.issueClasses = {
5446
5588
  weight: 3,
5447
5589
  tools: {
5448
5590
  testaro: {
5449
- 'focOp': {
5591
+ focOp: {
5450
5592
  variable: false,
5451
5593
  quality: 1,
5452
5594
  what: 'Tab-focusable elements that are inoperable or operable elements that are not focusable'
@@ -5570,6 +5712,24 @@ exports.issueClasses = {
5570
5712
  }
5571
5713
  }
5572
5714
  },
5715
+ multipleLabelees: {
5716
+ wcag: '1.3.1',
5717
+ weight: 4,
5718
+ tools: {
5719
+ nuVal: {
5720
+ 'The label element may contain at most one button, input, meter, output, progress, select, or textarea descendant.': {
5721
+ variable: false,
5722
+ quality: 1,
5723
+ what: 'label element has more than 1 labelable descendant.'
5724
+ },
5725
+ 'label element with multiple labelable descendants.': {
5726
+ variable: false,
5727
+ quality: 1,
5728
+ what: 'label element has multiple labelable descendants.'
5729
+ }
5730
+ }
5731
+ }
5732
+ },
5573
5733
  labeledHidden: {
5574
5734
  wcag: '1.3.1',
5575
5735
  weight: 2,
@@ -5648,20 +5808,7 @@ exports.issueClasses = {
5648
5808
  hover: {
5649
5809
  variable: false,
5650
5810
  quality: 1,
5651
- what: 'Hovering is mis-indicated or changes content'
5652
- }
5653
- }
5654
- }
5655
- },
5656
- hoverSurprise: {
5657
- wcag: '1.4.13',
5658
- weight: 3,
5659
- tools: {
5660
- testaro: {
5661
- 'hover': {
5662
- variable: false,
5663
- quality: 1,
5664
- what: 'Hovering over element has unexpected effects'
5811
+ what: 'Hovering is impossible or mis-indicated or changes content'
5665
5812
  }
5666
5813
  }
5667
5814
  }
@@ -5678,7 +5825,7 @@ exports.issueClasses = {
5678
5825
  }
5679
5826
  },
5680
5827
  testaro: {
5681
- 'labClash': {
5828
+ labClash: {
5682
5829
  variable: false,
5683
5830
  quality: 1,
5684
5831
  what: 'Incompatible label types'
@@ -5692,7 +5839,7 @@ exports.issueClasses = {
5692
5839
  }
5693
5840
  },
5694
5841
  wave: {
5695
- 'label_multiple': {
5842
+ label_multiple: {
5696
5843
  variable: false,
5697
5844
  quality: 1,
5698
5845
  what: 'Form control has more than one label associated with it'
@@ -5717,7 +5864,7 @@ exports.issueClasses = {
5717
5864
  }
5718
5865
  },
5719
5866
  wave: {
5720
- 'label_empty': {
5867
+ label_empty: {
5721
5868
  variable: false,
5722
5869
  quality: 1,
5723
5870
  what: 'Empty form label'
@@ -5730,7 +5877,7 @@ exports.issueClasses = {
5730
5877
  weight: 1,
5731
5878
  tools: {
5732
5879
  wave: {
5733
- 'link_suspicious': {
5880
+ link_suspicious: {
5734
5881
  variable: false,
5735
5882
  quality: 1,
5736
5883
  what: 'Suspicious link text'
@@ -5750,12 +5897,12 @@ exports.issueClasses = {
5750
5897
  }
5751
5898
  },
5752
5899
  wave: {
5753
- 'link_excel': {
5900
+ link_excel: {
5754
5901
  variable: false,
5755
5902
  quality: 1,
5756
5903
  what: 'Link to Microsoft Excel workbook'
5757
5904
  },
5758
- 'link_word': {
5905
+ link_word: {
5759
5906
  variable: false,
5760
5907
  quality: 1,
5761
5908
  what: 'Link to Microsoft Word document'
@@ -5821,7 +5968,7 @@ exports.issueClasses = {
5821
5968
  weight: 4,
5822
5969
  tools: {
5823
5970
  wave: {
5824
- 'aria_menu_broken': {
5971
+ aria_menu_broken: {
5825
5972
  variable: false,
5826
5973
  quality: 1,
5827
5974
  what: 'ARIA menu does not contain required menu items'
@@ -5954,6 +6101,13 @@ exports.issueClasses = {
5954
6101
  wcag: '1.3.1',
5955
6102
  weight: 4,
5956
6103
  tools: {
6104
+ ibm: {
6105
+ aria_parent_required: {
6106
+ variable: true,
6107
+ quality: 1,
6108
+ what: 'Element is not contained in or owned by an element with a required role'
6109
+ }
6110
+ },
5957
6111
  nuVal: {
5958
6112
  '^Element .+ not allowed as child of element .+ in this context.*$': {
5959
6113
  variable: true,
@@ -6014,7 +6168,7 @@ exports.issueClasses = {
6014
6168
  }
6015
6169
  },
6016
6170
  wave: {
6017
- 'tabindex': {
6171
+ tabindex: {
6018
6172
  variable: false,
6019
6173
  quality: 1,
6020
6174
  what: 'tabIndex value positive'
@@ -6199,12 +6353,12 @@ exports.issueClasses = {
6199
6353
  quality: 1,
6200
6354
  what: 'video or audio element may have no or incorrect captions, transcript, or audio description'
6201
6355
  },
6202
- 'audio_video': {
6356
+ audio_video: {
6203
6357
  variable: false,
6204
6358
  quality: 1,
6205
6359
  what: 'audio or video file or link may have no or incorrect captions, transcript, or audio description'
6206
6360
  },
6207
- 'youtube_video': {
6361
+ youtube_video: {
6208
6362
  variable: false,
6209
6363
  quality: 1,
6210
6364
  what: 'YouTube video may have no or incorrect captions'
@@ -6303,7 +6457,7 @@ exports.issueClasses = {
6303
6457
  weight: 3,
6304
6458
  tools: {
6305
6459
  axe: {
6306
- 'bypass': {
6460
+ bypass: {
6307
6461
  variable: false,
6308
6462
  quality: 1,
6309
6463
  what: 'Page has no means to bypass repeated blocks'
@@ -6334,7 +6488,7 @@ exports.issueClasses = {
6334
6488
  }
6335
6489
  },
6336
6490
  wave: {
6337
- 'link_skip_broken': {
6491
+ link_skip_broken: {
6338
6492
  variable: false,
6339
6493
  quality: 1,
6340
6494
  what: 'Skip-navigation link has no target or is not keyboard accessible'
@@ -6433,7 +6587,7 @@ exports.issueClasses = {
6433
6587
  weight: 1,
6434
6588
  tools: {
6435
6589
  wave: {
6436
- 'noscript': {
6590
+ noscript: {
6437
6591
  variable: false,
6438
6592
  quality: 1,
6439
6593
  what: 'noscript element may fail to contain an accessible equivalent or alternative'
@@ -6564,12 +6718,12 @@ exports.issueClasses = {
6564
6718
  }
6565
6719
  },
6566
6720
  wave: {
6567
- 'longdesc': {
6721
+ longdesc: {
6568
6722
  variable: false,
6569
6723
  quality: 1,
6570
6724
  what: 'longdesc attribute is obsolete'
6571
6725
  },
6572
- 'flash': {
6726
+ flash: {
6573
6727
  variable: false,
6574
6728
  quality: 1,
6575
6729
  what: 'Flash content is present'
@@ -6771,13 +6925,28 @@ exports.issueClasses = {
6771
6925
  weight: 3,
6772
6926
  tools: {
6773
6927
  ibm: {
6774
- 'Rpt_Aria_InvalidTabindexForActivedescendant': {
6928
+ aria_child_valid: {
6929
+ variable: false,
6930
+ quality: 1,
6931
+ what: 'Child element has a role not allowed for the role of the parent'
6932
+ },
6933
+ Rpt_Aria_InvalidTabindexForActivedescendant: {
6775
6934
  variable: false,
6776
6935
  quality: 1,
6777
6936
  what: 'Element with an aria-activedescendant attribute has no nonpositive tabindex attribute'
6778
6937
  }
6779
6938
  },
6780
6939
  nuVal: {
6940
+ 'No space between attributes.': {
6941
+ variable: false,
6942
+ quality: 1,
6943
+ what: 'No space between attributes'
6944
+ },
6945
+ 'Saw <?. Probable cause: Attempt to use an XML processing instruction in HTML. (XML processing instructions are not supported in HTML.)': {
6946
+ variable: false,
6947
+ quality: 1,
6948
+ what: 'Left angle bracket is followed by a question mark'
6949
+ },
6781
6950
  'Almost standards mode doctype. Expected <!DOCTYPE html>.': {
6782
6951
  variable: false,
6783
6952
  quality: 1,
@@ -6942,7 +7111,7 @@ exports.issueClasses = {
6942
7111
  }
6943
7112
  },
6944
7113
  wave: {
6945
- 'longdesc_invalid': {
7114
+ longdesc_invalid: {
6946
7115
  variable: false,
6947
7116
  quality: 1,
6948
7117
  what: 'longdesc attribute has a value that is not a URL (and is obsolete)'
@@ -29,7 +29,7 @@ const latencyWeight = 1;
29
29
  // Normal latency (1.5 second per visit).
30
30
  const normalLatency = 20;
31
31
  // How much each prevention adds to the score.
32
- const preventionWeight = 200;
32
+ const preventionWeight = 300;
33
33
  // Indexes of issues.
34
34
  const issueIndex = {};
35
35
  const issueMatcher = [];
@@ -83,7 +83,7 @@ exports.scorer = report => {
83
83
  testActs.forEach(act => {
84
84
  // If the page prevented the tool from operating:
85
85
  const {which, standardResult} = act;
86
- if (standardResult.prevented) {
86
+ if (! standardResult || standardResult.prevented) {
87
87
  // Add this to the score.
88
88
  details.prevention[which] = preventionWeight;
89
89
  }
@@ -149,7 +149,7 @@ exports.scorer = report => {
149
149
  }
150
150
  });
151
151
  }
152
- // Otherwise, i.e. if no successful standard result exists:
152
+ // Otherwise, i.e. if a failed standard result exists:
153
153
  else {
154
154
  // Add an inferred prevention to the score.
155
155
  details.prevention[which] = preventionWeight;