testilo 3.9.0 → 3.9.3
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 +1 -1
- package/procs/score/sp15a.js +225 -87
package/package.json
CHANGED
package/procs/score/sp15a.js
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
This proc applies specified weights to the component scores before summing them. An issue reported
|
|
11
11
|
by a test is given a score. That score is determined by:
|
|
12
12
|
Whether the issue is reported as an error or a warning.
|
|
13
|
-
How important the issue is, if the test package is
|
|
14
|
-
Whether the test belongs to a group or is a
|
|
13
|
+
How important the issue is, if the test package is pre-weighted (axe, tenon, and testaro)
|
|
14
|
+
Whether the test belongs to a group or is a solo test.
|
|
15
15
|
How heavily the group is weighted, if the test package is not pre-weighted and the test belongs
|
|
16
16
|
to a group
|
|
17
17
|
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
Browser logging produces a log score, and the prevention of tests produces a prevention score.
|
|
28
28
|
They, too, are added to the total score.
|
|
29
29
|
|
|
30
|
-
Each grouped test has a
|
|
30
|
+
Each grouped test has a quality property, typically set to 1. The value of this property can be
|
|
31
31
|
modified when the test is found to be higher or lower in quality than usual.
|
|
32
32
|
*/
|
|
33
33
|
|
|
@@ -58,8 +58,25 @@ const otherPackages = ['alfa', 'axe', 'continuum', 'htmlcs', 'ibm', 'nuVal', 'te
|
|
|
58
58
|
const preWeightedPackages = ['axe', 'tenon', 'testaro'];
|
|
59
59
|
const testMatchers = {
|
|
60
60
|
nuVal: [
|
|
61
|
+
/^CSS: background-image: .+ is not a background-image value.*$/,
|
|
62
|
+
/^CSS: background: .+ is not a color value.*$/,
|
|
63
|
+
/^CSS: cursor: .+ is not a cursor value.*$/,
|
|
64
|
+
/^CSS: transform: .+ is not a transform value.*$/,
|
|
65
|
+
/^Bad value for attribute id on element .+: An ID must not be the empty string.+$/,
|
|
66
|
+
/^Duplicate ID .+$|^The first occurrence of ID .* was here.*$/,
|
|
67
|
+
/^Start tag .+ seen but an element of the same type was already open.*$/,
|
|
68
|
+
/^End tag .+ violates nesting rules.*$/,
|
|
69
|
+
/^Attribute .+ is not serializable as XML 1\.0.*$/,
|
|
70
|
+
/^Attribute .+ not allowed on element meta at this point.*$/,
|
|
61
71
|
/^Attribute .+ not allowed on element .+ at this point.*$/,
|
|
62
|
-
/^
|
|
72
|
+
/^Bad value .+ for attribute .+ on element meta.*$/,
|
|
73
|
+
/^Bad value .+ for attribute .+ on element .+$/,
|
|
74
|
+
/^Bad value .+ for the attribute .+$/,
|
|
75
|
+
/^Attribute .+ not allowed here.*$/,
|
|
76
|
+
/^The .+ role is unnecessary for element .+$/,
|
|
77
|
+
/^CSS: .+: Property .+ doesn't exist.*$/,
|
|
78
|
+
/^CSS: .+: only 0 can be a length. You must put a unit after your number.*$/,
|
|
79
|
+
/^Element .+ not allowed as child of element .+ in this context.*$/
|
|
63
80
|
]
|
|
64
81
|
};
|
|
65
82
|
const groups = {
|
|
@@ -67,7 +84,7 @@ const groups = {
|
|
|
67
84
|
weight: 0,
|
|
68
85
|
packages: {
|
|
69
86
|
nuVal: {
|
|
70
|
-
'Element
|
|
87
|
+
'Element mediaelementwrapper not allowed as child of element div in this context. (Suppressing further errors from this subtree.)': {
|
|
71
88
|
quality: 0,
|
|
72
89
|
what: 'Bug in nuVal'
|
|
73
90
|
}
|
|
@@ -114,6 +131,12 @@ const groups = {
|
|
|
114
131
|
quality: 1,
|
|
115
132
|
what: 'Element id attribute value is not unique within the document'
|
|
116
133
|
}
|
|
134
|
+
},
|
|
135
|
+
nuVal: {
|
|
136
|
+
'^Duplicate ID .+$|^The first occurrence of ID .* was here.*$': {
|
|
137
|
+
quality: 1,
|
|
138
|
+
what: 'Duplicate id'
|
|
139
|
+
}
|
|
117
140
|
}
|
|
118
141
|
}
|
|
119
142
|
},
|
|
@@ -328,7 +351,7 @@ const groups = {
|
|
|
328
351
|
}
|
|
329
352
|
},
|
|
330
353
|
nuVal: {
|
|
331
|
-
'An
|
|
354
|
+
'An img element must have an alt attribute, except under certain conditions. For details, consult guidance on providing text alternatives for images.': {
|
|
332
355
|
quality: 1,
|
|
333
356
|
what: 'img element has no alt attribute'
|
|
334
357
|
}
|
|
@@ -371,18 +394,29 @@ const groups = {
|
|
|
371
394
|
weight: 4,
|
|
372
395
|
packages: {
|
|
373
396
|
nuVal: {
|
|
374
|
-
'Element
|
|
397
|
+
'Element img is missing required attribute src.': {
|
|
375
398
|
quality: 1,
|
|
376
399
|
what: 'img element has no src attribute'
|
|
377
400
|
}
|
|
378
401
|
}
|
|
379
402
|
}
|
|
380
403
|
},
|
|
404
|
+
backgroundBad: {
|
|
405
|
+
weight: 4,
|
|
406
|
+
packages: {
|
|
407
|
+
nuVal: {
|
|
408
|
+
'^CSS: background: .+ is not a color value.*$': {
|
|
409
|
+
quality: 1,
|
|
410
|
+
what: 'CSS background color is misdefined'
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
},
|
|
381
415
|
backgroundImageBad: {
|
|
382
416
|
weight: 4,
|
|
383
417
|
packages: {
|
|
384
418
|
nuVal: {
|
|
385
|
-
'^CSS:
|
|
419
|
+
'^CSS: background-image: .+ is not a background-image value.*$': {
|
|
386
420
|
quality: 1,
|
|
387
421
|
what: 'CSS background image is misdefined'
|
|
388
422
|
}
|
|
@@ -780,7 +814,7 @@ const groups = {
|
|
|
780
814
|
weight: 1,
|
|
781
815
|
packages: {
|
|
782
816
|
nuVal: {
|
|
783
|
-
'Possible misuse of
|
|
817
|
+
'Possible misuse of aria-label. (If you disagree with this warning, file an issue report or send e-mail to www-validator@w3.org.)': {
|
|
784
818
|
quality: 1,
|
|
785
819
|
what: 'aria-label attribute may be misused'
|
|
786
820
|
}
|
|
@@ -867,7 +901,7 @@ const groups = {
|
|
|
867
901
|
}
|
|
868
902
|
},
|
|
869
903
|
nuVal: {
|
|
870
|
-
'The
|
|
904
|
+
'The aria-labelledby attribute must point to an element in the same document.': {
|
|
871
905
|
quality: 1,
|
|
872
906
|
what: 'aria-labelledby attribute references an element not in the document'
|
|
873
907
|
}
|
|
@@ -1154,7 +1188,7 @@ const groups = {
|
|
|
1154
1188
|
weight: 4,
|
|
1155
1189
|
packages: {
|
|
1156
1190
|
nuVal: {
|
|
1157
|
-
'Attribute
|
|
1191
|
+
'Attribute alt not allowed on element button at this point.': {
|
|
1158
1192
|
quality: 1,
|
|
1159
1193
|
what: 'button element has an alt attribute'
|
|
1160
1194
|
}
|
|
@@ -1456,7 +1490,7 @@ const groups = {
|
|
|
1456
1490
|
weight: 4,
|
|
1457
1491
|
packages: {
|
|
1458
1492
|
nuVal: {
|
|
1459
|
-
'Element
|
|
1493
|
+
'Element title not allowed as child of element body in this context. (Suppressing further errors from this subtree.)': {
|
|
1460
1494
|
quality: 1,
|
|
1461
1495
|
what: 'title element is a child of the body element'
|
|
1462
1496
|
}
|
|
@@ -1473,7 +1507,7 @@ const groups = {
|
|
|
1473
1507
|
weight: 4,
|
|
1474
1508
|
packages: {
|
|
1475
1509
|
nuVal: {
|
|
1476
|
-
'A
|
|
1510
|
+
'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.': {
|
|
1477
1511
|
quality: 1,
|
|
1478
1512
|
what: 'link element with a body ancestor has no itemprop or valid rel attribute'
|
|
1479
1513
|
}
|
|
@@ -1484,37 +1518,33 @@ const groups = {
|
|
|
1484
1518
|
weight: 3,
|
|
1485
1519
|
packages: {
|
|
1486
1520
|
nuVal: {
|
|
1487
|
-
'Attribute
|
|
1521
|
+
'^Attribute .+ not allowed on element meta at this point.*$': {
|
|
1488
1522
|
quality: 1,
|
|
1489
|
-
what: '
|
|
1523
|
+
what: 'Attribute is not allowed on a meta element here'
|
|
1490
1524
|
},
|
|
1491
|
-
'
|
|
1492
|
-
quality: 1,
|
|
1493
|
-
what: 'rel attribute is not allowed on a meta element here'
|
|
1494
|
-
},
|
|
1495
|
-
'Attribute “href” not allowed on element “meta” at this point.': {
|
|
1496
|
-
quality: 1,
|
|
1497
|
-
what: 'href attribute is not allowed on a meta element here'
|
|
1498
|
-
},
|
|
1499
|
-
'Element “meta” is missing one or more of the following attributes: “charset”, “content”, “http-equiv”, “itemprop”, “name”, “property”.': {
|
|
1525
|
+
'Element meta is missing one or more of the following attributes: charset, content, http-equiv, itemprop, name, property.': {
|
|
1500
1526
|
quality: 1,
|
|
1501
1527
|
what: 'meta element is missing a charset, content, http-equiv, itemprop, name, or property attribute'
|
|
1502
1528
|
},
|
|
1503
|
-
'A document must not include more than one
|
|
1529
|
+
'A document must not include more than one meta element with its name attribute set to the value description.': {
|
|
1504
1530
|
quality: 1,
|
|
1505
1531
|
what: 'meta element with name="description" is not the only one'
|
|
1506
1532
|
},
|
|
1507
|
-
'
|
|
1508
|
-
quality: 1,
|
|
1509
|
-
what: 'http-equiv attribute is not allowed on a meta element here'
|
|
1510
|
-
},
|
|
1511
|
-
'A “meta” element with an “http-equiv” attribute whose value is “X-UA-Compatible” must have a “content” attribute with the value “IE=edge”.': {
|
|
1533
|
+
'A meta element with an http-equiv attribute whose value is X-UA-Compatible must have a content attribute with the value IE=edge.': {
|
|
1512
1534
|
quality: 1,
|
|
1513
1535
|
what: 'meta element with http-equiv="X-UA-Compatible" has no content="IE=edge"'
|
|
1514
1536
|
},
|
|
1515
|
-
'Element
|
|
1537
|
+
'Element meta is missing one or more of the following attributes: itemprop, property.': {
|
|
1516
1538
|
quality: 1,
|
|
1517
1539
|
what: 'meta element is missing an itemprop or property attribute'
|
|
1540
|
+
},
|
|
1541
|
+
'A charset attribute on a meta element found after the first 1024 bytes.': {
|
|
1542
|
+
quality: 1,
|
|
1543
|
+
what: 'charset attribute on a meta element appears after 1024 bytes'
|
|
1544
|
+
},
|
|
1545
|
+
'^Bad value .+ for attribute .+ on element meta.*$': {
|
|
1546
|
+
quality: 1,
|
|
1547
|
+
what: 'attribute of a meta element has an invalid value'
|
|
1518
1548
|
}
|
|
1519
1549
|
}
|
|
1520
1550
|
}
|
|
@@ -1523,7 +1553,7 @@ const groups = {
|
|
|
1523
1553
|
weight: 4,
|
|
1524
1554
|
packages: {
|
|
1525
1555
|
nuVal: {
|
|
1526
|
-
'Element
|
|
1556
|
+
'Element script must not have attribute defer unless attribute src is also specified.': {
|
|
1527
1557
|
quality: 1,
|
|
1528
1558
|
what: 'script element has a defer attribute without a src attribute'
|
|
1529
1559
|
}
|
|
@@ -1534,7 +1564,7 @@ const groups = {
|
|
|
1534
1564
|
weight: 4,
|
|
1535
1565
|
packages: {
|
|
1536
1566
|
nuVal: {
|
|
1537
|
-
'The
|
|
1567
|
+
'The itemtype attribute must not be specified on elements that do not have an itemscope attribute specified.': {
|
|
1538
1568
|
quality: 1,
|
|
1539
1569
|
what: 'Element has an itemtype attribute without an itemscope attribute'
|
|
1540
1570
|
}
|
|
@@ -1652,7 +1682,7 @@ const groups = {
|
|
|
1652
1682
|
}
|
|
1653
1683
|
},
|
|
1654
1684
|
nuVal: {
|
|
1655
|
-
'Bad value
|
|
1685
|
+
'Bad value dialog for attribute role on element li.': {
|
|
1656
1686
|
quality: 1,
|
|
1657
1687
|
what: 'dialog role is not valid for an li element'
|
|
1658
1688
|
}
|
|
@@ -1675,21 +1705,9 @@ const groups = {
|
|
|
1675
1705
|
}
|
|
1676
1706
|
},
|
|
1677
1707
|
nuVal: {
|
|
1678
|
-
'The
|
|
1679
|
-
quality: 1,
|
|
1680
|
-
what: 'banner role is redundant for a header element'
|
|
1681
|
-
},
|
|
1682
|
-
'The “contentinfo” role is unnecessary for element “footer”.': {
|
|
1683
|
-
quality: 1,
|
|
1684
|
-
what: 'contentinfo role is redundant for a footer element'
|
|
1685
|
-
},
|
|
1686
|
-
'The “main” role is unnecessary for element “main”.': {
|
|
1687
|
-
quality: 1,
|
|
1688
|
-
what: 'main role is redundant for a main element'
|
|
1689
|
-
},
|
|
1690
|
-
'The “navigation” role is unnecessary for element “nav”.': {
|
|
1708
|
+
'^The .+ role is unnecessary for element .+$': {
|
|
1691
1709
|
quality: 1,
|
|
1692
|
-
what: '
|
|
1710
|
+
what: 'explicit role is redundant for its element'
|
|
1693
1711
|
}
|
|
1694
1712
|
}
|
|
1695
1713
|
}
|
|
@@ -1710,7 +1728,7 @@ const groups = {
|
|
|
1710
1728
|
}
|
|
1711
1729
|
},
|
|
1712
1730
|
nuVal: {
|
|
1713
|
-
'Element
|
|
1731
|
+
'Element a is missing required attribute aria-valuenow.': {
|
|
1714
1732
|
quality: 1,
|
|
1715
1733
|
what: 'a element has no aria-valuenow attribute'
|
|
1716
1734
|
}
|
|
@@ -1850,6 +1868,12 @@ const groups = {
|
|
|
1850
1868
|
quality: 1,
|
|
1851
1869
|
what: 'ARIA property value is invalid'
|
|
1852
1870
|
}
|
|
1871
|
+
},
|
|
1872
|
+
nuVal: {
|
|
1873
|
+
'The aria-hidden attribute must not be specified on the noscript element.': {
|
|
1874
|
+
quality: 1,
|
|
1875
|
+
what: 'noscript element has an aria-hidden attribute'
|
|
1876
|
+
}
|
|
1853
1877
|
}
|
|
1854
1878
|
}
|
|
1855
1879
|
},
|
|
@@ -2032,7 +2056,7 @@ const groups = {
|
|
|
2032
2056
|
weight: 4,
|
|
2033
2057
|
packages: {
|
|
2034
2058
|
nuVal: {
|
|
2035
|
-
'Bad value
|
|
2059
|
+
'^Bad value for attribute id on element .+: An ID must not be the empty string.+$': {
|
|
2036
2060
|
quality: 1,
|
|
2037
2061
|
what: 'id attribute has an empty value'
|
|
2038
2062
|
}
|
|
@@ -2066,6 +2090,12 @@ const groups = {
|
|
|
2066
2090
|
what: 'Heading element provides no descriptive text'
|
|
2067
2091
|
}
|
|
2068
2092
|
},
|
|
2093
|
+
nuVal: {
|
|
2094
|
+
'Empty heading.': {
|
|
2095
|
+
quality: 1,
|
|
2096
|
+
what: 'Empty heading'
|
|
2097
|
+
}
|
|
2098
|
+
},
|
|
2069
2099
|
wave: {
|
|
2070
2100
|
'e:heading_empty': {
|
|
2071
2101
|
quality: 1,
|
|
@@ -2089,11 +2119,11 @@ const groups = {
|
|
|
2089
2119
|
weight: 1,
|
|
2090
2120
|
packages: {
|
|
2091
2121
|
nuVal: {
|
|
2092
|
-
'The
|
|
2122
|
+
'The type attribute is unnecessary for JavaScript resources.': {
|
|
2093
2123
|
quality: 1,
|
|
2094
2124
|
what: 'type attribute is unnecessary for a JavaScript resource'
|
|
2095
2125
|
},
|
|
2096
|
-
'The
|
|
2126
|
+
'The type attribute for the style element is not needed and should be omitted.': {
|
|
2097
2127
|
quality: 1,
|
|
2098
2128
|
what: 'type attribute is unnecessary for a style element'
|
|
2099
2129
|
}
|
|
@@ -2185,8 +2215,14 @@ const groups = {
|
|
|
2185
2215
|
}
|
|
2186
2216
|
},
|
|
2187
2217
|
docType: {
|
|
2188
|
-
weight:
|
|
2218
|
+
weight: 3,
|
|
2189
2219
|
packages: {
|
|
2220
|
+
nuVal: {
|
|
2221
|
+
'Start tag seen without seeing a doctype first. Expected <!DOCTYPE html>.': {
|
|
2222
|
+
quality: 1,
|
|
2223
|
+
what: 'Page does not start with <!DOCTYPE html>'
|
|
2224
|
+
}
|
|
2225
|
+
},
|
|
2190
2226
|
testaro: {
|
|
2191
2227
|
docType: {
|
|
2192
2228
|
quality: 1,
|
|
@@ -2229,7 +2265,7 @@ const groups = {
|
|
|
2229
2265
|
}
|
|
2230
2266
|
},
|
|
2231
2267
|
nuVal: {
|
|
2232
|
-
'Element
|
|
2268
|
+
'Element head is missing a required instance of child element title.': {
|
|
2233
2269
|
quality: 1,
|
|
2234
2270
|
what: 'head element has no child title element'
|
|
2235
2271
|
}
|
|
@@ -2263,6 +2299,12 @@ const groups = {
|
|
|
2263
2299
|
what: 'Heading level is incorrect'
|
|
2264
2300
|
}
|
|
2265
2301
|
},
|
|
2302
|
+
nuVal: {
|
|
2303
|
+
'Consider using the h1 element as a top-level heading only (all h1 elements are treated as top-level headings by many screen readers and other tools).': {
|
|
2304
|
+
quality: 1,
|
|
2305
|
+
what: 'Page contains more than 1 h1 element'
|
|
2306
|
+
}
|
|
2307
|
+
},
|
|
2266
2308
|
tenon: {
|
|
2267
2309
|
155: {
|
|
2268
2310
|
quality: 1,
|
|
@@ -2328,11 +2370,26 @@ const groups = {
|
|
|
2328
2370
|
}
|
|
2329
2371
|
}
|
|
2330
2372
|
},
|
|
2373
|
+
articleHeadingless: {
|
|
2374
|
+
weight: 1,
|
|
2375
|
+
packages: {
|
|
2376
|
+
nuVal: {
|
|
2377
|
+
'Article lacks heading. Consider using h2-h6 elements to add identifying headings to all articles.': {
|
|
2378
|
+
quality: 1,
|
|
2379
|
+
what: 'article has no heading'
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
},
|
|
2331
2384
|
sectionHeadingless: {
|
|
2332
2385
|
weight: 1,
|
|
2333
2386
|
packages: {
|
|
2334
2387
|
nuVal: {
|
|
2335
|
-
'Section lacks heading. Consider using
|
|
2388
|
+
'Section lacks heading. Consider using h2-h6 elements to add identifying headings to all sections.': {
|
|
2389
|
+
quality: 1,
|
|
2390
|
+
what: 'section has no heading'
|
|
2391
|
+
},
|
|
2392
|
+
'Section lacks heading. Consider using h2-h6 elements to add identifying headings to all sections, or else use a div element instead for any cases where no heading is needed.': {
|
|
2336
2393
|
quality: 1,
|
|
2337
2394
|
what: 'section has no heading'
|
|
2338
2395
|
}
|
|
@@ -2499,7 +2556,7 @@ const groups = {
|
|
|
2499
2556
|
}
|
|
2500
2557
|
},
|
|
2501
2558
|
nuVal: {
|
|
2502
|
-
'Element
|
|
2559
|
+
'Element li not allowed as child of element div in this context. (Suppressing further errors from this subtree.)': {
|
|
2503
2560
|
quality: 1,
|
|
2504
2561
|
what: 'li element is a child of a div element'
|
|
2505
2562
|
}
|
|
@@ -3455,7 +3512,7 @@ const groups = {
|
|
|
3455
3512
|
weight: 2,
|
|
3456
3513
|
packages: {
|
|
3457
3514
|
nuVal: {
|
|
3458
|
-
'Potentially bad value
|
|
3515
|
+
'Potentially bad value allow-scripts allow-same-origin for attribute sandbox on element iframe: Setting both allow-scripts and allow-same-origin is not recommended, because it effectively enables an embedded page to break out of all sandboxing.': {
|
|
3459
3516
|
quality: 1,
|
|
3460
3517
|
what: 'iframe element has vulnerable sandbox="allow-scripts allow-same-origin"'
|
|
3461
3518
|
}
|
|
@@ -3535,6 +3592,22 @@ const groups = {
|
|
|
3535
3592
|
'^Attribute .+ not allowed on element .+ at this point.*$': {
|
|
3536
3593
|
quality: 1,
|
|
3537
3594
|
what: 'attribute not allowed on this element'
|
|
3595
|
+
},
|
|
3596
|
+
'^Bad value .+ for attribute .+ on element .+$': {
|
|
3597
|
+
quality: 1,
|
|
3598
|
+
what: 'attribute on this element has an invalid value'
|
|
3599
|
+
},
|
|
3600
|
+
'^Bad value .+ for the attribute .+$': {
|
|
3601
|
+
quality: 1,
|
|
3602
|
+
what: 'attribute has an invalid value'
|
|
3603
|
+
},
|
|
3604
|
+
'^Attribute .+ not allowed here.*$': {
|
|
3605
|
+
quality: 1,
|
|
3606
|
+
what: 'Attribute not allowed here'
|
|
3607
|
+
},
|
|
3608
|
+
'^Attribute .+ is not serializable as XML 1\\.0.*$': {
|
|
3609
|
+
quality: 1,
|
|
3610
|
+
what: 'Attribute is invalidly nonserializable'
|
|
3538
3611
|
}
|
|
3539
3612
|
}
|
|
3540
3613
|
}
|
|
@@ -3653,7 +3726,7 @@ const groups = {
|
|
|
3653
3726
|
weight: 4,
|
|
3654
3727
|
packages: {
|
|
3655
3728
|
nuVal: {
|
|
3656
|
-
'Element
|
|
3729
|
+
'Element div not allowed as child of element button in this context. (Suppressing further errors from this subtree.)': {
|
|
3657
3730
|
quality: 1,
|
|
3658
3731
|
what: 'div element has a button element as its parent'
|
|
3659
3732
|
}
|
|
@@ -3664,7 +3737,7 @@ const groups = {
|
|
|
3664
3737
|
weight: 4,
|
|
3665
3738
|
packages: {
|
|
3666
3739
|
nuVal: {
|
|
3667
|
-
'Element
|
|
3740
|
+
'Element p not allowed as child of element strong in this context. (Suppressing further errors from this subtree.)': {
|
|
3668
3741
|
quality: 1,
|
|
3669
3742
|
what: 'p element has a strong element as its parent'
|
|
3670
3743
|
}
|
|
@@ -3675,19 +3748,19 @@ const groups = {
|
|
|
3675
3748
|
weight: 4,
|
|
3676
3749
|
packages: {
|
|
3677
3750
|
nuVal: {
|
|
3678
|
-
'Element
|
|
3751
|
+
'Element style not allowed as child of element body in this context. (Suppressing further errors from this subtree.)': {
|
|
3679
3752
|
quality: 1,
|
|
3680
3753
|
what: 'style element not allowed as a child of the body element'
|
|
3681
3754
|
},
|
|
3682
|
-
'Element
|
|
3755
|
+
'Element style not allowed as child of element div in this context. (Suppressing further errors from this subtree.)': {
|
|
3683
3756
|
quality: 1,
|
|
3684
3757
|
what: 'style element not allowed as a child of this div element'
|
|
3685
3758
|
},
|
|
3686
|
-
'Element
|
|
3759
|
+
'Element style not allowed as child of element main in this context. (Suppressing further errors from this subtree.)': {
|
|
3687
3760
|
quality: 1,
|
|
3688
3761
|
what: 'style element not allowed as a child of this main element'
|
|
3689
3762
|
},
|
|
3690
|
-
'Element
|
|
3763
|
+
'Element style not allowed as child of element footer in this context. (Suppressing further errors from this subtree.)': {
|
|
3691
3764
|
quality: 1,
|
|
3692
3765
|
what: 'style element not allowed as a child of this footer element'
|
|
3693
3766
|
}
|
|
@@ -3953,21 +4026,41 @@ const groups = {
|
|
|
3953
4026
|
}
|
|
3954
4027
|
},
|
|
3955
4028
|
nuVal: {
|
|
3956
|
-
'The
|
|
4029
|
+
'The charset attribute on the script element is obsolete.': {
|
|
3957
4030
|
quality: 1,
|
|
3958
4031
|
what: 'charset attribute is obsolete on a script element'
|
|
3959
4032
|
},
|
|
3960
|
-
'The only allowed value for the
|
|
4033
|
+
'The only allowed value for the charset attribute for the script element is utf-8. (But the attribute is not needed and should be omitted altogether.)': {
|
|
3961
4034
|
quality: 1,
|
|
3962
4035
|
what: 'charset attribute has a value other than utf-8 and is unnecessary'
|
|
3963
4036
|
},
|
|
3964
|
-
'The
|
|
4037
|
+
'The language attribute on the script element is obsolete. You can safely omit it.': {
|
|
4038
|
+
quality: 1,
|
|
4039
|
+
what: 'language attribute is obsolete on a script element'
|
|
4040
|
+
},
|
|
4041
|
+
'The language attribute on the script element is obsolete. Use the type attribute instead.': {
|
|
4042
|
+
quality: 1,
|
|
4043
|
+
what: 'language attribute is obsolete on a script element'
|
|
4044
|
+
},
|
|
4045
|
+
'Using the meta element to specify the document-wide default language is obsolete. Consider specifying the language on the root element instead.': {
|
|
4046
|
+
quality: 1,
|
|
4047
|
+
what: 'language declaration in a meta element is obsolete'
|
|
4048
|
+
},
|
|
4049
|
+
'The frameborder attribute on the iframe element is obsolete. Use CSS instead.': {
|
|
3965
4050
|
quality: 1,
|
|
3966
4051
|
what: 'frameborder attribute is obsolete'
|
|
3967
4052
|
},
|
|
3968
|
-
'The
|
|
4053
|
+
'The name attribute is obsolete. Consider putting an id attribute on the nearest container instead.': {
|
|
3969
4054
|
quality: 1,
|
|
3970
4055
|
what: 'name attribute is obsolete'
|
|
4056
|
+
},
|
|
4057
|
+
'The allowtransparency attribute on the iframe element is obsolete. Use CSS instead.': {
|
|
4058
|
+
quality: 1,
|
|
4059
|
+
what: 'allowtransparency attribute on an iframe element is obsolete'
|
|
4060
|
+
},
|
|
4061
|
+
'The scrolling attribute on the iframe element is obsolete. Use CSS instead.': {
|
|
4062
|
+
quality: 1,
|
|
4063
|
+
what: 'scrolling attribute on an iframe element is obsolete'
|
|
3971
4064
|
}
|
|
3972
4065
|
},
|
|
3973
4066
|
wave: {
|
|
@@ -3982,33 +4075,61 @@ const groups = {
|
|
|
3982
4075
|
weight: 3,
|
|
3983
4076
|
packages: {
|
|
3984
4077
|
nuVal: {
|
|
3985
|
-
'CSS:
|
|
4078
|
+
'CSS: -webkit-box-flex: Parse Error.': {
|
|
3986
4079
|
quality: 1,
|
|
3987
4080
|
what: 'Invalid -webkit-box-flex in CSS'
|
|
3988
4081
|
},
|
|
3989
|
-
'CSS:
|
|
4082
|
+
'CSS: -webkit-flex: Parse Error.': {
|
|
3990
4083
|
quality: 1,
|
|
3991
4084
|
what: 'Invalid -webkit-flex in CSS'
|
|
3992
4085
|
},
|
|
3993
|
-
'CSS:
|
|
4086
|
+
'CSS: -ms-flex: Parse Error.': {
|
|
3994
4087
|
quality: 1,
|
|
3995
4088
|
what: 'Invalid -ms-flex in CSS'
|
|
3996
4089
|
},
|
|
3997
|
-
'CSS:
|
|
4090
|
+
'CSS: -moz-box-flex: Parse Error.': {
|
|
3998
4091
|
quality: 1,
|
|
3999
4092
|
what: 'Invalid -moz-box-flex in CSS'
|
|
4000
4093
|
},
|
|
4001
|
-
'CSS:
|
|
4094
|
+
'CSS: flex: Parse Error.': {
|
|
4002
4095
|
quality: 1,
|
|
4003
4096
|
what: 'Invalid flex in CSS'
|
|
4004
4097
|
},
|
|
4005
|
-
'
|
|
4098
|
+
'^CSS: cursor: .+ is not a cursor value.*$': {
|
|
4099
|
+
quality: 1,
|
|
4100
|
+
what: 'Invalid cursor in CSS'
|
|
4101
|
+
},
|
|
4102
|
+
'^CSS: transform: .+ is not a transform value.*$': {
|
|
4103
|
+
quality: 1,
|
|
4104
|
+
what: 'Invalid transform in CSS'
|
|
4105
|
+
},
|
|
4106
|
+
'^CSS: .+: Property .+ doesn\'t exist.*$': {
|
|
4107
|
+
quality: 1,
|
|
4108
|
+
what: 'Invalid property in CSS'
|
|
4109
|
+
},
|
|
4110
|
+
'^CSS: .+: only 0 can be a length. You must put a unit after your number.*$': {
|
|
4111
|
+
quality: 1,
|
|
4112
|
+
what: 'Length in CSS is nonzero but has no unit'
|
|
4113
|
+
},
|
|
4114
|
+
'CSS: Parse Error.': {
|
|
4115
|
+
quality: 1,
|
|
4116
|
+
what: 'Invalid CSS'
|
|
4117
|
+
},
|
|
4118
|
+
'Stray end tag head.': {
|
|
4006
4119
|
quality: 1,
|
|
4007
4120
|
what: 'Invalid closing head tag'
|
|
4008
4121
|
},
|
|
4009
|
-
'Start tag
|
|
4122
|
+
'^Start tag .+ seen but an element of the same type was already open.*$': {
|
|
4123
|
+
quality: 1,
|
|
4124
|
+
what: 'Element is invalidly a descendant of another such element'
|
|
4125
|
+
},
|
|
4126
|
+
'^End tag .+ violates nesting rules.*$': {
|
|
4127
|
+
quality: 1,
|
|
4128
|
+
what: 'End tag violates nesting rules'
|
|
4129
|
+
},
|
|
4130
|
+
'^Element .+ not allowed as child of element .+ in this context.*$': {
|
|
4010
4131
|
quality: 1,
|
|
4011
|
-
what: '
|
|
4132
|
+
what: 'Element not allowed as a child of its parent here'
|
|
4012
4133
|
}
|
|
4013
4134
|
}
|
|
4014
4135
|
}
|
|
@@ -4024,6 +4145,17 @@ const groups = {
|
|
|
4024
4145
|
}
|
|
4025
4146
|
}
|
|
4026
4147
|
},
|
|
4148
|
+
fatalError: {
|
|
4149
|
+
weight: 50,
|
|
4150
|
+
packages: {
|
|
4151
|
+
nuVal: {
|
|
4152
|
+
'Cannot recover after last error. Any further errors will be ignored.': {
|
|
4153
|
+
quality: 1,
|
|
4154
|
+
what: 'Testing was interrupted by a fatal error'
|
|
4155
|
+
}
|
|
4156
|
+
}
|
|
4157
|
+
}
|
|
4158
|
+
}
|
|
4027
4159
|
};
|
|
4028
4160
|
|
|
4029
4161
|
// VARIABLES
|
|
@@ -4086,7 +4218,7 @@ exports.scorer = async report => {
|
|
|
4086
4218
|
if (verdict && rule) {
|
|
4087
4219
|
const {ruleID} = rule;
|
|
4088
4220
|
if (ruleID) {
|
|
4089
|
-
// Add 4 per failure, 1 per warning (
|
|
4221
|
+
// Add 4 per failure, 1 per warning (cantTell).
|
|
4090
4222
|
addDetail(which, ruleID, verdict === 'failed' ? 4 : 1);
|
|
4091
4223
|
}
|
|
4092
4224
|
}
|
|
@@ -4171,7 +4303,7 @@ exports.scorer = async report => {
|
|
|
4171
4303
|
items.forEach(issue => {
|
|
4172
4304
|
const {ruleId, level} = issue;
|
|
4173
4305
|
if (ruleId && level) {
|
|
4174
|
-
// Add 4 per violation, 1 per warning (
|
|
4306
|
+
// Add 4 per violation, 1 per warning (recommendation).
|
|
4175
4307
|
addDetail(which, ruleId, level === 'violation' ? 4 : 1);
|
|
4176
4308
|
}
|
|
4177
4309
|
});
|
|
@@ -4217,7 +4349,7 @@ exports.scorer = async report => {
|
|
|
4217
4349
|
testIDs.forEach(testID => {
|
|
4218
4350
|
const {count} = items[testID];
|
|
4219
4351
|
if (count) {
|
|
4220
|
-
// Add 4 per error, 3 per contrast error, 1 per warning (
|
|
4352
|
+
// Add 4 per error, 3 per contrast error, 1 per warning (alert).
|
|
4221
4353
|
addDetail(
|
|
4222
4354
|
which, `${issueClass[0]}:${testID}`, count * classScores[issueClass]
|
|
4223
4355
|
);
|
|
@@ -4433,19 +4565,21 @@ exports.scorer = async report => {
|
|
|
4433
4565
|
// For each package with any scores:
|
|
4434
4566
|
Object.keys(packageDetails).forEach(packageName => {
|
|
4435
4567
|
const matchers = testMatchers[packageName];
|
|
4568
|
+
let testClass = '';
|
|
4436
4569
|
// For each test with any scores in the package:
|
|
4437
4570
|
Object.keys(packageDetails[packageName]).forEach(testID => {
|
|
4438
|
-
//
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4571
|
+
// Determine whether the test is in a group.
|
|
4572
|
+
let groupName = testGroups[packageName][testID];
|
|
4573
|
+
// If not:
|
|
4574
|
+
if (! groupName) {
|
|
4575
|
+
// Determine whether the package has test classes and the class is in a group.
|
|
4576
|
+
testClass = matchers && matchers.find(matcher => matcher.test(testID));
|
|
4577
|
+
if (testClass) {
|
|
4578
|
+
testID = testClass.source;
|
|
4579
|
+
groupName = testGroups[packageName][testID];
|
|
4445
4580
|
}
|
|
4446
4581
|
}
|
|
4447
|
-
// If the test is in a group:
|
|
4448
|
-
const groupName = testGroups[packageName][testID];
|
|
4582
|
+
// If the test or its class is in a group:
|
|
4449
4583
|
if (groupName) {
|
|
4450
4584
|
// Determine the preweighted or group-weighted score.
|
|
4451
4585
|
if (! groupDetails.groups[groupName]) {
|
|
@@ -4467,6 +4601,10 @@ exports.scorer = async report => {
|
|
|
4467
4601
|
score: roundedScore,
|
|
4468
4602
|
what: groups[groupName].packages[packageName][testID].what
|
|
4469
4603
|
};
|
|
4604
|
+
}
|
|
4605
|
+
// Otherwise, if the package has varying test names and the test belongs to a class:
|
|
4606
|
+
else if (matchers && (testCode = matchers.find(matcher => matcher.test(testID)))) {
|
|
4607
|
+
|
|
4470
4608
|
}
|
|
4471
4609
|
// Otherwise, i.e. if the test is solo:
|
|
4472
4610
|
else {
|