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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testilo",
3
- "version": "20.0.3",
3
+ "version": "21.1.0",
4
4
  "description": "Prepares and processes Testaro reports",
5
5
  "main": "aim.js",
6
6
  "scripts": {
@@ -3,14 +3,14 @@
3
3
  // IMPORTS
4
4
 
5
5
  // Module to classify tool rules into issues
6
- const {issues} = require('../../score/tic37');
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 = 'tdp37';
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
- rows.issueRows.push(
57
- getIssueScoreRow(issues[issueID].summary, issues[issueID].wcag, score, Object.keys(tools))
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 => {
@@ -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: 3,
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: 'link element is not in the document head'
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: 'link element with an as attribute has no rel attribute with preload, modulepreload, or prefetch as its value'
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: 'link element with a body ancestor has no itemprop or valid rel attribute'
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: 'link element with an as attribute has no rel attribute with preload, modulepreload, or prefetch as its value'
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: 'link element with an as attribute has no rel attribute with preload or modulepreload as its value'
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: 'meta element is missing a required attribute'
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: 'meta element with name="description" is not the only one'
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: 'meta element with http-equiv="content-type" is incompatible with the meta element with a charset attribute'
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: 'meta element with http-equiv="X-UA-Compatible" has no content="IE=edge"'
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 exposed to risk of corruption',
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: 'li element is not contained by a ul or ol element'
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 invalid code',
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,
@@ -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, '&amp;')
24
- .replace(/</g, '&lt;');
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>