testilo 10.3.1 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +188 -190
  2. package/batch.js +60 -0
  3. package/call.js +9 -4
  4. package/compare.js +2 -2
  5. package/merge.js +0 -6
  6. package/package.json +1 -1
  7. package/procs/compare/cp20sqrt/index.js +7 -10
  8. package/procs/compare/{cp15b → tcp24}/index.html +5 -5
  9. package/procs/compare/{cp12a → tcp24}/index.js +13 -20
  10. package/procs/score/{tic24.js → tic26.js} +205 -199
  11. package/procs/score/tsp24.js +8 -2
  12. package/procs/score/tsp26.js +120 -0
  13. package/score.js +2 -8
  14. package/procs/compare/cp0/index.html +0 -46
  15. package/procs/compare/cp0/index.js +0 -70
  16. package/procs/compare/cp1/index.html +0 -46
  17. package/procs/compare/cp1/index.js +0 -71
  18. package/procs/compare/cp12a/index.html +0 -47
  19. package/procs/compare/cp12b/index.html +0 -47
  20. package/procs/compare/cp12b/index.js +0 -71
  21. package/procs/compare/cp14a/index.html +0 -47
  22. package/procs/compare/cp14a/index.js +0 -71
  23. package/procs/compare/cp15a/index.html +0 -47
  24. package/procs/compare/cp15a/index.js +0 -71
  25. package/procs/compare/cp15b/index.js +0 -74
  26. package/procs/compare/cp16a/index.html +0 -47
  27. package/procs/compare/cp16a/index.js +0 -74
  28. package/procs/compare/cp16b/index.html +0 -47
  29. package/procs/compare/cp16b/index.js +0 -74
  30. package/procs/digest/dp10a/index.html +0 -137
  31. package/procs/digest/dp10a/index.js +0 -402
  32. package/procs/digest/dp10b/index.html +0 -74
  33. package/procs/digest/dp10b/index.js +0 -130
  34. package/procs/digest/dp10c/index.html +0 -55
  35. package/procs/digest/dp10c/index.js +0 -129
  36. package/procs/digest/dp11a/index.html +0 -76
  37. package/procs/digest/dp11a/index.js +0 -127
  38. package/procs/digest/dp12a/index.html +0 -78
  39. package/procs/digest/dp12a/index.js +0 -126
  40. package/procs/digest/dp12b/index.html +0 -78
  41. package/procs/digest/dp12b/index.js +0 -126
  42. package/procs/digest/dp13a/index.html +0 -78
  43. package/procs/digest/dp13a/index.js +0 -126
  44. package/procs/digest/dp14a/index.html +0 -79
  45. package/procs/digest/dp14a/index.js +0 -126
  46. package/procs/digest/dp15a/index.html +0 -80
  47. package/procs/digest/dp15a/index.js +0 -126
  48. package/procs/digest/dp16a/index.html +0 -80
  49. package/procs/digest/dp16a/index.js +0 -126
  50. package/procs/digest/dp16b/index.html +0 -80
  51. package/procs/digest/dp16b/index.js +0 -126
  52. package/procs/digest/dp18a/index.html +0 -80
  53. package/procs/digest/dp18a/index.js +0 -129
  54. package/procs/digest/dp20c/index.html +0 -54
  55. package/procs/digest/dp20c/index.js +0 -117
  56. package/procs/digest/dp20d/index.html +0 -54
  57. package/procs/digest/dp20d/index.js +0 -121
  58. package/procs/digest/tdp09a/index.html +0 -126
  59. package/procs/digest/tdp09a/index.js +0 -381
  60. package/procs/digest/tdp22/index.html +0 -54
  61. package/procs/digest/tdp22/index.js +0 -120
  62. package/procs/score/tic21.js +0 -6868
  63. package/procs/score/tic22.js +0 -6911
  64. package/procs/score/tic23.js +0 -6924
  65. package/procs/score/tsp21.js +0 -720
  66. package/procs/score/tsp22.js +0 -720
  67. package/procs/score/tsp23.js +0 -720
  68. package/specs/batches/orgs.json +0 -43
  69. package/specs/scripts/ts21.json +0 -213
  70. package/specs/scripts/ts23.json +0 -219
  71. package/specs/scripts/ts24.json +0 -225
