testilo 13.3.3 → 13.5.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 +16 -20
- package/call.js +16 -11
- package/compare.js +7 -13
- package/digest.js +1 -1
- package/package.json +1 -1
- package/procs/compare/tcp27/index.html +47 -0
- package/procs/compare/tcp27/index.js +83 -0
- package/scripts/ts27.json +79 -0
package/README.md
CHANGED
|
@@ -469,15 +469,13 @@ A module can invoke `digest` in this way:
|
|
|
469
469
|
|
|
470
470
|
```javaScript
|
|
471
471
|
const {digest} = require('testilo/digest');
|
|
472
|
-
const digesterDir = `${process.env.FUNCTIONDIR}/digest/
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
const digestedReports = digest(template, digester, scoredReports);
|
|
477
|
-
});
|
|
472
|
+
const digesterDir = `${process.env.FUNCTIONDIR}/digest/tdp99a`;
|
|
473
|
+
const {digester} = require(`${digesterDir}/index`);
|
|
474
|
+
digest(digester, scoredReports)
|
|
475
|
+
.then(digestedReports => {…});
|
|
478
476
|
```
|
|
479
477
|
|
|
480
|
-
The first
|
|
478
|
+
The first argument to `digest()` is a digesting function. In this example, it has been obtained from a files in the Testilo package, but it could be custom-made. The second argument to `digest()` is an array of scored report objects. The `digest()` function returns an array of digested reports. The invoking module can further dispose of the digested reports as needed.
|
|
481
479
|
|
|
482
480
|
#### By a user
|
|
483
481
|
|
|
@@ -505,12 +503,11 @@ To test the `digest` module, in the project directory you can execute the statem
|
|
|
505
503
|
|
|
506
504
|
If you use Testilo to perform a battery of tests on multiple targets, you may want a single report that compares the total scores received by the targets. Testilo can produce such a _comparative report_.
|
|
507
505
|
|
|
508
|
-
The `compare` module compares the scores in a collection of scored reports. Its `compare()` function takes
|
|
509
|
-
- a comparison template
|
|
506
|
+
The `compare` module compares the scores in a collection of scored reports. Its `compare()` function takes two arguments:
|
|
510
507
|
- a comparison function
|
|
511
508
|
- an array of scored reports
|
|
512
509
|
|
|
513
|
-
The comparison
|
|
510
|
+
The comparison function defines the rules for generating an HTML file comparing the scored reports. The Testilo package contains a `procs/compare` directory, in which there are subdirectories containing modules that export comparison functions. You can use one of those functions, or you can create your own.
|
|
514
511
|
|
|
515
512
|
### Invocation
|
|
516
513
|
|
|
@@ -521,31 +518,30 @@ There are two ways to use the `compare` module.
|
|
|
521
518
|
A module can invoke `compare` in this way:
|
|
522
519
|
|
|
523
520
|
```javaScript
|
|
524
|
-
const fs = require('fs/promises);
|
|
525
521
|
const {compare} = require('testilo/compare');
|
|
526
522
|
const comparerDir = `${process.env.FUNCTIONDIR}/compare/tcp99`;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
const comparativeReport = compare(template, comparer, scoredReports);
|
|
531
|
-
});
|
|
523
|
+
const {comparer} = require(`${comparerDir}/index`);
|
|
524
|
+
compare(comparer, scoredReports)
|
|
525
|
+
.then(comparison => {…});
|
|
532
526
|
```
|
|
533
527
|
|
|
534
|
-
The first
|
|
528
|
+
The first argument to `compare()` is a comparison function. In this example, it been obtained from a file in the Testilo package, but it could be custom-made. The second argument to `compare()` is an array of report objects. The `compare()` function returns a comparative report. The invoking module can further dispose of the comparative report as needed.
|
|
535
529
|
|
|
536
530
|
#### By a user
|
|
537
531
|
|
|
538
532
|
A user can invoke `compare` in this way:
|
|
539
533
|
|
|
540
534
|
```bash
|
|
541
|
-
node call compare tcp99 legislators
|
|
535
|
+
node call compare tcp99 legislators 23pl
|
|
542
536
|
```
|
|
543
537
|
|
|
544
538
|
When a user invokes `compare` in this example, the `call` module:
|
|
545
|
-
- gets the
|
|
546
|
-
- gets all the reports in the `scored` subdirectory of the `process.env.REPORTDIR` directory
|
|
539
|
+
- gets the comparison module from subdirectory `tcp99` of the subdirectory `compare` in the `process.env.FUNCTIONDIR` directory.
|
|
540
|
+
- gets all the reports in the `scored` subdirectory of the `process.env.REPORTDIR` directory whose file names begin with `23pl`.
|
|
547
541
|
- writes the comparative report as an HTML file named `legislators.html` to the `comparative` subdirectory of the `process.env.REPORTDIR` directory.
|
|
548
542
|
|
|
543
|
+
The fourth argument to `call` (`23pl` in this example) is optional. If it is omitted, `call` will get and `comparer` will compare all the reports in the `scored` directory.
|
|
544
|
+
|
|
549
545
|
The comparative report created by `compare` is an HTML file, and it expects a `style.css` file to exist in its directory. The `reports/comparative/style.css` file in Testilo is an appropriate stylesheet to be copied into the directory where comparative reports are written.
|
|
550
546
|
|
|
551
547
|
### Validation
|
package/call.js
CHANGED
|
@@ -131,8 +131,8 @@ const callDigest = async (digesterID, selector = '') => {
|
|
|
131
131
|
const reports = await getReports('scored', selector);
|
|
132
132
|
// If any exist:
|
|
133
133
|
if (reports.length) {
|
|
134
|
-
const digesterDir = `${functionDir}/digest/${digesterID}`;
|
|
135
134
|
// Get the digester.
|
|
135
|
+
const digesterDir = `${functionDir}/digest/${digesterID}`;
|
|
136
136
|
const {digester} = require(`${digesterDir}/index`);
|
|
137
137
|
// Digest the reports.
|
|
138
138
|
const digestedReports = await digest(digester, reports);
|
|
@@ -152,15 +152,20 @@ const callDigest = async (digesterID, selector = '') => {
|
|
|
152
152
|
};
|
|
153
153
|
// Fulfills a comparison request.
|
|
154
154
|
// Get the scored reports to be scored.
|
|
155
|
-
const callCompare = async (compareProcID, comparisonNameBase) => {
|
|
156
|
-
const reports = await getReports('scored');
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
155
|
+
const callCompare = async (compareProcID, comparisonNameBase, selector = '') => {
|
|
156
|
+
const reports = await getReports('scored', selector);
|
|
157
|
+
// If any exist:
|
|
158
|
+
if (reports.length) {
|
|
159
|
+
// Get the comparer.
|
|
160
|
+
const comparerDir = `${functionDir}/compare/${compareProcID}`;
|
|
161
|
+
const {comparer} = require(`${comparerDir}/index`);
|
|
162
|
+
// Compare the reports.
|
|
163
|
+
const comparison = await compare(comparer, reports);
|
|
164
|
+
// Save the comparison.
|
|
165
|
+
const comparisonDir = `${reportDir}/comparative`;
|
|
166
|
+
await fs.writeFile(`${comparisonDir}/${comparisonNameBase}.html`, comparison);
|
|
167
|
+
console.log(`Comparison completed and saved in ${comparisonDir}`);
|
|
168
|
+
}
|
|
164
169
|
};
|
|
165
170
|
|
|
166
171
|
// ########## OPERATION
|
|
@@ -214,7 +219,7 @@ else if (fn === 'multiDigest' && fnArgs.length === 1) {
|
|
|
214
219
|
console.log('Execution completed');
|
|
215
220
|
});
|
|
216
221
|
}
|
|
217
|
-
else if (fn === 'compare' && fnArgs.length
|
|
222
|
+
else if (fn === 'compare' && fnArgs.length > 1 && fnArgs.length < 4) {
|
|
218
223
|
callCompare(... fnArgs)
|
|
219
224
|
.then(() => {
|
|
220
225
|
console.log('Execution completed');
|
package/compare.js
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
/*
|
|
2
2
|
compare.js
|
|
3
|
-
Creates a
|
|
3
|
+
Creates a comparison from scored reports.
|
|
4
|
+
Arguments:
|
|
5
|
+
0. Comparing function.
|
|
6
|
+
1. Array of scored reports.
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
9
|
// ########## FUNCTIONS
|
|
7
10
|
|
|
8
|
-
// Replaces the placeholders in a template with eponymous query parameters.
|
|
9
|
-
const replaceHolders = (template, query) => template
|
|
10
|
-
.replace(/__([a-zA-Z]+)__/g, (ph, qp) => query[qp]);
|
|
11
11
|
// Compares the scored reports and returns a comparison.
|
|
12
|
-
exports.compare = async (
|
|
13
|
-
// Create a query.
|
|
14
|
-
const query = {};
|
|
15
|
-
// Populate the query.
|
|
16
|
-
await comparer(reports, query);
|
|
17
|
-
// Use it to create a comparison.
|
|
18
|
-
const comparison = replaceHolders(comparisonTemplate, query);
|
|
12
|
+
exports.compare = async (comparer, scoredReports) => {
|
|
19
13
|
// Return the comparison.
|
|
20
|
-
console.log(`Comparison complete. Report count: ${
|
|
21
|
-
return
|
|
14
|
+
console.log(`Comparison complete. Report count: ${scoredReports.length}`);
|
|
15
|
+
return comparer(scoredReports);
|
|
22
16
|
};
|
package/digest.js
CHANGED
package/package.json
CHANGED
|
@@ -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">
|
|
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 __pageCount__ web pages on <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/">accessibility</a>. The page names are links to the pages on the web. The scores are links to digests that explain in detail how the scores were computed.</p>
|
|
22
|
+
<p>The pages were:</p>
|
|
23
|
+
<ol id="summary">
|
|
24
|
+
<li>Tested by <a href="https://www.npmjs.com/package/testaro">Testaro</a> with procedure <code>__scriptID__</code></li>
|
|
25
|
+
<li>Scored by <a href="https://www.npmjs.com/package/testilo">Testilo</a> with procedure <code>__scorer__</code></li>
|
|
26
|
+
<li>Digested by Testilo with procedure <code>__digester__</code></li>
|
|
27
|
+
<li>Compared by Testilo with procedure <code>__comparer__</code></li>
|
|
28
|
+
</ol>
|
|
29
|
+
<p>Testaro used ten tools (Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, Tenon, Testaro, and WAVE) to perform about 1350 automated accessibility tests. Testilo used its scoring procedure to assign a score to each page, with 0 being perfect.</p>
|
|
30
|
+
<h2>Comparison</h2>
|
|
31
|
+
<table class="allBorder">
|
|
32
|
+
<caption>Accessibility scores of web pages</caption>
|
|
33
|
+
<thead>
|
|
34
|
+
<tr><th scope="col">Page</th><th scope="col" colspan="2">Score (from best to worst)</tr>
|
|
35
|
+
</thead>
|
|
36
|
+
<tbody class="linkSmaller secondCellRight">
|
|
37
|
+
__tableBody__
|
|
38
|
+
</tbody>
|
|
39
|
+
</table>
|
|
40
|
+
<h2>Disclaimer</h2>
|
|
41
|
+
<p>Other tests and scoring formulae would produce different results. The algorithms underlying these results can be inspected in the Testaro and Testilo packages and can be revised to fit different definitions and weightings of types of accessibility.</p>
|
|
42
|
+
<footer>
|
|
43
|
+
<p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
|
|
44
|
+
</footer>
|
|
45
|
+
</main>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// index: comparer for scoring procedure tsp27
|
|
2
|
+
|
|
3
|
+
// ########## IMPORTS
|
|
4
|
+
|
|
5
|
+
// Module to access files.
|
|
6
|
+
const fs = require('fs/promises');
|
|
7
|
+
|
|
8
|
+
// CONSTANTS
|
|
9
|
+
|
|
10
|
+
// Digester ID.
|
|
11
|
+
const id = 'tcp27';
|
|
12
|
+
// Newlines with indentations.
|
|
13
|
+
const joiner = '\n ';
|
|
14
|
+
const innerJoiner = '\n ';
|
|
15
|
+
const innestJoiner = '\n ';
|
|
16
|
+
|
|
17
|
+
// ########## FUNCTIONS
|
|
18
|
+
|
|
19
|
+
// Returns data on the targets.
|
|
20
|
+
const getData = async scoredReports => {
|
|
21
|
+
const bodyData = [];
|
|
22
|
+
for (const report of scoredReports) {
|
|
23
|
+
const {id, sources, score} = report;
|
|
24
|
+
bodyData.push({
|
|
25
|
+
id,
|
|
26
|
+
org: sources.target.what,
|
|
27
|
+
url: sources.target.which,
|
|
28
|
+
score: score.summary.total
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
pageCount: scoredReports.length,
|
|
33
|
+
script: scoredReports[0].sources.script,
|
|
34
|
+
bodyData
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
// Returns the maximum score.
|
|
38
|
+
const getMaxScore = tableData => tableData.reduce((max, item) => Math.max(max, item.score), 0);
|
|
39
|
+
// Converts report data to a table body.
|
|
40
|
+
const getTableBody = async bodyData => {
|
|
41
|
+
const maxScore = getMaxScore(bodyData);
|
|
42
|
+
const rows = bodyData
|
|
43
|
+
.sort((a, b) => a.score - b.score)
|
|
44
|
+
.map(item => {
|
|
45
|
+
const {id, org, url, score} = item;
|
|
46
|
+
const pageCell = `<th scope="row"><a href="${url}">${org}</a></th>`;
|
|
47
|
+
const numCell = `<td><a href="digests/${id}.html">${score}</a></td>`;
|
|
48
|
+
// Make the bar width proportional.
|
|
49
|
+
const barWidth = 100 * score / maxScore;
|
|
50
|
+
const bar = `<rect height="100%" width="${barWidth}%" fill="red"></rect>`;
|
|
51
|
+
const barCell = `<td aria-hidden="true"><svg width="100%" height="0.7em">${bar}</svg></td>`;
|
|
52
|
+
const row = `<tr>${pageCell}${numCell}${barCell}</tr>`;
|
|
53
|
+
return row;
|
|
54
|
+
});
|
|
55
|
+
return rows.join(innestJoiner);
|
|
56
|
+
};
|
|
57
|
+
// Populates a query for a comparative table.
|
|
58
|
+
const populateQuery = async (scoredReports, query) => {
|
|
59
|
+
const data = await getData(scoredReports);
|
|
60
|
+
query.pageCount = data.pageCount;
|
|
61
|
+
query.scriptID = scoredReports[0].sources.script;
|
|
62
|
+
query.scorer = 'tsp27';
|
|
63
|
+
query.digester = 'tdp27';
|
|
64
|
+
query.comparer = 'tcp27';
|
|
65
|
+
query.tableBody = await getTableBody(data.bodyData);
|
|
66
|
+
const date = new Date();
|
|
67
|
+
query.dateISO = date.toISOString().slice(0, 10);
|
|
68
|
+
query.dateSlash = query.dateISO.replace(/-/g, '/');
|
|
69
|
+
};
|
|
70
|
+
// Returns a digested report.
|
|
71
|
+
exports.comparer = async scoredReports => {
|
|
72
|
+
// Create a query to replace placeholders.
|
|
73
|
+
const query = {};
|
|
74
|
+
populateQuery(scoredReports, query);
|
|
75
|
+
// Get the template.
|
|
76
|
+
let template = await fs.readFile(`${__dirname}/index.html`, 'utf8');
|
|
77
|
+
// Replace its placeholders.
|
|
78
|
+
Object.keys(query).forEach(param => {
|
|
79
|
+
template = template.replace(new RegExp(`__${param}__`, 'g'), query[param]);
|
|
80
|
+
});
|
|
81
|
+
// Return the digest.
|
|
82
|
+
return template;
|
|
83
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ts27",
|
|
3
|
+
"what": "accessibility tests",
|
|
4
|
+
"strict": true,
|
|
5
|
+
"timeLimit": 330,
|
|
6
|
+
"acts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "placeholder",
|
|
9
|
+
"which": "main",
|
|
10
|
+
"launch": "webkit"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "tenonRequest",
|
|
14
|
+
"id": "a",
|
|
15
|
+
"withNewContent": false,
|
|
16
|
+
"what": "Tenon API version 2 test request, with page content"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"type": "test",
|
|
20
|
+
"which": "testaro",
|
|
21
|
+
"what": "Testaro motion test (requires webkit)",
|
|
22
|
+
"withItems": true,
|
|
23
|
+
"rules": ["y", "motion"]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "placeholder",
|
|
27
|
+
"which": "main",
|
|
28
|
+
"launch": "chromium"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "test",
|
|
32
|
+
"which": "alfa"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "test",
|
|
36
|
+
"which": "axe",
|
|
37
|
+
"detailLevel": 2
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "test",
|
|
41
|
+
"which": "continuum"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "test",
|
|
45
|
+
"which": "htmlcs"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "test",
|
|
49
|
+
"which": "ibm",
|
|
50
|
+
"withItems": true,
|
|
51
|
+
"withNewContent": false
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "test",
|
|
55
|
+
"which": "nuVal"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "test",
|
|
59
|
+
"which": "qualWeb",
|
|
60
|
+
"withNewContent": false
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"type": "test",
|
|
64
|
+
"which": "tenon",
|
|
65
|
+
"id": "a"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "test",
|
|
69
|
+
"which": "testaro",
|
|
70
|
+
"withItems": true,
|
|
71
|
+
"rules": ["n", "motion"]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"type": "test",
|
|
75
|
+
"which": "wave",
|
|
76
|
+
"reportType": 4
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|