testilo 3.2.0 → 3.4.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/README.md +33 -3
- package/compare.js +8 -8
- package/package.json +1 -1
- package/procs/compare/cp0/index.html +10 -5
- package/procs/compare/cp0/index.js +2 -4
- package/procs/compare/cp1/index.html +46 -0
- package/procs/compare/cp1/index.js +71 -0
- package/procs/digest/dp10a/index.html +3 -3
- package/procs/digest/dp10b/index.html +74 -0
- package/procs/digest/dp10b/index.js +130 -0
- package/procs/digest/dp10c/index.html +55 -0
- package/procs/digest/dp10c/index.js +129 -0
- package/procs/score/sp10b.js +507 -0
- package/procs/score/sp10c.js +465 -0
- package/reports/comparative/railsites.html +47 -0
- package/reports/comparative/style.css +4 -0
- package/reports/digested/35k1r-railpass.html +1130 -844
- package/reports/digested/3aee6-eurail.html +36233 -0
- package/reports/digested/dp10a/35k1r-railpass.html +9302 -0
- package/reports/digested/dp10a/3aee6-eurail.html +35782 -0
- package/reports/digested/style.css +2 -2
- package/reports/raw/3aee6-eurail.json +35250 -0
- package/reports/scored/35k1r-railpass.json +559 -175
- package/reports/scored/3aee6-eurail.json +35957 -0
- package/score.js +1 -1
- package/scoring/data/duplications.json +22 -22
- package/scoring/data/groups.json +335 -0
- package/scoring/data/packageRules/alfa.tsv +82 -0
- package/scoring/data/packageRules/axe.js +390 -0
- package/scoring/data/packageRules/ibm.tsv +159 -0
- package/scoring/data/packageRules/tenon.tsv +14 -0
- package/scoring/data/packageRules/wave.json +1617 -0
- package/scoring/data/packageRules/wave.tsv +55 -0
- package/scoring/data/testGroups.json +1067 -0
- package/scoring/{data → procs}/correlation.js +0 -0
- package/scoring/{data → procs}/dupCounts.js +0 -0
- package/scoring/procs/groups.js +61 -0
- package/scoring/{data → procs}/packageData.js +0 -0
- package/scoring/{data → procs}/packageIssues.js +0 -0
- package/scoring/procs/regroup.js +39 -0
- package/reports/comparative/35k1r-.html +0 -41
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/*
|
|
2
|
+
sp10c
|
|
3
|
+
Testilo score proc 10c
|
|
4
|
+
Computes scores from a Testaro script that removes API tests from tp10, and adds the scores
|
|
5
|
+
to a report.
|
|
6
|
+
Usage example: node score 35k1r sp10c
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ########## IMPORTS
|
|
10
|
+
|
|
11
|
+
// Module to read and write files.
|
|
12
|
+
const fs = require('fs/promises');
|
|
13
|
+
|
|
14
|
+
// CONSTANTS
|
|
15
|
+
|
|
16
|
+
const scoreProcID = 'sp10b';
|
|
17
|
+
// Define the configuration disclosures.
|
|
18
|
+
const logWeights = {
|
|
19
|
+
count: 0.5,
|
|
20
|
+
size: 0.01,
|
|
21
|
+
prohibited: 15,
|
|
22
|
+
visitTimeout: 10,
|
|
23
|
+
visitRejection: 10
|
|
24
|
+
};
|
|
25
|
+
const groupWeights = {
|
|
26
|
+
accessKeyDup: 3,
|
|
27
|
+
activeEmbedding: 2,
|
|
28
|
+
allCaps: 1,
|
|
29
|
+
ariaRefBad: 4,
|
|
30
|
+
autocompleteBad: 2,
|
|
31
|
+
buttonNoText: 4,
|
|
32
|
+
childMissing: 3,
|
|
33
|
+
contrastAA: 3,
|
|
34
|
+
contrastAAA: 1,
|
|
35
|
+
dupID: 2,
|
|
36
|
+
eventKbd: 3,
|
|
37
|
+
fieldSetMissing: 2,
|
|
38
|
+
focusableOperable: 3,
|
|
39
|
+
focusIndication: 3,
|
|
40
|
+
h1Missing: 1,
|
|
41
|
+
headingEmpty: 2,
|
|
42
|
+
headingStruc: 2,
|
|
43
|
+
hoverSurprise: 1,
|
|
44
|
+
htmlLang: 3,
|
|
45
|
+
htmlLangBad: 3,
|
|
46
|
+
iframeNoText: 3,
|
|
47
|
+
imgAltRedundant: 1,
|
|
48
|
+
imgInputNoText: 4,
|
|
49
|
+
imgMapAreaNoText: 3,
|
|
50
|
+
imgNoText: 4,
|
|
51
|
+
inconsistentStyles: 1,
|
|
52
|
+
contrastRisk: 1,
|
|
53
|
+
labelClash: 2,
|
|
54
|
+
labelForBadID: 4,
|
|
55
|
+
langChange: 2,
|
|
56
|
+
leadingClipsText: 3,
|
|
57
|
+
leadingFrozen: 3,
|
|
58
|
+
linkForcesNewWindow: 2,
|
|
59
|
+
linkNoText: 4,
|
|
60
|
+
linkPair: 1,
|
|
61
|
+
linkTextsIdentical: 2,
|
|
62
|
+
linkTitleRedundant: 1,
|
|
63
|
+
linkUnderlines: 2,
|
|
64
|
+
menuNavigation: 2,
|
|
65
|
+
metaBansZoom: 3,
|
|
66
|
+
nameValue: 3,
|
|
67
|
+
noLeading: 2,
|
|
68
|
+
objNoText: 2,
|
|
69
|
+
parentMissing: 3,
|
|
70
|
+
pseudoHeadingRisk: 1,
|
|
71
|
+
pseudoLinkRisk: 2,
|
|
72
|
+
pseudoListRisk: 1,
|
|
73
|
+
roleBad: 3,
|
|
74
|
+
roleBadAttr: 3,
|
|
75
|
+
roleMissingAttr: 3,
|
|
76
|
+
selectFlatRisk: 1,
|
|
77
|
+
selectNoText: 3,
|
|
78
|
+
spontaneousMotion: 2,
|
|
79
|
+
svgImgNoText: 4,
|
|
80
|
+
tabFocusability: 3,
|
|
81
|
+
tabNavigation: 2,
|
|
82
|
+
targetSize: 2,
|
|
83
|
+
textBeyondLandmarks: 1,
|
|
84
|
+
title: 3,
|
|
85
|
+
visibleBulk: 1,
|
|
86
|
+
zIndexNotZero: 1
|
|
87
|
+
};
|
|
88
|
+
const soloWeight = 1;
|
|
89
|
+
const countWeights = {
|
|
90
|
+
absolute: 2,
|
|
91
|
+
largest: 1,
|
|
92
|
+
smaller: 0.4
|
|
93
|
+
};
|
|
94
|
+
const preventionWeights = {
|
|
95
|
+
testaro: 50,
|
|
96
|
+
other: 100
|
|
97
|
+
};
|
|
98
|
+
const packageDetails = {};
|
|
99
|
+
const groupDetails = {
|
|
100
|
+
groups: {},
|
|
101
|
+
solos: {}
|
|
102
|
+
};
|
|
103
|
+
const summary = {
|
|
104
|
+
total: 0,
|
|
105
|
+
log: 0,
|
|
106
|
+
preventions: 0,
|
|
107
|
+
solos: 0,
|
|
108
|
+
groups: {}
|
|
109
|
+
};
|
|
110
|
+
const otherPackages = ['aatt', 'alfa', 'axe', 'ibm'];
|
|
111
|
+
const preventionScores = {};
|
|
112
|
+
|
|
113
|
+
// FUNCTIONS
|
|
114
|
+
|
|
115
|
+
// Adds to the count of issues of a kind discovered by a test package.
|
|
116
|
+
const addDetail = (actWhich, testID, addition = 1) => {
|
|
117
|
+
if (! packageDetails[actWhich]) {
|
|
118
|
+
packageDetails[actWhich] = {};
|
|
119
|
+
}
|
|
120
|
+
if (! packageDetails[actWhich][testID]) {
|
|
121
|
+
packageDetails[actWhich][testID] = 0;
|
|
122
|
+
}
|
|
123
|
+
packageDetails[actWhich][testID] += addition;
|
|
124
|
+
};
|
|
125
|
+
// Adds scores to a report.
|
|
126
|
+
exports.scorer = async report => {
|
|
127
|
+
// If there are any acts:
|
|
128
|
+
const {acts} = report;
|
|
129
|
+
if (Array.isArray(acts)) {
|
|
130
|
+
// If any of them are test acts:
|
|
131
|
+
const testActs = acts.filter(act => act.type === 'test');
|
|
132
|
+
if (testActs.length) {
|
|
133
|
+
// For each test act:
|
|
134
|
+
testActs.forEach(test => {
|
|
135
|
+
const {which} = test;
|
|
136
|
+
// Get the issue tally.
|
|
137
|
+
if (which === 'aatt') {
|
|
138
|
+
const issues = test.result;
|
|
139
|
+
if (issues && Array.isArray(issues)) {
|
|
140
|
+
issues.forEach(issue => {
|
|
141
|
+
const {type, id} = issue;
|
|
142
|
+
if (type && id) {
|
|
143
|
+
const typedID = `${type[0]}:${id}`;
|
|
144
|
+
addDetail(which, typedID);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (which === 'alfa') {
|
|
150
|
+
const issues = test.result;
|
|
151
|
+
if (issues && Array.isArray(issues)) {
|
|
152
|
+
issues.forEach(issue => {
|
|
153
|
+
const {rule} = issue;
|
|
154
|
+
if (rule) {
|
|
155
|
+
const {ruleID} = rule;
|
|
156
|
+
if (ruleID) {
|
|
157
|
+
addDetail(which, ruleID);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (which === 'axe') {
|
|
164
|
+
const tests = test.result && test.result.items;
|
|
165
|
+
if (tests && Array.isArray(tests)) {
|
|
166
|
+
tests.forEach(test => {
|
|
167
|
+
const {rule, elements} = test;
|
|
168
|
+
if (rule && Array.isArray(elements) && elements.length) {
|
|
169
|
+
addDetail(which, rule, elements.length);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (which === 'ibm') {
|
|
175
|
+
const result = test.result && test.result.content;
|
|
176
|
+
const {items} = result;
|
|
177
|
+
if (items && Array.isArray(items) && items.length) {
|
|
178
|
+
items.forEach(issue => {
|
|
179
|
+
const {ruleID} = issue;
|
|
180
|
+
if (ruleID) {
|
|
181
|
+
addDetail(which, ruleID);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (which === 'bulk') {
|
|
187
|
+
const count = test.result && test.result.visibleElements;
|
|
188
|
+
if (typeof count === 'number') {
|
|
189
|
+
const faultCount = Math.floor(count / 300);
|
|
190
|
+
addDetail('testaro', which, faultCount);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else if (which === 'embAc') {
|
|
194
|
+
const issueCounts = test.result && test.result.totals;
|
|
195
|
+
if (issueCounts) {
|
|
196
|
+
const counts = Object.values(issueCounts);
|
|
197
|
+
const total = counts.reduce((sum, current) => sum + current);
|
|
198
|
+
addDetail('testaro', which, total);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else if (which === 'focAll') {
|
|
202
|
+
const discrepancy = test.result && test.result.discrepancy;
|
|
203
|
+
if (discrepancy) {
|
|
204
|
+
addDetail('testaro', which, Math.abs(discrepancy));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (which === 'focInd') {
|
|
208
|
+
const issueTypes = test.result && test.result.totals && test.result.totals.types;
|
|
209
|
+
if (issueTypes) {
|
|
210
|
+
const missingCount = issueTypes.indicatorMissing && issueTypes.indicatorMissing.total;
|
|
211
|
+
const badCount = issueTypes.nonOutlinePresent && issueTypes.nonOutlinePresent.total;
|
|
212
|
+
const faultCount = Math.round(missingCount + badCount / 2);
|
|
213
|
+
if (faultCount) {
|
|
214
|
+
addDetail('testaro', which, faultCount);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else if (which === 'focOp') {
|
|
219
|
+
const issueTypes = test.result && test.result.totals && test.result.totals.types;
|
|
220
|
+
if (issueTypes) {
|
|
221
|
+
const noOpCount = issueTypes.onlyFocusable && issueTypes.onlyFocusable.total;
|
|
222
|
+
const noFocCount = issueTypes.onlyOperable && issueTypes.onlyOperable.total;
|
|
223
|
+
const faultCount = Math.round(noFocCount + noOpCount / 2);
|
|
224
|
+
if (faultCount) {
|
|
225
|
+
addDetail('testaro', which, faultCount);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else if (which === 'hover') {
|
|
230
|
+
const issues = test.result && test.result.totals;
|
|
231
|
+
if (issues) {
|
|
232
|
+
const {triggers, madeVisible, opacityChanged, opacityAffected, unhoverables} = issues;
|
|
233
|
+
const faultCount = Math.round(
|
|
234
|
+
1 * triggers
|
|
235
|
+
+ 0.5 * madeVisible
|
|
236
|
+
+ 0.2 * opacityChanged
|
|
237
|
+
+ 0.2 * opacityAffected
|
|
238
|
+
+ 1 * unhoverables
|
|
239
|
+
);
|
|
240
|
+
if (faultCount) {
|
|
241
|
+
addDetail('testaro', which, faultCount);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else if (which === 'labClash') {
|
|
246
|
+
const mislabeledCount = test.result
|
|
247
|
+
&& test.result.totals
|
|
248
|
+
&& test.result.totals.mislabeled;
|
|
249
|
+
if (mislabeledCount) {
|
|
250
|
+
addDetail('testaro', which, mislabeledCount);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else if (which === 'linkUl') {
|
|
254
|
+
const issues = test.result && test.result.items && test.result.items.notUnderlined;
|
|
255
|
+
if (issues && issues.length) {
|
|
256
|
+
addDetail('testaro', which, issues.length);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else if (which === 'menuNav') {
|
|
260
|
+
const issueCount = test.result
|
|
261
|
+
&& test.result.totals
|
|
262
|
+
&& test.result.totals.navigations
|
|
263
|
+
&& test.result.totals.navigations.all
|
|
264
|
+
&& test.result.totals.navigations.all.incorrect;
|
|
265
|
+
if (issueCount && typeof issueCount === 'number') {
|
|
266
|
+
addDetail('testaro', which, issueCount);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else if (which === 'motion') {
|
|
270
|
+
const data = test.result;
|
|
271
|
+
if (data && data.bytes) {
|
|
272
|
+
const faultCount = Math.floor(
|
|
273
|
+
5 * (data.meanLocalRatio - 1)
|
|
274
|
+
+ 2 * (data.maxLocalRatio - 1)
|
|
275
|
+
+ data.globalRatio - 1
|
|
276
|
+
+ data.meanPixelChange / 10000
|
|
277
|
+
+ data.maxPixelChange / 25000
|
|
278
|
+
+ 30 * data.changeFrequency
|
|
279
|
+
);
|
|
280
|
+
addDetail('testaro', which, faultCount);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else if (which === 'radioSet') {
|
|
284
|
+
const counts = test.result && test.result.totals;
|
|
285
|
+
const {total, inSet} = counts;
|
|
286
|
+
if (total && typeof inSet === 'number' && total >= inSet) {
|
|
287
|
+
addDetail('testaro', which, total - inSet);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else if (which === 'role') {
|
|
291
|
+
const issueCount = test.result && test.result.badRoleElements;
|
|
292
|
+
if (issueCount && typeof issueCount === 'number') {
|
|
293
|
+
addDetail('testaro', which, issueCount);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (which === 'styleDiff') {
|
|
297
|
+
const counts = test.result && test.result.totals;
|
|
298
|
+
if (counts) {
|
|
299
|
+
// Identify objects having the tag-name totals and style distributions as properties.
|
|
300
|
+
const tagNameCounts = Object.values(counts);
|
|
301
|
+
// Identify an array of pairs of counts of excess styles and of nonplurality elements.
|
|
302
|
+
const faults = tagNameCounts.map(
|
|
303
|
+
item => {
|
|
304
|
+
const subtotals = item.subtotals ? item.subtotals : [item.total];
|
|
305
|
+
return [subtotals.length - 1, item.total - subtotals[0]];
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
// Fault count: 2 per excess style + 0.2 per nonplurality element.
|
|
309
|
+
const faultCount = Math.floor(faults.reduce(
|
|
310
|
+
(total, currentPair) => total + 2 * currentPair[0] + 0.2 * currentPair[1], 0
|
|
311
|
+
));
|
|
312
|
+
addDetail('testaro', which, faultCount);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
else if (which === 'tabNav') {
|
|
316
|
+
const issueCount = test.result
|
|
317
|
+
&& test.result.totals
|
|
318
|
+
&& test.result.totals.navigations
|
|
319
|
+
&& test.result.totals.navigations.all
|
|
320
|
+
&& test.result.totals.navigations.all.incorrect;
|
|
321
|
+
if (issueCount && typeof issueCount === 'number') {
|
|
322
|
+
addDetail('testaro', which, issueCount);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
else if (which === 'zIndex') {
|
|
326
|
+
const issueCount = test.result && test.result.totals;
|
|
327
|
+
if (issueCount && typeof issueCount === 'number') {
|
|
328
|
+
addDetail('testaro', which, issueCount);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
// Get the prevention scores and add them to the summary.
|
|
333
|
+
const actsPrevented = testActs.filter(test => test.result.prevented);
|
|
334
|
+
actsPrevented.forEach(act => {
|
|
335
|
+
if (otherPackages.includes(act.which)) {
|
|
336
|
+
preventionScores[act.which] = preventionWeights.other;
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
preventionScores[`testaro-${act.which}`] = preventionWeights.testaro;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
const preventionScore = Object
|
|
343
|
+
.values(preventionScores)
|
|
344
|
+
.reduce((sum, current) => sum + current, 0);
|
|
345
|
+
summary.preventions = preventionScore;
|
|
346
|
+
summary.total += preventionScore;
|
|
347
|
+
// Get data on test groups.
|
|
348
|
+
const testGroupsJSON = await fs.readFile('scoring/data/testGroups.json', 'utf8');
|
|
349
|
+
const testGroups = JSON.parse(testGroupsJSON);
|
|
350
|
+
// Use the data to populate groupDetails.groups.
|
|
351
|
+
const {tests} = testGroups;
|
|
352
|
+
const groupPackageIDs = Object.keys(tests);
|
|
353
|
+
groupPackageIDs.forEach(packageID => {
|
|
354
|
+
const packageTestIDs = Object.keys(tests[packageID]);
|
|
355
|
+
packageTestIDs.forEach(testID => {
|
|
356
|
+
const testData = tests[packageID][testID];
|
|
357
|
+
const {groupID, what} = testData;
|
|
358
|
+
if (! groupDetails.groups[groupID]) {
|
|
359
|
+
groupDetails.groups[groupID] = {};
|
|
360
|
+
}
|
|
361
|
+
if (! groupDetails.groups[groupID][packageID]) {
|
|
362
|
+
groupDetails.groups[groupID][packageID] = {};
|
|
363
|
+
}
|
|
364
|
+
groupDetails.groups[testData.groupID][packageID][testID] = {
|
|
365
|
+
what,
|
|
366
|
+
issueCount: 0
|
|
367
|
+
};
|
|
368
|
+
});
|
|
369
|
+
})
|
|
370
|
+
// Get the IDs of the packages whose tests report any issues.
|
|
371
|
+
const issuePackageIDs = Object.keys(packageDetails);
|
|
372
|
+
// For each such package:
|
|
373
|
+
issuePackageIDs.forEach(packageID => {
|
|
374
|
+
// Get the IDs of the tests in the package that report issues.
|
|
375
|
+
const issueTestIDs = Object.keys(packageDetails[packageID]);
|
|
376
|
+
// For each such test:
|
|
377
|
+
issueTestIDs.forEach(testID => {
|
|
378
|
+
// Get its group data, if any.
|
|
379
|
+
const testGroupData = tests[packageID][testID];
|
|
380
|
+
const issueCount = packageDetails[packageID][testID];
|
|
381
|
+
// If it is in a group:
|
|
382
|
+
if (testGroupData) {
|
|
383
|
+
// Add the issue count to the group details.
|
|
384
|
+
const {groupID} = testGroupData;
|
|
385
|
+
groupDetails.groups[groupID][packageID][testID].issueCount = issueCount;
|
|
386
|
+
}
|
|
387
|
+
// Otherwise, i.e. if the test is solo:
|
|
388
|
+
else {
|
|
389
|
+
// Add the issue count to the solo details.
|
|
390
|
+
if (! groupDetails.solos[packageID]) {
|
|
391
|
+
groupDetails.solos[packageID] = {};
|
|
392
|
+
}
|
|
393
|
+
groupDetails.solos[packageID][testID] = issueCount;
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
// Delete from the group details groups without any issues.
|
|
398
|
+
const groupIDs = Object.keys(groupDetails.groups);
|
|
399
|
+
groupIDs.forEach(groupID => {
|
|
400
|
+
const groupPackageData = Object.values(groupDetails.groups[groupID]);
|
|
401
|
+
if (
|
|
402
|
+
groupPackageData.every(datum => Object.values(datum).every(test => test.issueCount === 0))
|
|
403
|
+
) {
|
|
404
|
+
delete groupDetails.groups[groupID];
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
// Get the group scores and add them to the summary.
|
|
408
|
+
const issueGroupIDs = Object.keys(groupDetails.groups);
|
|
409
|
+
const {absolute, largest, smaller} = countWeights;
|
|
410
|
+
issueGroupIDs.forEach(groupID => {
|
|
411
|
+
const issueCounts = [];
|
|
412
|
+
const groupPackageData = Object.values(groupDetails.groups[groupID]);
|
|
413
|
+
groupPackageData.forEach(packageDatum => {
|
|
414
|
+
const issueCountSum = Object
|
|
415
|
+
.values(packageDatum)
|
|
416
|
+
.reduce((sum, current) => sum + current.issueCount, 0);
|
|
417
|
+
issueCounts.push(issueCountSum);
|
|
418
|
+
});
|
|
419
|
+
issueCounts.sort((a, b) => b - a);
|
|
420
|
+
const groupScore = groupWeights[groupID] * (
|
|
421
|
+
absolute + largest * issueCounts[0] + smaller * issueCounts.slice(1).reduce(
|
|
422
|
+
(sum, current) => sum + current, 0
|
|
423
|
+
)
|
|
424
|
+
);
|
|
425
|
+
const roundedScore = Math.round(groupScore);
|
|
426
|
+
summary.groups[groupID] = roundedScore;
|
|
427
|
+
summary.total += roundedScore;
|
|
428
|
+
});
|
|
429
|
+
// Get the solo scores and add them to the summary.
|
|
430
|
+
const issueSoloPackageIDs = Object.keys(groupDetails.solos);
|
|
431
|
+
issueSoloPackageIDs.forEach(packageID => {
|
|
432
|
+
const testIDs = Object.keys(groupDetails.solos[packageID]);
|
|
433
|
+
testIDs.forEach(testID => {
|
|
434
|
+
const issueCount = groupDetails.solos[packageID][testID];
|
|
435
|
+
const issueScore = Math.round(soloWeight * issueCount);
|
|
436
|
+
summary.solos += issueScore;
|
|
437
|
+
summary.total += issueScore;
|
|
438
|
+
});
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
// Get the log score.
|
|
443
|
+
logScore = Math.floor(
|
|
444
|
+
logWeights.count * report.logCount
|
|
445
|
+
+ logWeights.size * report.logSize
|
|
446
|
+
+ logWeights.prohibited * report.prohibitedCount
|
|
447
|
+
+ logWeights.visitTimeout * report.visitTimeoutCount
|
|
448
|
+
+ logWeights.visitRejection * report.visitRejectionCount
|
|
449
|
+
);
|
|
450
|
+
summary.log = logScore;
|
|
451
|
+
summary.total += logScore;
|
|
452
|
+
// Add the score facts to the report.
|
|
453
|
+
report.score = {
|
|
454
|
+
scoreProcID,
|
|
455
|
+
logWeights,
|
|
456
|
+
groupWeights,
|
|
457
|
+
soloWeight,
|
|
458
|
+
countWeights,
|
|
459
|
+
preventionWeights,
|
|
460
|
+
packageDetails,
|
|
461
|
+
groupDetails,
|
|
462
|
+
preventionScores,
|
|
463
|
+
summary
|
|
464
|
+
};
|
|
465
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
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="comparison of accessibility scores from tsp10 procedure">
|
|
10
|
+
<meta name="keywords" content="accessibility a11y web testing">
|
|
11
|
+
<title>Accessibility score comparison</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 score comparison</h1>
|
|
19
|
+
</header>
|
|
20
|
+
<h2>Introduction</h2>
|
|
21
|
+
<p>The table below compares 2 web pages on <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/">accessibility</a>. The page names link to the pages on the web. The scores link to digests that explain in detail how the scores were computed.</p>
|
|
22
|
+
<p>The pages were:</p>
|
|
23
|
+
<div id="summary">
|
|
24
|
+
<p>Tested by <a href="https://www.npmjs.com/package/testaro">Testaro</a> with procedure <code>tp10</code></p>
|
|
25
|
+
<p>Scored by <a href="https://www.npmjs.com/package/testilo">Testilo</a> with procedure <code>sp10a</code></p>
|
|
26
|
+
<p>Digested by Testilo with procedure <code>dp10a</code></p>
|
|
27
|
+
<p>Compared by Testilo with procedure <code>cp0</code></p>
|
|
28
|
+
</div>
|
|
29
|
+
<p>The <code>tp10</code> procedure performs 808 tests on each page. Of these, 16 tests are custom tests defined by Testaro, and the others belong to packages of tests created by others.</p>
|
|
30
|
+
<p>Tests and scoring formulae are fallible and subjective. The reported faults merit investigation as potential opportunities for improved accessibility. But some may not actually harm accessibility, and some other accessibility faults may have escaped detection. Different reasonable procedures could yield different test results and different scores. Testaro and Testilo can be customized to fit different definitions and weightings of types of accessibility.</p>
|
|
31
|
+
<h2>Comparison</h2>
|
|
32
|
+
<table class="allBorder">
|
|
33
|
+
<caption>Accessibility scores of web pages</caption>
|
|
34
|
+
<thead>
|
|
35
|
+
<tr><th scope="col">Page</th><th scope="col" colspan="2">Score (lower is better)</tr>
|
|
36
|
+
</thead>
|
|
37
|
+
<tbody class="linkSmaller secondCellRight">
|
|
38
|
+
<tr><th scope="row"><a href="https://www.railpass.com/">Railpass</a></th><td><a href="digests/35k1r-railpass.html">1589</a></td><td aria-hidden="true"><svg width="100%" height="0.7em"><rect height="100%" width="23.159889228975366%" fill="red"></rect></svg></td></tr>
|
|
39
|
+
<tr><th scope="row"><a href="https://www.eurail.com/en">Eurail</a></th><td><a href="digests/3aee6-eurail.html">6861</a></td><td aria-hidden="true"><svg width="100%" height="0.7em"><rect height="100%" width="100%" fill="red"></rect></svg></td></tr>
|
|
40
|
+
</tbody>
|
|
41
|
+
</table>
|
|
42
|
+
<footer>
|
|
43
|
+
<p class="date">Produced <time itemprop="datePublished" datetime="2022-06-08">2022/06/08</time></p>
|
|
44
|
+
</footer>
|
|
45
|
+
</main>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|