@@ -1,130 +0,0 @@
1
- /*
2
- index: digester for scoring procedure sp10b.
3
- Creator of parameters for substitution into index.html.
4
- Usage example: node digest 35k1r-railpass dp10b
5
- Arguments:
6
- 0. report. Scored report.
7
- 1. query. Object to which this module will add properties.
8
- */
9
-
10
- // CONSTANTS
11
-
12
- // Newlines with indentations.
13
- const joiner = '\n ';
14
- const innerJoiner = '\n ';
15
- const specialMessages = {
16
- log: 'This is based on the amount of browser logging during the tests. Browsers usually log messages only when pages contain erroneous code.',
17
- preventions: 'This is based on tests that the page did not allow to be run. That impedes accessibility progress and risks interfering with tools that users with disabilities need.',
18
- solos: 'This is based on issues reported by unclassified tests. Details are in the report.'
19
- };
20
-
21
- // FUNCTIONS
22
-
23
- // Makes strings HTML-safe.
24
- const htmlEscape = textOrNumber => textOrNumber
25
- .toString()
26
- .replace(/&/g, '&')
27
- .replace(/</g, '&lt;');
28
- // Gets a row of the score-summary table.
29
- const getScoreRow = (component, score) => `<tr><th>${component}</th><td>${score}</td></tr>`;
30
- // Gets the start of a paragraph about a special score.
31
- const getSpecialPStart = (summary, scoreID) =>
32
- `<p><span class="componentID">${scoreID}</span>: Score ${summary[scoreID]}.`;
33
- // Adds parameters to a query for a digest.
34
- exports.makeQuery = (report, query) => {
35
- // Add an HTML-safe copy of the host report to the query to be appended to the digest.
36
- const {script, host, score} = report;
37
- const reportJSON = JSON.stringify(report, null, 2);
38
- const reportJSONSafe = htmlEscape(reportJSON);
39
- query.report = reportJSONSafe;
40
- // Add the job data to the query.
41
- query.dateISO = report.endTime.slice(0, 10);
42
- query.dateSlash = query.dateISO.replace(/-/g, '/');
43
- if (host && host.what && host.which) {
44
- query.org = host.what;
45
- query.url = host.which;
46
- }
47
- else {
48
- const firstURLCommand = script.commands.find(command => command.type === 'url');
49
- if (firstURLCommand && firstURLCommand.what && firstURLCommand.which) {
50
- query.org = firstURLCommand.what;
51
- query.url = firstURLCommand.which;
52
- }
53
- else {
54
- console.log('ERROR: host missing or invalid');
55
- return;
56
- }
57
- }
58
- const {groupDetails, summary} = score;
59
- if (typeof summary.total === 'number') {
60
- query.totalScore = summary.total;
61
- }
62
- else {
63
- console.log('ERROR: missing or invalid total score');
64
- return;
65
- }
66
- // Add the total and any special rows of the score-summary table to the query.
67
- const scoreRows = [];
68
- const specialComponentIDs = ['log', 'preventions', 'solos'];
69
- ['total'].concat(specialComponentIDs).forEach(item => {
70
- if (summary[item]) {
71
- scoreRows.push(getScoreRow(item, summary[item]));
72
- }
73
- });
74
- // Add the group rows of the score-summary table to the query.
75
- const {groups} = summary;
76
- const groupIDs = Object.keys(groups);
77
- groupIDs.sort((a, b) => groups[b] - groups[a]);
78
- groupIDs.forEach(groupID => {
79
- scoreRows.push(getScoreRow(`${groupID}`, groups[groupID]));
80
- });
81
- query.scoreRows = scoreRows.join(innerJoiner);
82
- // If the score has any special components:
83
- const scoredSpecialIDs = specialComponentIDs.filter(item => summary[item]);
84
- if (scoredSpecialIDs.length) {
85
- // Add paragraphs about them for the issue summary to the query.
86
- const specialPs = [];
87
- scoredSpecialIDs.forEach(id => {
88
- specialPs.push(`${getSpecialPStart(summary, id)} ${specialMessages[id]}`);
89
- });
90
- query.specialSummary = specialPs.join(joiner);
91
- }
92
- // Otherwise, i.e. if the score has no special components:
93
- else {
94
- // Add a paragraph stating this for the issue summary to the query.
95
- query.specialSummary = '<p>No special issues contributed to the score.</p>'
96
- }
97
- // If the score has any classified issues as components:
98
- if (groupIDs.length) {
99
- // Add paragraphs about them for the special summary to the query.
100
- const groupSummaryItems = [];
101
- groupIDs.forEach(id => {
102
- const groupP = `<p><span class="componentID">${id}</span>: Score ${summary.groups[id]}. Issues reported by tests in this category:</p>`;
103
- const groupListItems = [];
104
- const groupData = groupDetails.groups[id];
105
- const packageIDs = Object.keys(groupData);
106
- packageIDs.forEach(packageID => {
107
- const testIDs = Object.keys(groupData[packageID]);
108
- testIDs.forEach(testID => {
109
- const testData = groupData[packageID][testID];
110
- const {issueCount} = testData;
111
- const issueNoun = issueCount !== 1 ? 'issues' : 'issue';
112
- const listItem = `<li>${issueCount} ${issueNoun} reported by package <code>${packageID}</code>, test <code>${testID}</code> (${testData.what})</li>`;
113
- groupListItems.push(listItem);
114
- });
115
- });
116
- const groupList = [
117
- '<ul>',
118
- groupListItems.join('\n '),
119
- '</ul>'
120
- ].join(joiner);
121
- groupSummaryItems.push(groupP, groupList);
122
- });
123
- query.groupSummary = groupSummaryItems.join(joiner);
124
- }
125
- // Otherwise, i.e. if the score has no classified issues as components:
126
- else {
127
- // Add a paragraph stating this for the group summary to the query.
128
- query.groupSummary = '<p>No classified issues contributed to the score.</p>'
129
- }
130
- };
@@ -1,55 +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 test 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 test digest</h1>
19
- <h2>Synopsis</h2>
20
- <div id="synopsis">
21
- <p>Page: __org__</p>
22
- <p>URL: __url__</p>
23
- <p>Score: __totalScore__</p>
24
- <p>Tested by: Testaro, script <code>__scriptID__</code></p>
25
- <p>Scored by: Testilo, procedure <code>sp10c</code></p>
26
- <p>Digested by: Testilo, procedure <code>dp10c</code></p>
27
- </div>
28
- </header>
29
- <h2>Introduction</h2>
30
- <p>The <code>__scriptID__</code> <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/">accessibility</a> testing script was executed by <a href="https://www.npmjs.com/package/testaro">Testaro</a> on the __org__ web page arrived at in a transaction that began at <a href="__url__">__url__</a>, on __dateSlash__. The procedure performed custom tests defined by Testaro and tests belonging to packages created by others. Testaro produced a report enumerating the test results.</p>
31
- <p><a href="https://www.npmjs.com/package/testilo">Testilo</a> used its <code>sp10c</code> scoring procedure to compute partial and total scores for the page. The total score is __totalScore__ (where 0 is the best possible score). The scored report is appended below.</p>
32
- <p>Finally, Testilo used procedure <code>dp10c</code> to produce this digest, explaining how <code>sp10c</code> computed the scores.</p>
33
- <p>Disclaimer: Even though there are widely accepted accessibility standards, there is still no unanimity about how to define, test for, and quantify accessibility. The failures reported below merit investigation as <strong>potential</strong> opportunities for improved accessibility. But you may conclude that some of the failures do not actually harm accessibility, and some substantial accessibility faults can escape detection by any of these tests. Likewise, you may not agree with weightings and formulas of scoring procedure <code>sp10b</code>, or even question whether it is appropriate to assign accessibility scores to a web page. This digest describes only one interpretation of the page&rsquo;s accessibility.</p>
34
- <h2>Score summary</h2>
35
- <p>The total score and its components were:</p>
36
- <table class="allBorder secondCellRight">
37
- <caption>Score components</caption>
38
- <tbody class="headersLeft">
39
- __scoreRows__
40
- </tbody>
41
- </table>
42
- <h2>Issue summary</h2>
43
- <h3>Special issues</h3>
44
- __specialSummary__
45
- <h3>Classified issues</h3>
46
- <p>The classified issues reported by tests are summarized below.</p>
47
- __groupSummary__
48
- <h2>Report</h2>
49
- <pre>__report__</pre>
50
- <footer>
51
- <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
52
- </footer>
53
- </main>
54
- </body>
55
- </html>
@@ -1,129 +0,0 @@
1
- /*
2
- index: digester for scoring procedure sp10b.
3
- Creator of parameters for substitution into index.html.
4
- Usage example: node digest 35k1r-railpass dp10b
5
- Arguments:
6
- 0. report. Scored report.
7
- 1. query. Object to which this module will add properties.
8
- */
9
-
10
- // CONSTANTS
11
-
12
- // Newlines with indentations.
13
- const joiner = '\n ';
14
- const innerJoiner = '\n ';
15
- const specialMessages = {
16
- log: 'This is based on the amount of browser logging during the tests. Browsers usually log messages only when pages contain erroneous code.',
17
- preventions: 'This is based on tests that the page did not allow to be run. That impedes accessibility progress and risks interfering with tools that users with disabilities need.',
18
- solos: 'This is based on issues reported by unclassified tests. Details are in the report.'
19
- };
20
-
21
- // FUNCTIONS
22
-
23
- // Makes strings HTML-safe.
24
- const htmlEscape = textOrNumber => textOrNumber
25
- .toString()
26
- .replace(/&/g, '&amp;')
27
- .replace(/</g, '&lt;');
28
- // Gets a row of the score-summary table.
29
- const getScoreRow = (component, score) => `<tr><th>${component}</th><td>${score}</td></tr>`;
30
- // Gets the start of a paragraph about a special score.
31
- const getSpecialPStart
32
- = (summary, scoreID) => `<p><span class="componentID">log</span>: Score ${summary[scoreID]}.`;
33
- // Adds parameters to a query for a digest.
34
- exports.makeQuery = (report, query) => {
35
- // Add an HTML-safe copy of the host report to the query to be appended to the digest.
36
- const {script, host, score} = report;
37
- const reportJSON = JSON.stringify(report, null, 2);
38
- const reportJSONSafe = htmlEscape(reportJSON);
39
- query.report = reportJSONSafe;
40
- // Add the job data to the query.
41
- query.dateISO = report.endTime.slice(0, 10);
42
- query.dateSlash = query.dateISO.replace(/-/g, '/');
43
- query.scriptID = script.id;
44
- if (host && host.what && host.which) {
45
- query.org = host.what;
46
- query.url = host.which;
47
- }
48
- else {
49
- const firstURLCommand = script.commands.find(command => command.type === 'url');
50
- if (firstURLCommand && firstURLCommand.what && firstURLCommand.which) {
51
- query.org = script.what;
52
- query.url = firstURLCommand.which;
53
- }
54
- else {
55
- console.log('ERROR: host missing or invalid');
56
- return;
57
- }
58
- }
59
- const {groupDetails, summary} = score;
60
- if (typeof summary.total === 'number') {
61
- query.totalScore = summary.total;
62
- }
63
- else {
64
- console.log('ERROR: missing or invalid total score');
65
- return;
66
- }
67
- // Add the total and any special rows of the score-summary table to the query.
68
- const scoreRows = [];
69
- const specialComponentIDs = ['log', 'preventions', 'solos'];
70
- ['total'].concat(specialComponentIDs).forEach(item => {
71
- if (summary[item]) {
72
- scoreRows.push(getScoreRow(item, summary[item]));
73
- }
74
- });
75
- // Add the group rows of the score-summary table to the query.
76
- const {groups} = summary;
77
- const groupIDs = Object.keys(groups);
78
- groupIDs.sort((a, b) => groups[b] - groups[a]);
79
- groupIDs.forEach(groupID => {
80
- scoreRows.push(getScoreRow(`group ${groupID}`, groups[groupID]));
81
- });
82
- query.scoreRows = scoreRows.join(innerJoiner);
83
- // If the score has any special components:
84
- const scoredSpecialIDs = specialComponentIDs.filter(item => summary[item]);
85
- if (scoredSpecialIDs.length) {
86
- // Add paragraphs about them for the issue summary to the query.
87
- const specialPs = [];
88
- scoredSpecialIDs.forEach(id => {
89
- specialPs.push(`${getSpecialPStart(summary, id)} ${specialMessages[id]}`);
90
- });
91
- query.specialSummary = specialPs.join(joiner);
92
- }
93
- // Otherwise, i.e. if the score has no special components:
94
- else {
95
- // Add a paragraph stating this for the issue summary to the query.
96
- query.specialSummary = '<p>No special issues contributed to the score.</p>'
97
- }
98
- // If the score has any classified issues as components:
99
- if (groupIDs.length) {
100
- // Add paragraphs about them for the special summary to the query.
101
- const groupSummaryItems = [];
102
- groupIDs.forEach(id => {
103
- const groupP = `<p><span class="componentID">${id}</span>: Score ${summary.groups[id]}. Issues reported by tests in this category:</p>`;
104
- const groupListItems = [];
105
- const groupData = groupDetails.groups[id];
106
- const packageIDs = Object.keys(groupData);
107
- packageIDs.forEach(packageID => {
108
- const testIDs = Object.keys(groupData[packageID]);
109
- testIDs.forEach(testID => {
110
- const testData = groupData[packageID][testID];
111
- const listItem = `<li>${testData.issueCount} issues reported by package ${packageID}, test ${testID} (${testData.what})</li>`;
112
- groupListItems.push(listItem);
113
- });
114
- });
115
- const groupList = [
116
- '<ul>',
117
- groupListItems.join('\n '),
118
- '</ul>'
119
- ].join(joiner);
120
- groupSummaryItems.push(groupP, groupList);
121
- });
122
- query.groupSummary = groupSummaryItems.join(joiner);
123
- }
124
- // Otherwise, i.e. if the score has no classified issues as components:
125
- else {
126
- // Add a paragraph stating this for the group summary to the query.
127
- query.groupSummary = '<p>No classified issues contributed to the score.</p>'
128
- }
129
- };
@@ -1,76 +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 test 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 test digest</h1>
19
- <h2>Synopsis</h2>
20
- <div id="synopsis">
21
- <p>Page: __org__</p>
22
- <p>URL: __url__</p>
23
- <p>Score: __totalScore__</p>
24
- <p>Tested by: Testaro, procedure <code>tp11</code></p>
25
- <p>Scored by: Testilo, procedure <code>sp11a</code></p>
26
- <p>Digested by: Testilo, procedure <code>dp11a</code></p>
27
- </div>
28
- </header>
29
- <h2>Introduction</h2>
30
- <p>The <a href="https://www.npmjs.com/package/testaro">Testaro</a> application used its <code>tp11</code> testing procedure to test the <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/"><dfn>accessibility</dfn></a> (barrier-free design and coding) of the __org__ web page at <a href="__url__">__url__</a> on __dateSlash__. The procedure performed 808 tests. Of these, 16 are custom tests defined by Testaro, and the others belong to these six other packages (programs that perform collections of tests):</p>
31
- <ul>
32
- <li><a href="https://www.npmjs.com/package/aatt">AATT</a> by PayPal running <a href="https://marketplace.squiz.net/extensions/html-codesniffer">HTMLCodeSniffer</a> by Squiz</li>
33
- <li><a href="https://github.com/Siteimprove/alfa">Alfa</a> by Siteimprove</li>
34
- <li><a href="https://www.npmjs.com/package/axe-core">Axe-core</a> by Deque</li>
35
- <li><a href="https://github.com/IBMa/equal-access">Equal Access</a> by IBM</li>
36
- <li><a href="https://tenon.io/documentation/apiv2.php">Tenon</a> by Level Access</li>
37
- <li><a href="https://wave.webaim.org/api/">WAVE</a> by WebAIM</li>
38
- </ul>
39
- <p>Testaro produced a report enumerating the test results.</p>
40
- <p><a href="https://www.npmjs.com/package/testilo">Testilo</a> processed the report and used the <code>sp11a</code> scoring procedure to compute partial and total scores for the page. The total score is __totalScore__ (where 0 is the best possible score). The scored report is appended below.</p>
41
- <p>Finally, Testilo used procedure <code>dp11a</code> to produce this digest, briefly explaining how <code>sp11a</code> computed the scores.</p>
42
- <h2>Score summary</h2>
43
- <table class="allBorder secondCellRight">
44
- <caption>Score components</caption>
45
- <tbody class="headersLeft">
46
- __scoreRows__
47
- </tbody>
48
- </table>
49
- <h2>Issue summary</h2>
50
- <h3>Special issues</h3>
51
- __specialSummary__
52
- <h3>Classified issues</h3>
53
- __groupSummary__
54
- <h2>Discussion</h2>
55
- <p>Although there are widely accepted <a href="https://www.w3.org/WAI/standards-guidelines/">accessibility standards</a>, there is no unanimity about how to define, test, and quantify accessibility. The failures reported in this digest merit investigation as potential opportunities for improved accessibility. Investigation may lead you to conclude that some of the reported failures do not actually harm accessibility. Conversely, some substantial accessibility faults can escape detection by any of these tests. You may question the attempt to assign an accessibility score to a web page, or you may prefer weightings and formulas different from those used by <code>sp11a</code>. You can modify and extend Testaro and Testilo to fit other theories and priorities.</p>
56
- <p>Here, in brief, is how <code>sp11a</code> computes a score for a page.</p>
57
- <ul>
58
- <li>It finds all the defects and warnings (let&rsquo;s call them <q>issues</q>) recorded in the report.</li>
59
- <li>It classifies them according to type. For example, a link that looks like the text around it is one type of issue, while a video that has no captions is another type of issue.</li>
60
- <li>It also classifies the issues according to severity. For example, an issue that prevents a transaction is more severe than an issue that only complicates the transaction, and a warning about a possible issue is less severe than a definite finding of an issue. (Some packages rate the severity of each issue; for the other packages, <code>sp11a</code> assigns a severity weight to the issue type and uses that weight.)</li>
61
- <li>It assigns quality ratings to particular tests that are judged abnormally reliable or unreliable.</li>
62
- <li>It assigns a score to each issue reported by each test of each package.</li>
63
- <li>It aggregates the issue scores, weighting them by severity, test quality, and redundancy. Redundancy occurs, and causes downweighting, when two or more packages contain tests that are designed to discover the same or mostly the same issues.</li>
64
- <li>It assigns a score for the defects in the page logged by the browser.</li>
65
- <li>It assigns an estimated score each time the page prevents one of the packages from being run on the page.</li>
66
- <li>It adds the scores together to obtain a total score.</li>
67
- </ul>
68
- <p>The precise rules of <code>sp11a</code> are found in the <a href="https://github.com/jrpool/testilo/blob/main/procs/score/sp1'a.js">code itself</a>.</p>
69
- <h2>Report</h2>
70
- <pre>__report__</pre>
71
- <footer>
72
- <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
73
- </footer>
74
- </main>
75
- </body>
76
- </html>
@@ -1,127 +0,0 @@
1
- /*
2
- index: digester for scoring procedure sp11a.
3
- Creator of parameters for substitution into index.html.
4
- Usage example: node digest 35k1r-railpass dp11a
5
- */
6
-
7
- // CONSTANTS
8
-
9
- // Newlines with indentations.
10
- const joiner = '\n ';
11
- const innerJoiner = '\n ';
12
- const specialMessages = {
13
- log: 'This is based on the amount of browser logging during the tests. Browsers usually log messages only when pages contain erroneous code.',
14
- preventions: 'This is based on tests that the page did not allow to be run. That impedes accessibility progress and risks interfering with tools that users with disabilities need.',
15
- solos: 'This is based on issues reported by unclassified tests. Details are in the report.'
16
- };
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 = (component, score) => `<tr><th>${component}</th><td>${score}</td></tr>`;
27
- // Gets the start of a paragraph about a special score.
28
- const getSpecialPStart = (summary, scoreID) =>
29
- `<p><span class="componentID">${scoreID}</span>: Score ${summary[scoreID]}.`;
30
- // Adds parameters to a query for a digest.
31
- exports.makeQuery = (report, query) => {
32
- // Add an HTML-safe copy of the host report to the query to be appended to the digest.
33
- const { script, host, score } = report;
34
- const reportJSON = JSON.stringify(report, null, 2);
35
- const reportJSONSafe = htmlEscape(reportJSON);
36
- query.report = reportJSONSafe;
37
- // Add the job data to the query.
38
- query.dateISO = report.endTime.slice(0, 10);
39
- query.dateSlash = query.dateISO.replace(/-/g, '/');
40
- if (host && host.what && host.which) {
41
- query.org = host.what;
42
- query.url = host.which;
43
- }
44
- else {
45
- const firstURLCommand = script.commands.find(command => command.type === 'url');
46
- if (firstURLCommand && firstURLCommand.what && firstURLCommand.which) {
47
- query.org = firstURLCommand.what;
48
- query.url = firstURLCommand.which;
49
- }
50
- else {
51
- console.log('ERROR: host missing or invalid');
52
- return;
53
- }
54
- }
55
- const { groupDetails, summary } = score;
56
- if (typeof summary.total === 'number') {
57
- query.totalScore = summary.total;
58
- }
59
- else {
60
- console.log('ERROR: missing or invalid total score');
61
- return;
62
- }
63
- // Add the total and any special rows of the score-summary table to the query.
64
- const scoreRows = [];
65
- const specialComponentIDs = ['log', 'preventions', 'solos'];
66
- ['total'].concat(specialComponentIDs).forEach(item => {
67
- if (summary[item]) {
68
- scoreRows.push(getScoreRow(item, summary[item]));
69
- }
70
- });
71
- // Add the group rows of the score-summary table to the query.
72
- const { groups } = summary;
73
- const groupIDs = Object.keys(groups);
74
- groupIDs.sort((a, b) => groups[b] - groups[a]);
75
- groupIDs.forEach(groupID => {
76
- scoreRows.push(getScoreRow(`${groupID}`, groups[groupID]));
77
- });
78
- query.scoreRows = scoreRows.join(innerJoiner);
79
- // If the score has any special components:
80
- const scoredSpecialIDs = specialComponentIDs.filter(item => summary[item]);
81
- if (scoredSpecialIDs.length) {
82
- // Add paragraphs about them for the issue summary to the query.
83
- const specialPs = [];
84
- scoredSpecialIDs.forEach(id => {
85
- specialPs.push(`${getSpecialPStart(summary, id)} ${specialMessages[id]}`);
86
- });
87
- query.specialSummary = specialPs.join(joiner);
88
- }
89
- // Otherwise, i.e. if the score has no special components:
90
- else {
91
- // Add a paragraph stating this for the issue summary to the query.
92
- query.specialSummary = '<p>No special issues contributed to the score.</p>';
93
- }
94
- // If the score has any classified issues as components:
95
- if (groupIDs.length) {
96
- // Add paragraphs about them for the special summary to the query.
97
- const groupSummaryItems = [];
98
- groupIDs.forEach(id => {
99
- const groupP = `<p><span class="componentID">${id}</span>: Score ${summary.groups[id]}. Issues reported by tests in this category:</p>`;
100
- const groupListItems = [];
101
- const groupData = groupDetails.groups[id];
102
- const packageIDs = Object.keys(groupData);
103
- packageIDs.forEach(packageID => {
104
- const testIDs = Object.keys(groupData[packageID]);
105
- testIDs.forEach(testID => {
106
- const testData = groupData[packageID][testID];
107
- const { issueCount } = testData;
108
- const issueNoun = issueCount !== 1 ? 'issues' : 'issue';
109
- const listItem = `<li>${issueCount} ${issueNoun} reported by package <code>${packageID}</code>, test <code>${testID}</code> (${testData.what})</li>`;
110
- groupListItems.push(listItem);
111
- });
112
- });
113
- const groupList = [
114
- '<ul>',
115
- groupListItems.join('\n '),
116
- '</ul>'
117
- ].join(joiner);
118
- groupSummaryItems.push(groupP, groupList);
119
- });
120
- query.groupSummary = groupSummaryItems.join(joiner);
121
- }
122
- // Otherwise, i.e. if the score has no classified issues as components:
123
- else {
124
- // Add a paragraph stating this for the group summary to the query.
125
- query.groupSummary = '<p>No classified issues contributed to the score.</p>';
126
- }
127
- };
@@ -1,78 +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 test 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 test digest</h1>
19
- <h2>Synopsis</h2>
20
- <div id="synopsis">
21
- <p><strong>Page</strong>: __org__</p>
22
- <p><strong>URL</strong>: __url__</p>
23
- <p><strong>Score</strong>: __totalScore__</p>
24
- <p><strong>Tested by</strong>: Testaro, procedure <code>tp12</code></p>
25
- <p><strong>Scored by</strong>: Testilo, procedure <code>sp12a</code></p>
26
- <p><strong>Digested by</strong>: Testilo, procedure <code>dp12a</code></p>
27
- </div>
28
- </header>
29
- <h2>Introduction</h2>
30
- <p>The <a href="https://www.npmjs.com/package/testaro">Testaro</a> application used its <code>tp12</code> testing procedure to test the <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/"><dfn>accessibility</dfn></a> (barrier-free design and coding) of the __org__ web page at <a href="__url__">__url__</a> on __dateSlash__. The procedure performed 808 tests. Of these, 16 are custom tests defined by Testaro, and the others belong to these six other packages (programs that perform collections of tests):</p>
31
- <ul>
32
- <li><a href="https://github.com/Siteimprove/alfa">Alfa</a> by Siteimprove</li>
33
- <li><a href="https://www.npmjs.com/package/axe-core">Axe-core</a> by Deque</li>
34
- <li>
35
- <a href="https://www.npmjs.com/package/html_codesniffer">HTML CodeSniffer</a> by Squiz Labs
36
- </li>
37
- <li><a href="https://github.com/IBMa/equal-access">Equal Access</a> by IBM</li>
38
- <li><a href="https://tenon.io/documentation/apiv2.php">Tenon</a> by Level Access</li>
39
- <li><a href="https://wave.webaim.org/api/">WAVE</a> by WebAIM</li>
40
- </ul>
41
- <p>Testaro produced a report enumerating the test results.</p>
42
- <p><a href="https://www.npmjs.com/package/testilo">Testilo</a> processed the report and used the <code>sp12a</code> scoring procedure to compute partial and total scores for the page. The total score is __totalScore__ (where 0 is the best possible score). The scored report is appended below.</p>
43
- <p>Finally, Testilo used procedure <code>dp12a</code> to produce this digest, briefly explaining how <code>sp12a</code> computed the scores.</p>
44
- <h2>Score summary</h2>
45
- <table class="allBorder secondCellRight">
46
- <caption>Score components</caption>
47
- <tbody class="headersLeft">
48
- __scoreRows__
49
- </tbody>
50
- </table>
51
- <h2>Issue summary</h2>
52
- <h3>Special issues</h3>
53
- __specialSummary__
54
- <h3>Classified issues</h3>
55
- __groupSummary__
56
- <h2>Discussion</h2>
57
- <p>Although there are widely accepted <a href="https://www.w3.org/WAI/standards-guidelines/">accessibility standards</a>, there is no unanimity about how to define, test, and quantify accessibility. The failures reported in this digest merit investigation as potential opportunities for improved accessibility. Investigation may lead you to conclude that some of the reported failures do not actually harm accessibility. Conversely, some substantial accessibility faults can escape detection by any of these tests. You may question the attempt to assign an accessibility score to a web page, or you may prefer weightings and formulas different from those used by <code>sp12a</code>. You can modify and extend Testaro and Testilo to fit other theories and priorities.</p>
58
- <p>Here, in brief, is how <code>sp12a</code> computes a score for a page.</p>
59
- <ul>
60
- <li>It finds all the defects and warnings (let&rsquo;s call them <q>issues</q>) recorded in the report.</li>
61
- <li>It classifies them according to type. For example, a link that looks like the text around it is one issue category, while a video that has no captions is another issue category.</li>
62
- <li>It also classifies the issues according to severity. For example, an issue that prevents a transaction is more severe than an issue that only complicates the transaction, and a warning about a possible issue is less severe than a definite finding of an issue. (Some packages rate the severity of each issue; for the other packages, <code>sp12a</code> assigns a severity weight to the issue type and uses that weight.)</li>
63
- <li>It assigns quality ratings to particular tests that are judged abnormally reliable or unreliable.</li>
64
- <li>It assigns a score to each issue reported by each test of each package.</li>
65
- <li>It aggregates the issue scores, weighting them by severity, test quality, and redundancy. Redundancy occurs, and causes downweighting, when two or more packages contain tests that are designed to discover the same or mostly the same issues. So the score for a category is not simply the sum of the scores of the tests in that category.</li>
66
- <li>It assigns a score for issues in the page logged by the browser.</li>
67
- <li>It assigns an estimated score each time the page prevents one of the packages or one of the Testaro tests from being run on the page.</li>
68
- <li>It adds the scores together to obtain a total score.</li>
69
- </ul>
70
- <p>The precise rules of <code>sp12a</code> are found in the <a href="https://github.com/jrpool/testilo/blob/main/procs/score/sp12a.js">code itself</a>.</p>
71
- <h2>Report</h2>
72
- <pre>__report__</pre>
73
- <footer>
74
- <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
75
- </footer>
76
- </main>
77
- </body>
78
- </html>