testilo 20.0.3 → 21.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.
- package/package.json +1 -1
- package/procs/digest/{tdp37 → tdp38}/index.js +10 -5
- package/procs/score/tic38.js +130 -13
- package/procs/score/tsp38.js +1 -1
- package/procs/digest/tdp31/index.html +0 -72
- package/procs/digest/tdp31/index.js +0 -105
- package/procs/digest/tdp33/index.html +0 -72
- package/procs/digest/tdp33/index.js +0 -105
- package/procs/digest/tdp33h/index.html +0 -82
- package/procs/digest/tdp33h/index.js +0 -111
- package/procs/digest/tdp36/index.html +0 -72
- package/procs/digest/tdp36/index.js +0 -96
- package/procs/score/tic31.js +0 -7235
- package/procs/score/tic32.js +0 -7274
- package/procs/score/tic33.js +0 -7524
- package/procs/score/tic34.js +0 -7538
- package/procs/score/tic35.js +0 -7413
- package/procs/score/tic36.js +0 -8215
- package/procs/score/tic37.js +0 -8543
- package/procs/score/tsp31.js +0 -241
- package/procs/score/tsp33.js +0 -278
- package/procs/score/tsp36.js +0 -278
- package/procs/score/tsp37.js +0 -292
- /package/procs/digest/{tdp37 → tdp38}/index.html +0 -0
package/package.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
// IMPORTS
|
|
4
4
|
|
|
5
5
|
// Module to classify tool rules into issues
|
|
6
|
-
const {issues} = require('../../score/
|
|
6
|
+
const {issues} = require('../../score/tic38');
|
|
7
7
|
// Module to process files.
|
|
8
8
|
const fs = require('fs/promises');
|
|
9
9
|
|
|
10
10
|
// CONSTANTS
|
|
11
11
|
|
|
12
12
|
// Digester ID.
|
|
13
|
-
const id = '
|
|
13
|
+
const id = 'tdp38';
|
|
14
14
|
// Newline with indentations.
|
|
15
15
|
const innerJoiner = '\n ';
|
|
16
16
|
|
|
@@ -53,9 +53,14 @@ const populateQuery = (report, query) => {
|
|
|
53
53
|
// Get rows for the issue-score table.
|
|
54
54
|
issueIDs.forEach(issueID => {
|
|
55
55
|
const {score, tools} = details.issue[issueID];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if (issues[issueID]) {
|
|
57
|
+
rows.issueRows.push(
|
|
58
|
+
getIssueScoreRow(issues[issueID].summary, issues[issueID].wcag, score, Object.keys(tools))
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.log(`ERROR: Issue ${issueID} not found`);
|
|
63
|
+
}
|
|
59
64
|
});
|
|
60
65
|
// Add the rows to the query.
|
|
61
66
|
['summaryRows', 'issueRows'].forEach(rowType => {
|
package/procs/score/tic38.js
CHANGED
|
@@ -54,6 +54,11 @@ exports.issues = {
|
|
|
54
54
|
quality: 0,
|
|
55
55
|
what: 'Document contains a commercial overlay modifier that may fail or invalidate test results [unreliable]'
|
|
56
56
|
},
|
|
57
|
+
object_missing_body: {
|
|
58
|
+
variable: false,
|
|
59
|
+
quality: 0,
|
|
60
|
+
what: 'object element has no body to act as a text alternative [invalid]'
|
|
61
|
+
},
|
|
57
62
|
reflow: {
|
|
58
63
|
variable: false,
|
|
59
64
|
quality: 0,
|
|
@@ -1328,7 +1333,7 @@ exports.issues = {
|
|
|
1328
1333
|
summary: 'label referent ineligible',
|
|
1329
1334
|
why: 'User cannot get help understanding an item in a form',
|
|
1330
1335
|
wcag: '1.3.1',
|
|
1331
|
-
weight:
|
|
1336
|
+
weight: 4,
|
|
1332
1337
|
tools: {
|
|
1333
1338
|
aslint: {
|
|
1334
1339
|
label_inappropriate_associationN: {
|
|
@@ -1360,6 +1365,21 @@ exports.issues = {
|
|
|
1360
1365
|
}
|
|
1361
1366
|
}
|
|
1362
1367
|
},
|
|
1368
|
+
buttonIDInLabelBad: {
|
|
1369
|
+
summary: 'label contains button with nonmatching ID',
|
|
1370
|
+
why: 'User cannot get help understanding an item in a form',
|
|
1371
|
+
wcag: '1.3.1',
|
|
1372
|
+
weight: 4,
|
|
1373
|
+
tools: {
|
|
1374
|
+
nuVal: {
|
|
1375
|
+
'Any button descendant of a label element with a for attribute must have an ID value that matches that for attribute.': {
|
|
1376
|
+
variable: false,
|
|
1377
|
+
quality: 1,
|
|
1378
|
+
what: 'label element has a button descendant whose ID differs from the for attribute of the label'
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
},
|
|
1363
1383
|
ariaLabelWrongRisk: {
|
|
1364
1384
|
summary: 'dubious aria-label',
|
|
1365
1385
|
why: 'User may fail to get help understanding an item in a form',
|
|
@@ -1988,6 +2008,21 @@ exports.issues = {
|
|
|
1988
2008
|
}
|
|
1989
2009
|
}
|
|
1990
2010
|
},
|
|
2011
|
+
linkPairRisk: {
|
|
2012
|
+
summary: 'text and image link may merit combination',
|
|
2013
|
+
why: 'Keyboard-only user may expend extra effort to skip a link',
|
|
2014
|
+
wcag: '2.4.4',
|
|
2015
|
+
weight: 1,
|
|
2016
|
+
tools: {
|
|
2017
|
+
htmlcs: {
|
|
2018
|
+
'AAA.1_1_1.H2.EG4': {
|
|
2019
|
+
variable: false,
|
|
2020
|
+
quality: 1,
|
|
2021
|
+
what: 'Adjacent links, one with text and the other with a textless image, may merit combination'
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
},
|
|
1991
2026
|
pageNewWindow: {
|
|
1992
2027
|
summary: 'page immediately opens window',
|
|
1993
2028
|
why: 'User promised a document gets another document, too',
|
|
@@ -2624,29 +2659,34 @@ exports.issues = {
|
|
|
2624
2659
|
'AAA.2_4_8.H59.1': {
|
|
2625
2660
|
variable: false,
|
|
2626
2661
|
quality: 1,
|
|
2627
|
-
what: '
|
|
2662
|
+
what: 'Element is not in the document head'
|
|
2663
|
+
},
|
|
2664
|
+
'AAA.2_4_8.H59.2a': {
|
|
2665
|
+
variable: false,
|
|
2666
|
+
quality: 1,
|
|
2667
|
+
what: 'Element has no nonempty rel attribute for the type'
|
|
2628
2668
|
},
|
|
2629
2669
|
'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.': {
|
|
2630
2670
|
variable: false,
|
|
2631
2671
|
quality: 1,
|
|
2632
|
-
what: '
|
|
2672
|
+
what: 'Element with an as attribute has no rel attribute with preload, modulepreload, or prefetch as its value'
|
|
2633
2673
|
}
|
|
2634
2674
|
},
|
|
2635
2675
|
nuVal: {
|
|
2636
2676
|
'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.': {
|
|
2637
2677
|
variable: false,
|
|
2638
2678
|
quality: 1,
|
|
2639
|
-
what: '
|
|
2679
|
+
what: 'Element has a body ancestor but no itemprop or valid rel attribute'
|
|
2640
2680
|
},
|
|
2641
2681
|
'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.': {
|
|
2642
2682
|
variable: false,
|
|
2643
2683
|
quality: 1,
|
|
2644
|
-
what: '
|
|
2684
|
+
what: 'Element has an as attribute but no rel attribute with preload, modulepreload, or prefetch as its value'
|
|
2645
2685
|
},
|
|
2646
2686
|
'A link element with an as attribute must have a rel attribute that contains the value preload or the value modulepreload.': {
|
|
2647
2687
|
variable: false,
|
|
2648
2688
|
quality: 1,
|
|
2649
|
-
what: '
|
|
2689
|
+
what: 'Element has an as attribute but no rel attribute with preload or modulepreload as its value'
|
|
2650
2690
|
}
|
|
2651
2691
|
}
|
|
2652
2692
|
}
|
|
@@ -2666,17 +2706,17 @@ exports.issues = {
|
|
|
2666
2706
|
'^Element meta is missing one or more of the following attributes: .+$': {
|
|
2667
2707
|
variable: true,
|
|
2668
2708
|
quality: 1,
|
|
2669
|
-
what: '
|
|
2709
|
+
what: 'Element is missing a required attribute'
|
|
2670
2710
|
},
|
|
2671
2711
|
'A document must not include more than one meta element with its name attribute set to the value description.': {
|
|
2672
2712
|
variable: false,
|
|
2673
2713
|
quality: 1,
|
|
2674
|
-
what: '
|
|
2714
|
+
what: 'Element with name="description" is not the only meta element with that name'
|
|
2675
2715
|
},
|
|
2676
2716
|
'A document must not include both a meta element with an http-equiv attribute whose value is content-type, and a meta element with a charset attribute.': {
|
|
2677
2717
|
variable: false,
|
|
2678
2718
|
quality: 1,
|
|
2679
|
-
what: '
|
|
2719
|
+
what: 'Element with http-equiv="content-type" is incompatible with the meta element with a charset attribute'
|
|
2680
2720
|
},
|
|
2681
2721
|
'A document must not include more than one meta element with a http-equiv attribute whose value is content-type.': {
|
|
2682
2722
|
variable: false,
|
|
@@ -2686,7 +2726,7 @@ exports.issues = {
|
|
|
2686
2726
|
'A meta element with an http-equiv attribute whose value is X-UA-Compatible must have a content attribute with the value IE=edge.': {
|
|
2687
2727
|
variable: false,
|
|
2688
2728
|
quality: 1,
|
|
2689
|
-
what: '
|
|
2729
|
+
what: 'Element with http-equiv="X-UA-Compatible" has no content="IE=edge"'
|
|
2690
2730
|
},
|
|
2691
2731
|
'A document must not include more than one meta element with a charset attribute.': {
|
|
2692
2732
|
variable: false,
|
|
@@ -3510,7 +3550,7 @@ exports.issues = {
|
|
|
3510
3550
|
},
|
|
3511
3551
|
requirementRedundant: {
|
|
3512
3552
|
summary: 'requirement redundant',
|
|
3513
|
-
why: 'Help determining whether a form item must be completed is
|
|
3553
|
+
why: 'Help determining whether a form item must be completed is at risk of corruption',
|
|
3514
3554
|
wcag: '1.3.5',
|
|
3515
3555
|
weight: 1,
|
|
3516
3556
|
tools: {
|
|
@@ -3884,6 +3924,21 @@ exports.issues = {
|
|
|
3884
3924
|
}
|
|
3885
3925
|
}
|
|
3886
3926
|
},
|
|
3927
|
+
typeBad: {
|
|
3928
|
+
summary: 'type invalid',
|
|
3929
|
+
why: 'Document styles are at risk of corruption',
|
|
3930
|
+
wcag: '1.3.1',
|
|
3931
|
+
weight: 4,
|
|
3932
|
+
tools: {
|
|
3933
|
+
nuVal: {
|
|
3934
|
+
'The only allowed value for the type attribute for the style element is text/css (with no parameters). (But the attribute is not needed and should be omitted altogether.)': {
|
|
3935
|
+
variable: false,
|
|
3936
|
+
quality: 1,
|
|
3937
|
+
what: 'type attribute is invalid'
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
},
|
|
3887
3942
|
typeRedundant: {
|
|
3888
3943
|
summary: 'type redundant',
|
|
3889
3944
|
why: 'Document includes unnecessary code',
|
|
@@ -4125,6 +4180,13 @@ exports.issues = {
|
|
|
4125
4180
|
what: 'Document head element contains an empty title element'
|
|
4126
4181
|
}
|
|
4127
4182
|
},
|
|
4183
|
+
ibm: {
|
|
4184
|
+
'page_title_exists': {
|
|
4185
|
+
variable: false,
|
|
4186
|
+
quality: 1,
|
|
4187
|
+
what: 'Page has no title'
|
|
4188
|
+
}
|
|
4189
|
+
},
|
|
4128
4190
|
nuVal: {
|
|
4129
4191
|
'Element head is missing a required instance of child element title.': {
|
|
4130
4192
|
variable: false,
|
|
@@ -4605,7 +4667,22 @@ exports.issues = {
|
|
|
4605
4667
|
listitem: {
|
|
4606
4668
|
variable: false,
|
|
4607
4669
|
quality: 1,
|
|
4608
|
-
what: '
|
|
4670
|
+
what: 'Element is not contained by a ul or ol element'
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
},
|
|
4675
|
+
descriptionOrphan: {
|
|
4676
|
+
summary: 'description list orphan',
|
|
4677
|
+
why: 'User cannot get help on whether an item is in a list',
|
|
4678
|
+
wcag: '1.3.1',
|
|
4679
|
+
weight: 4,
|
|
4680
|
+
tools: {
|
|
4681
|
+
qualWeb: {
|
|
4682
|
+
'The test target is not contained in a correct description list element.': {
|
|
4683
|
+
variable: false,
|
|
4684
|
+
quality: 1,
|
|
4685
|
+
what: 'Element is not contained by a valid dl element'
|
|
4609
4686
|
}
|
|
4610
4687
|
}
|
|
4611
4688
|
}
|
|
@@ -7659,7 +7736,7 @@ exports.issues = {
|
|
|
7659
7736
|
},
|
|
7660
7737
|
obsolete: {
|
|
7661
7738
|
summary: 'code obsolete',
|
|
7662
|
-
why: 'Document contains
|
|
7739
|
+
why: 'Document contains code that is no longer standard',
|
|
7663
7740
|
wcag: '4.1',
|
|
7664
7741
|
weight: 3,
|
|
7665
7742
|
tools: {
|
|
@@ -7676,6 +7753,11 @@ exports.issues = {
|
|
|
7676
7753
|
}
|
|
7677
7754
|
},
|
|
7678
7755
|
nuVal: {
|
|
7756
|
+
'Legacy doctype. Expected <!DOCTYPE html>.': {
|
|
7757
|
+
variable: false,
|
|
7758
|
+
quality: 1,
|
|
7759
|
+
what: 'doctype is obsolete'
|
|
7760
|
+
},
|
|
7679
7761
|
'Obsolete doctype. Expected <!DOCTYPE html>.': {
|
|
7680
7762
|
variable: false,
|
|
7681
7763
|
quality: 1,
|
|
@@ -7711,11 +7793,21 @@ exports.issues = {
|
|
|
7711
7793
|
quality: 1,
|
|
7712
7794
|
what: 'CSS style sheet includes HTML syntax'
|
|
7713
7795
|
},
|
|
7796
|
+
'^CSS: column-count: .+ is not valid, only values greater than 0 allowed.*$': {
|
|
7797
|
+
variable: true,
|
|
7798
|
+
quality: 1,
|
|
7799
|
+
what: 'CSS column-count property has a nonpositive value'
|
|
7800
|
+
},
|
|
7714
7801
|
'CSS: font-size: One operand must be a number.': {
|
|
7715
7802
|
variable: false,
|
|
7716
7803
|
quality: 1,
|
|
7717
7804
|
what: 'CSS font-size property has no numeric operand'
|
|
7718
7805
|
},
|
|
7806
|
+
'^CSS: font-weight: .+ is not valid, only values greater than or equal to 1.0 are allowed.*$': {
|
|
7807
|
+
variable: true,
|
|
7808
|
+
quality: 1,
|
|
7809
|
+
what: 'CSS font-weight property has a value smaller than 1'
|
|
7810
|
+
},
|
|
7719
7811
|
'^CSS: .+: Parse Error.*$': {
|
|
7720
7812
|
variable: true,
|
|
7721
7813
|
quality: 1,
|
|
@@ -7811,6 +7903,11 @@ exports.issues = {
|
|
|
7811
7903
|
quality: 1,
|
|
7812
7904
|
what: 'CSS @charset at-rule is not at the start of its style sheet'
|
|
7813
7905
|
},
|
|
7906
|
+
'CSS: @import are not allowed after any valid statement other than @charset and @import.': {
|
|
7907
|
+
variable: false,
|
|
7908
|
+
quality: 1,
|
|
7909
|
+
what: 'CSS @import at-rule is after an at-rule other than @charset or @import'
|
|
7910
|
+
},
|
|
7814
7911
|
'^CSS: perspective: .+ is not valid, only values greater than 0 allowed.*$': {
|
|
7815
7912
|
variable: true,
|
|
7816
7913
|
quality: 0.5,
|
|
@@ -7988,11 +8085,26 @@ exports.issues = {
|
|
|
7988
8085
|
quality: 1,
|
|
7989
8086
|
what: 'Comment contains --'
|
|
7990
8087
|
},
|
|
8088
|
+
'The document is not mappable to XML 1.0 due to a trailing hyphen in a comment.': {
|
|
8089
|
+
variable: false,
|
|
8090
|
+
quality: 1,
|
|
8091
|
+
what: 'Comment ends with -'
|
|
8092
|
+
},
|
|
8093
|
+
'Bogus comment.': {
|
|
8094
|
+
variable: false,
|
|
8095
|
+
quality: 1,
|
|
8096
|
+
what: 'Comment is missing a valid termination'
|
|
8097
|
+
},
|
|
7991
8098
|
'^Element name .+ cannot be represented as XML 1\\.0.*$': {
|
|
7992
8099
|
variable: true,
|
|
7993
8100
|
quality: 1,
|
|
7994
8101
|
what: 'Invalid element name'
|
|
7995
8102
|
},
|
|
8103
|
+
'^Bad element name .*: Code point .* is not allowed*$': {
|
|
8104
|
+
variable: true,
|
|
8105
|
+
quality: 1,
|
|
8106
|
+
what: 'Element name contains an invalid character'
|
|
8107
|
+
},
|
|
7996
8108
|
'^Forbidden code point U+.+$': {
|
|
7997
8109
|
variable: true,
|
|
7998
8110
|
quality: 1,
|
|
@@ -8073,6 +8185,11 @@ exports.issues = {
|
|
|
8073
8185
|
quality: 1,
|
|
8074
8186
|
what: 'Element with a srcset attribute with a width has no sizes attribute'
|
|
8075
8187
|
},
|
|
8188
|
+
'When the srcset attribute has any image candidate string with a width descriptor, the sizes attribute must also be specified.': {
|
|
8189
|
+
variable: false,
|
|
8190
|
+
quality: 1,
|
|
8191
|
+
what: 'Element with a srcset attribute with a width has no valid sizes attribute'
|
|
8192
|
+
},
|
|
8076
8193
|
'^The text content of element .+ was not in the required format: Expected .+ but found .+ instead.*$': {
|
|
8077
8194
|
variable: true,
|
|
8078
8195
|
quality: 1,
|
package/procs/score/tsp38.js
CHANGED
|
@@ -283,7 +283,7 @@ exports.scorer = report => {
|
|
|
283
283
|
+ summary.prevention
|
|
284
284
|
+ summary.log
|
|
285
285
|
+ summary.latency;
|
|
286
|
-
// Add the score to the report.
|
|
286
|
+
// Add the score to the report or replace the existing score of the report.
|
|
287
287
|
report.score = score;
|
|
288
288
|
}
|
|
289
289
|
// Otherwise, i.e. if none of them is a test act:
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE HTML>
|
|
2
|
-
<html lang="en-US">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<meta name="author" content="Testilo">
|
|
7
|
-
<meta name="creator" content="Testilo">
|
|
8
|
-
<meta name="publisher" name="Testilo">
|
|
9
|
-
<meta name="description" content="report of accessibility testing of a web page">
|
|
10
|
-
<meta name="keywords" content="accessibility a11y web testing">
|
|
11
|
-
<title>Accessibility digest</title>
|
|
12
|
-
<link rel="icon" href="favicon.png">
|
|
13
|
-
<link rel="stylesheet" href="style.css">
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<main>
|
|
17
|
-
<header>
|
|
18
|
-
<h1>Accessibility digest</h1>
|
|
19
|
-
<table class="allBorder">
|
|
20
|
-
<caption>Synopsis</caption>
|
|
21
|
-
<tr><th>Page</th><td>__org__</td></tr>
|
|
22
|
-
<tr><th>URL</th><td>__url__</td></tr>
|
|
23
|
-
<tr><th>Requester</th><td>__requester__</td></tr>
|
|
24
|
-
<tr><th>Test date</th><td>__dateSlash__</td></tr>
|
|
25
|
-
<tr><th>Score</th><td>__total__</td></tr>
|
|
26
|
-
<tr><th>Tested by</th><td>Testaro, procedure <code>__ts__</code></td></tr>
|
|
27
|
-
<tr><th>Scored by</th><td>Testilo, procedure <code>__sp__</code></td></tr>
|
|
28
|
-
<tr><th>Digested by</th><td>Testilo, procedure <code>__dp__</code></td></tr>
|
|
29
|
-
</table>
|
|
30
|
-
</header>
|
|
31
|
-
<h2>Introduction</h2>
|
|
32
|
-
<p>This is a digest of results from a battery of <a href="https://www.w3.org/WAI/">web accessibility</a> tests.</p>
|
|
33
|
-
<p>Nine different <dfn>tools</dfn> (Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, QualWeb, Testaro, and WAVE) tested the web page of __org__ at __url__ to check its compliance with various <dfn>rules</dfn>. There were a total of about 900 rules, classified into about 260 accessibility <dfn>issues</dfn>.</p>
|
|
34
|
-
<p>The results were interpreted to yield an aggregate score of __total__, where 0 would be <q>perfect</q>.</p>
|
|
35
|
-
<h2>Total score</h2>
|
|
36
|
-
<p>The total score is the sum of five components.</p>
|
|
37
|
-
<table class="allBorder secondCellRight">
|
|
38
|
-
<caption>Score summary</caption>
|
|
39
|
-
<thead>
|
|
40
|
-
<tr><th>Component</th><th>Score</th><th>Description</th></tr>
|
|
41
|
-
</thead>
|
|
42
|
-
<tbody class="headersLeft">
|
|
43
|
-
<tr><th>total</th><td>__total__</td><td>Sum of the component scores</td></tr>
|
|
44
|
-
<tr><th>issue</th><td>__issue__</td><td>Severity and number of reported defects</td></tr>
|
|
45
|
-
<tr><th>tool</th><td>__tool__</td><td>Tool-by-tool defect ratings</td></tr>
|
|
46
|
-
<tr><th>prevention</th><td>__prevention__</td><td>Failed attempts by tools to test the page</td></tr>
|
|
47
|
-
<tr><th>log</th><td>__log__</td><td>Browser warnings about the page</td></tr>
|
|
48
|
-
<tr><th>latency</th><td>__latency__</td><td>Abnormal delay in page responses</td></tr>
|
|
49
|
-
</tbody>
|
|
50
|
-
</table>
|
|
51
|
-
<h2>Issue scores</h2>
|
|
52
|
-
<p>The score of an issue depends on the <dfn>severity</dfn> (user impact and certainty) of the issue and on how many instances were reported (by one or more tools).</p>
|
|
53
|
-
<table class="allBorder secondCellRight">
|
|
54
|
-
<caption>Issue scores</caption>
|
|
55
|
-
<thead>
|
|
56
|
-
<tr><th>Issue</th><th>Score</th></tr>
|
|
57
|
-
</thead>
|
|
58
|
-
<tbody class="headersLeft">
|
|
59
|
-
__issueRows__
|
|
60
|
-
</tbody>
|
|
61
|
-
</table>
|
|
62
|
-
<h2>Itemized issues</h2>
|
|
63
|
-
<p>The reported rule violations are itemized below, issue by issue. Additional details can be inspected in the complete report at the end of this page.</p>
|
|
64
|
-
__issueDetailRows__
|
|
65
|
-
<h2>Complete report</h2>
|
|
66
|
-
<pre>__report__</pre>
|
|
67
|
-
<footer>
|
|
68
|
-
<p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
|
|
69
|
-
</footer>
|
|
70
|
-
</main>
|
|
71
|
-
</body>
|
|
72
|
-
</html>
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
// index: digester for scoring procedure tsp28.
|
|
2
|
-
|
|
3
|
-
// IMPORTS
|
|
4
|
-
|
|
5
|
-
// Issue classification
|
|
6
|
-
const {issues} = require('../../score/tic31');
|
|
7
|
-
// Function to process files.
|
|
8
|
-
const fs = require('fs/promises');
|
|
9
|
-
|
|
10
|
-
// CONSTANTS
|
|
11
|
-
|
|
12
|
-
// Digester ID.
|
|
13
|
-
const id = 'tdp31';
|
|
14
|
-
// Newlines with indentations.
|
|
15
|
-
const joiner = '\n ';
|
|
16
|
-
const innerJoiner = '\n ';
|
|
17
|
-
|
|
18
|
-
// FUNCTIONS
|
|
19
|
-
|
|
20
|
-
// Makes strings HTML-safe.
|
|
21
|
-
const htmlEscape = textOrNumber => textOrNumber
|
|
22
|
-
.toString()
|
|
23
|
-
.replace(/&/g, '&')
|
|
24
|
-
.replace(/</g, '<');
|
|
25
|
-
// Gets a row of the score-summary table.
|
|
26
|
-
const getScoreRow = (componentName, score) => `<tr><th>${componentName}</th><td>${score}</td></tr>`;
|
|
27
|
-
// Adds parameters to a query for a digest.
|
|
28
|
-
const populateQuery = (report, query) => {
|
|
29
|
-
const {sources, jobData, score} = report;
|
|
30
|
-
const {script, target, requester} = sources;
|
|
31
|
-
const {scoreProcID, summary, details} = score;
|
|
32
|
-
query.ts = script;
|
|
33
|
-
query.sp = scoreProcID;
|
|
34
|
-
query.dp = id;
|
|
35
|
-
// Add the job data to the query.
|
|
36
|
-
query.dateISO = jobData.endTime.slice(0, 10);
|
|
37
|
-
query.dateSlash = query.dateISO.replace(/-/g, '/');
|
|
38
|
-
query.org = target.what;
|
|
39
|
-
query.url = target.which;
|
|
40
|
-
query.requester = requester;
|
|
41
|
-
// Add values for the score-summary table to the query.
|
|
42
|
-
const rows = {
|
|
43
|
-
summaryRows: [],
|
|
44
|
-
issueRows: []
|
|
45
|
-
};
|
|
46
|
-
['total', 'issue', 'tool', 'prevention', 'log', 'latency'].forEach(sumItem => {
|
|
47
|
-
query[sumItem] = summary[sumItem];
|
|
48
|
-
rows.summaryRows.push(getScoreRow(sumItem, query[sumItem]));
|
|
49
|
-
});
|
|
50
|
-
// Sort the issue IDs in descending score order.
|
|
51
|
-
const issueIDs = Object.keys(details.issue);
|
|
52
|
-
issueIDs.sort((a, b) => details.issue[b].score - details.issue[a].score);
|
|
53
|
-
// Get rows for the issue-score table.
|
|
54
|
-
issueIDs.forEach(issueID => {
|
|
55
|
-
rows.issueRows.push(getScoreRow(issueID, details.issue[issueID].score));
|
|
56
|
-
});
|
|
57
|
-
// Add the rows to the query.
|
|
58
|
-
['summaryRows', 'issueRows'].forEach(rowType => {
|
|
59
|
-
query[rowType] = rows[rowType].join(innerJoiner);
|
|
60
|
-
});
|
|
61
|
-
// Add paragraph groups about the issue details to the query.
|
|
62
|
-
const issueDetailRows = [];
|
|
63
|
-
issueIDs.forEach(issueID => {
|
|
64
|
-
issueDetailRows.push(`<h3 class="bars">Issue <code>${issueID}</code></h3>`);
|
|
65
|
-
issueDetailRows.push(`<p>WCAG: ${issues[issueID].wcag || 'N/A'}</p>`);
|
|
66
|
-
const issueData = details.issue[issueID];
|
|
67
|
-
issueDetailRows.push(`<p>Score: ${issueData.score}</p>`);
|
|
68
|
-
const toolIDs = Object.keys(issueData.tools);
|
|
69
|
-
toolIDs.forEach(toolID => {
|
|
70
|
-
issueDetailRows.push(`<h4>Complaints by <code>${toolID}</code></h5>`);
|
|
71
|
-
const ruleIDs = Object.keys(issueData.tools[toolID]);
|
|
72
|
-
ruleIDs.forEach(ruleID => {
|
|
73
|
-
const ruleData = issueData.tools[toolID][ruleID];
|
|
74
|
-
issueDetailRows.push(`<h5>Rule <code>${ruleID}</code></h5>`);
|
|
75
|
-
issueDetailRows.push(`<p>Description: ${ruleData.what}</p>`);
|
|
76
|
-
issueDetailRows.push(`<p>Count of instances: ${ruleData.complaints.countTotal}</p>`);
|
|
77
|
-
issueDetailRows.push('<h6>Complaint specifics</h6>');
|
|
78
|
-
issueDetailRows.push('<ul>');
|
|
79
|
-
ruleData.complaints.texts.forEach(text => {
|
|
80
|
-
issueDetailRows.push(` <li>${htmlEscape(text || '')}</li>`);
|
|
81
|
-
});
|
|
82
|
-
issueDetailRows.push('</ul>');
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
query.issueDetailRows = issueDetailRows.join(innerJoiner);
|
|
87
|
-
// Add an HTML-safe copy of the report to the query to be appended to the digest.
|
|
88
|
-
const reportJSON = JSON.stringify(report, null, 2);
|
|
89
|
-
const reportJSONSafe = htmlEscape(reportJSON);
|
|
90
|
-
query.report = reportJSONSafe;
|
|
91
|
-
};
|
|
92
|
-
// Returns a digested report.
|
|
93
|
-
exports.digester = async report => {
|
|
94
|
-
// Create a query to replace placeholders.
|
|
95
|
-
const query = {};
|
|
96
|
-
populateQuery(report, query);
|
|
97
|
-
// Get the template.
|
|
98
|
-
let template = await fs.readFile(`${__dirname}/index.html`, 'utf8');
|
|
99
|
-
// Replace its placeholders.
|
|
100
|
-
Object.keys(query).forEach(param => {
|
|
101
|
-
template = template.replace(new RegExp(`__${param}__`, 'g'), query[param]);
|
|
102
|
-
});
|
|
103
|
-
// Return the digest.
|
|
104
|
-
return template;
|
|
105
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE HTML>
|
|
2
|
-
<html lang="en-US">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<meta name="author" content="Testilo">
|
|
7
|
-
<meta name="creator" content="Testilo">
|
|
8
|
-
<meta name="publisher" name="Testilo">
|
|
9
|
-
<meta name="description" content="report of accessibility testing of a web page">
|
|
10
|
-
<meta name="keywords" content="accessibility a11y web testing">
|
|
11
|
-
<title>Accessibility digest</title>
|
|
12
|
-
<link rel="icon" href="favicon.png">
|
|
13
|
-
<link rel="stylesheet" href="style.css">
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<main>
|
|
17
|
-
<header>
|
|
18
|
-
<h1>Accessibility digest</h1>
|
|
19
|
-
<table class="allBorder">
|
|
20
|
-
<caption>Synopsis</caption>
|
|
21
|
-
<tr><th>Page</th><td>__org__</td></tr>
|
|
22
|
-
<tr><th>URL</th><td>__url__</td></tr>
|
|
23
|
-
<tr><th>Requester</th><td>__requester__</td></tr>
|
|
24
|
-
<tr><th>Test date</th><td>__dateSlash__</td></tr>
|
|
25
|
-
<tr><th>Score</th><td>__total__</td></tr>
|
|
26
|
-
<tr><th>Tested by</th><td>Testaro, procedure <code>__ts__</code></td></tr>
|
|
27
|
-
<tr><th>Scored by</th><td>Testilo, procedure <code>__sp__</code></td></tr>
|
|
28
|
-
<tr><th>Digested by</th><td>Testilo, procedure <code>__dp__</code></td></tr>
|
|
29
|
-
</table>
|
|
30
|
-
</header>
|
|
31
|
-
<h2>Introduction</h2>
|
|
32
|
-
<p>This is a digest of results from a battery of <a href="https://www.w3.org/WAI/">web accessibility</a> tests.</p>
|
|
33
|
-
<p>Nine different <dfn>tools</dfn> (Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, QualWeb, Testaro, and WAVE) tested the web page of __org__ at __url__ to check its compliance with various <dfn>rules</dfn>. There were a total of about 900 rules, classified into about 260 accessibility <dfn>issues</dfn>.</p>
|
|
34
|
-
<p>The results were interpreted to yield an aggregate score of __total__, where 0 would be <q>perfect</q>.</p>
|
|
35
|
-
<h2>Total score</h2>
|
|
36
|
-
<p>The total score is the sum of five components.</p>
|
|
37
|
-
<table class="allBorder secondCellRight">
|
|
38
|
-
<caption>Score summary</caption>
|
|
39
|
-
<thead>
|
|
40
|
-
<tr><th>Component</th><th>Score</th><th>Description</th></tr>
|
|
41
|
-
</thead>
|
|
42
|
-
<tbody class="headersLeft">
|
|
43
|
-
<tr><th>total</th><td>__total__</td><td>Sum of the component scores</td></tr>
|
|
44
|
-
<tr><th>issue</th><td>__issue__</td><td>Severity and number of reported defects</td></tr>
|
|
45
|
-
<tr><th>tool</th><td>__tool__</td><td>Tool-by-tool defect ratings</td></tr>
|
|
46
|
-
<tr><th>prevention</th><td>__prevention__</td><td>Failed attempts by tools to test the page</td></tr>
|
|
47
|
-
<tr><th>log</th><td>__log__</td><td>Browser warnings about the page</td></tr>
|
|
48
|
-
<tr><th>latency</th><td>__latency__</td><td>Abnormal delay in page responses</td></tr>
|
|
49
|
-
</tbody>
|
|
50
|
-
</table>
|
|
51
|
-
<h2>Issue scores</h2>
|
|
52
|
-
<p>The score of an issue depends on the <dfn>severity</dfn> (user impact and certainty) of the issue and on how many instances were reported (by one or more tools).</p>
|
|
53
|
-
<table class="allBorder secondCellRight">
|
|
54
|
-
<caption>Issue scores</caption>
|
|
55
|
-
<thead>
|
|
56
|
-
<tr><th>Issue</th><th>Score</th></tr>
|
|
57
|
-
</thead>
|
|
58
|
-
<tbody class="headersLeft">
|
|
59
|
-
__issueRows__
|
|
60
|
-
</tbody>
|
|
61
|
-
</table>
|
|
62
|
-
<h2>Itemized issues</h2>
|
|
63
|
-
<p>The reported rule violations are itemized below, issue by issue. Additional details can be inspected in the complete report at the end of this page.</p>
|
|
64
|
-
__issueDetailRows__
|
|
65
|
-
<h2>Complete report</h2>
|
|
66
|
-
<pre>__report__</pre>
|
|
67
|
-
<footer>
|
|
68
|
-
<p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
|
|
69
|
-
</footer>
|
|
70
|
-
</main>
|
|
71
|
-
</body>
|
|
72
|
-
</html>
|