testilo 13.1.1 → 13.2.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/call.js +5 -5
- package/digest.js +4 -4
- package/package.json +1 -1
- package/procs/digest/tdp27/index.html +9 -5
- package/procs/digest/tdp27/index.js +16 -17
- package/procs/score/tsp27.js +32 -19
package/call.js
CHANGED
|
@@ -117,7 +117,8 @@ const callScore = async (scorerID, selector = '') => {
|
|
|
117
117
|
// Save it.
|
|
118
118
|
await fs.writeFile(`${scoredReportDir}/${report.id}.json`, JSON.stringify(report, null, 2));
|
|
119
119
|
};
|
|
120
|
-
|
|
120
|
+
console.log(`Reports scored and saved in ${scoredReportDir}`);
|
|
121
|
+
}
|
|
121
122
|
// Otherwise, i.e. if no raw reports are to be scored:
|
|
122
123
|
else {
|
|
123
124
|
// Report this.
|
|
@@ -132,17 +133,16 @@ const callDigest = async (digesterID, selector = '') => {
|
|
|
132
133
|
if (reports.length) {
|
|
133
134
|
const digesterDir = `${functionDir}/digest/${digesterID}`;
|
|
134
135
|
// Get the digester.
|
|
135
|
-
const digester = require(`${digesterDir}/index`)
|
|
136
|
-
// Get the template.
|
|
137
|
-
const template = await fs.readFile(`${digesterDir}/index.html`, 'utf8');
|
|
136
|
+
const {digester} = require(`${digesterDir}/index`);
|
|
138
137
|
// Digest the reports.
|
|
139
|
-
const digestedReports = digest(
|
|
138
|
+
const digestedReports = await digest(digester, reports);
|
|
140
139
|
const digestedReportDir = `${reportDir}/digested`;
|
|
141
140
|
// For each digested report:
|
|
142
141
|
for (const reportID of Object.keys(digestedReports)) {
|
|
143
142
|
// Save it.
|
|
144
143
|
await fs.writeFile(`${digestedReportDir}/${reportID}.html`, digestedReports[reportID]);
|
|
145
144
|
};
|
|
145
|
+
console.log(`Reports digested and saved in ${digestedReportDir}`);
|
|
146
146
|
}
|
|
147
147
|
// Otherwise, i.e. if no scored reports are to be digested:
|
|
148
148
|
else {
|
package/digest.js
CHANGED
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
// ########## FUNCTIONS
|
|
10
10
|
|
|
11
11
|
// Digests the scored reports and returns them, digested.
|
|
12
|
-
exports.digest = (digester, reports) => {
|
|
12
|
+
exports.digest = async (digester, reports) => {
|
|
13
13
|
const digests = {};
|
|
14
14
|
// For each report:
|
|
15
|
-
|
|
15
|
+
for (const report of reports) {
|
|
16
16
|
// Use it to create a digest.
|
|
17
|
-
const digestedReport = digester(report);
|
|
17
|
+
const digestedReport = await digester(report);
|
|
18
18
|
// Add the digest to the array of digests.
|
|
19
19
|
digests[report.id] = digestedReport;
|
|
20
20
|
console.log(`Report ${report.id} digested`);
|
|
21
|
-
}
|
|
21
|
+
};
|
|
22
22
|
// Return the digests.
|
|
23
23
|
console.log(`Digesting complete. Report count: ${reports.length}`);
|
|
24
24
|
return digests;
|
package/package.json
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<tr><th>URL</th><td>__url__</td></tr>
|
|
23
23
|
<tr><th>Requester</th><td>__requester__</td></tr>
|
|
24
24
|
<tr><th>Test date</th><td>__dateSlash__</td></tr>
|
|
25
|
-
<tr><th>Score</th><td>
|
|
25
|
+
<tr><th>Score</th><td>__total__</td></tr>
|
|
26
26
|
<tr><th>Tested by</th><td>Testaro, procedure <code>__ts__</code></td></tr>
|
|
27
27
|
<tr><th>Scored by</th><td>Testilo, procedure <code>__sp__</code></td></tr>
|
|
28
28
|
<tr><th>Digested by</th><td>Testilo, procedure <code>__dp__</code></td></tr>
|
|
@@ -31,18 +31,22 @@
|
|
|
31
31
|
<h2>Introduction</h2>
|
|
32
32
|
<p>This is a digest of results from a battery of accessibility tests.</p>
|
|
33
33
|
<p>The battery includes about 1350 tests drawn from ten different packages: Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, QualWeb, Tenon, Testaro, and WAVE.</p>
|
|
34
|
-
<p>These tests were run on the web page named above and gave the page a score of
|
|
35
|
-
<h2>
|
|
34
|
+
<p>These tests were run on the web page named above and gave the page a score of __total__, where 0 would be <q>perfect</q>.</p>
|
|
35
|
+
<h2>Scores</h2>
|
|
36
36
|
<table class="allBorder secondCellRight">
|
|
37
37
|
<caption>Score summary</caption>
|
|
38
38
|
<thead>
|
|
39
39
|
<tr><th>Component</th><th>Score</th></tr>
|
|
40
40
|
</thead>
|
|
41
41
|
<tbody class="headersLeft">
|
|
42
|
-
|
|
42
|
+
<tr><th>total</th><td>__total__</td></tr>
|
|
43
|
+
<tr><th>issue</th><td>__issue__</td></tr>
|
|
44
|
+
<tr><th>tool</th><td>__tool__</td></tr>
|
|
45
|
+
<tr><th>prevention</th><td>__prevention__</td></tr>
|
|
46
|
+
<tr><th>log</th><td>__log__</td></tr>
|
|
47
|
+
<tr><th>latency</th><td>__latency__</td></tr>
|
|
43
48
|
</tbody>
|
|
44
49
|
</table>
|
|
45
|
-
<h2>Issue scores</h2>
|
|
46
50
|
<table class="allBorder secondCellRight">
|
|
47
51
|
<caption>Issue scores</caption>
|
|
48
52
|
<thead>
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
// IMPORTS
|
|
4
4
|
|
|
5
|
+
// Issue classification
|
|
5
6
|
const {issueClasses} = require('../../score/tic27');
|
|
7
|
+
// Function to process files.
|
|
8
|
+
const fs = require('fs/promises');
|
|
6
9
|
|
|
7
10
|
// CONSTANTS
|
|
8
11
|
|
|
@@ -23,10 +26,10 @@ const htmlEscape = textOrNumber => textOrNumber
|
|
|
23
26
|
// Gets a row of the score-summary table.
|
|
24
27
|
const getScoreRow = (componentName, score) => `<tr><th>${componentName}</th><td>${score}</td></tr>`;
|
|
25
28
|
// Adds parameters to a query for a digest.
|
|
26
|
-
const
|
|
29
|
+
const populateQuery = (report, query) => {
|
|
27
30
|
const {sources, jobData, score} = report;
|
|
28
31
|
const {script, target, requester} = sources;
|
|
29
|
-
const {scoreProcID, summary,
|
|
32
|
+
const {scoreProcID, summary, details} = score;
|
|
30
33
|
const {total} = summary;
|
|
31
34
|
query.ts = script;
|
|
32
35
|
query.sp = scoreProcID;
|
|
@@ -37,15 +40,10 @@ const makeQuery = (report, query) => {
|
|
|
37
40
|
query.org = target.what;
|
|
38
41
|
query.url = target.which;
|
|
39
42
|
query.requester = requester;
|
|
40
|
-
// Add the
|
|
41
|
-
|
|
42
|
-
query
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
console.log('ERROR: missing or invalid total score');
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
// Get rows for a score-summary table.
|
|
43
|
+
// Add values for the score-summary table to the query.
|
|
44
|
+
['total', 'issue', 'tool', 'prevention', 'log', 'latency'].forEach(sumItem => {
|
|
45
|
+
query[sumItem] = summary[sumItem];
|
|
46
|
+
});
|
|
49
47
|
const rows = {
|
|
50
48
|
summaryRows: [],
|
|
51
49
|
issueRows: []
|
|
@@ -57,8 +55,8 @@ const makeQuery = (report, query) => {
|
|
|
57
55
|
}
|
|
58
56
|
});
|
|
59
57
|
// Get rows for an issue-score table.
|
|
60
|
-
Object.keys(
|
|
61
|
-
rows.issueRows.push(getScoreRow(issueID,
|
|
58
|
+
Object.keys(details.issue).forEach(issueID => {
|
|
59
|
+
rows.issueRows.push(getScoreRow(issueID, details.issue[issueID].score));
|
|
62
60
|
});
|
|
63
61
|
// Add the rows to the query.
|
|
64
62
|
['summaryRows', 'issueRows'].forEach(rowType => {
|
|
@@ -66,13 +64,13 @@ const makeQuery = (report, query) => {
|
|
|
66
64
|
});
|
|
67
65
|
// Add paragraphs about the issues to the query.
|
|
68
66
|
const issueSummaryItems = [];
|
|
69
|
-
Object.keys(
|
|
67
|
+
Object.keys(details.issue).forEach(issueID => {
|
|
70
68
|
const issueHeading = `<h4>Issue ${issueID}</h4>`;
|
|
71
69
|
const wcagP = `<p>WCAG: ${issueClasses[issueID].wcag || 'N/A'}</p>`;
|
|
72
|
-
const scoreP = `<p>Score: ${
|
|
70
|
+
const scoreP = `<p>Score: ${details.issue[issueID]}</p>`;
|
|
73
71
|
const issueIntroP = '<p>Issue reports in this category:</p>';
|
|
74
72
|
const issueListItems = [];
|
|
75
|
-
const issueData =
|
|
73
|
+
const issueData = details.issue[issueID];
|
|
76
74
|
const toolIDs = Object.keys(issueData.tools);
|
|
77
75
|
toolIDs.forEach(toolID => {
|
|
78
76
|
const testIDs = Object.keys(issueData.tools[toolID]);
|
|
@@ -100,7 +98,8 @@ const makeQuery = (report, query) => {
|
|
|
100
98
|
// Returns a digested report.
|
|
101
99
|
exports.digester = async report => {
|
|
102
100
|
// Create a query to replace plateholders.
|
|
103
|
-
const query =
|
|
101
|
+
const query = {};
|
|
102
|
+
populateQuery(report, query);
|
|
104
103
|
// Get the template.
|
|
105
104
|
let template = await fs.readFile(`${__dirname}/index.html`, 'utf8');
|
|
106
105
|
// Replace its placeholders.
|
package/procs/score/tsp27.js
CHANGED
|
@@ -81,9 +81,14 @@ exports.scorer = report => {
|
|
|
81
81
|
const {summary, details} = score;
|
|
82
82
|
// For each test act:
|
|
83
83
|
testActs.forEach(act => {
|
|
84
|
-
// If
|
|
84
|
+
// If the page prevented the tool from operating:
|
|
85
85
|
const {which, standardResult} = act;
|
|
86
|
-
if (
|
|
86
|
+
if (standardResult.prevented) {
|
|
87
|
+
// Add this to the score.
|
|
88
|
+
details.prevention[which] = preventionWeight;
|
|
89
|
+
}
|
|
90
|
+
// Otherwise, if a successful standard result exists:
|
|
91
|
+
else if (
|
|
87
92
|
standardResult
|
|
88
93
|
&& standardResult.totals
|
|
89
94
|
&& standardResult.totals.length === 4
|
|
@@ -105,6 +110,8 @@ exports.scorer = report => {
|
|
|
105
110
|
const issueID = issueIndex[which][ruleID];
|
|
106
111
|
if (! details.issue[issueID]) {
|
|
107
112
|
details.issue[issueID] = {
|
|
113
|
+
score: 0,
|
|
114
|
+
maxCount: 0,
|
|
108
115
|
weight: issueClasses[issueID].weight,
|
|
109
116
|
tools: {}
|
|
110
117
|
};
|
|
@@ -144,17 +151,29 @@ exports.scorer = report => {
|
|
|
144
151
|
}
|
|
145
152
|
// Otherwise, i.e. if no successful standard result exists:
|
|
146
153
|
else {
|
|
147
|
-
// Add
|
|
148
|
-
if (! act.result) {
|
|
149
|
-
act.result = {};
|
|
150
|
-
}
|
|
151
|
-
if (! act.result.prevented) {
|
|
152
|
-
act.result.prevented = true;
|
|
153
|
-
};
|
|
154
|
-
// Add the tool and the prevention score to the score.
|
|
154
|
+
// Add an inferred prevention to the score.
|
|
155
155
|
details.prevention[which] = preventionWeight;
|
|
156
156
|
}
|
|
157
157
|
});
|
|
158
|
+
// For each issue with any complaints:
|
|
159
|
+
Object.keys(details.issue).forEach(issueID => {
|
|
160
|
+
const issueData = details.issue[issueID];
|
|
161
|
+
// For each tool with any complaints for the issue:
|
|
162
|
+
Object.keys(issueData.tools).forEach(toolID => {
|
|
163
|
+
// Get the sum of the weighted counts of its issue rules.
|
|
164
|
+
let weightedCount = 0;
|
|
165
|
+
Object.values(issueData.tools[toolID]).forEach(ruleData => {
|
|
166
|
+
weightedCount += ruleData.quality * ruleData.complaints.countTotal;
|
|
167
|
+
});
|
|
168
|
+
// If the sum exceeds the existing maximum weighted count for the issue:
|
|
169
|
+
if (weightedCount > issueData.maxCount) {
|
|
170
|
+
// Change the maximum count for the issue to the sum.
|
|
171
|
+
issueData.maxCount = weightedCount;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
// Get the score for the issue.
|
|
175
|
+
issueData.score = issueData.weight * issueData.maxCount;
|
|
176
|
+
});
|
|
158
177
|
// Add the severity detail totals to the score.
|
|
159
178
|
details.severity.total = Object.keys(details.severity.byTool).reduce((severityTotals, toolID) => {
|
|
160
179
|
details.severity.byTool[toolID].forEach((severityScore, index) => {
|
|
@@ -163,15 +182,9 @@ exports.scorer = report => {
|
|
|
163
182
|
return severityTotals;
|
|
164
183
|
}, details.severity.total);
|
|
165
184
|
// Add the summary issue total to the score.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
summary.issue += details.issue[issueID].weight
|
|
170
|
-
* details.issue[issueID].tools[toolID][ruleID].quality
|
|
171
|
-
* details.issue[issueID].tools[toolID][ruleID].complaints.countTotal;
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
});
|
|
185
|
+
summary.issue = Object
|
|
186
|
+
.values(details.issue)
|
|
187
|
+
.reduce((total, current) => total + current.score, 0);
|
|
175
188
|
// Add the summary tool total to the score.
|
|
176
189
|
summary.tool = toolWeight * details.severity.total.reduce(
|
|
177
190
|
(total, current, index) => total + severityWeights[index] * current, 0
|