testilo 3.1.1 → 3.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/README.md CHANGED
@@ -17,39 +17,55 @@ To score a report, Testilo needs to be told where to find the report, and also w
17
17
 
18
18
  Similarly, once a report has been scored, Testilo can digest it, provided that Testilo is told where to find the scored report and which _digest proc_ to use. Different digest procs could produce different human-oriented explanations of the same scored report, such as for different audiences.
19
19
 
20
- Testilo includes some score procs and digest procs. You can add others.
20
+ Testilo includes some score procs, digest procs, and comparison procs. You can add others.
21
21
 
22
22
  ## Execution
23
23
 
24
24
  ### Scoring
25
25
 
26
- To score a Testaro report, execute the statement `node score abc xyz`, replacing (here and below) `abc` with the base of the name of the file containing the report and `xyz` with the base of the name of the score proc.
26
+ To score Testaro reports, execute the statement `node score abc xyz`. Replace (here and below) `abc` with the base of the name of the file containing the report, or the prefix of the file name. Replace `xyz` with the base of the name of the score proc.
27
+
28
+ If you replace `abc` with the entire name base, Testilo will score one report. If you replace `abc` with a prefix (such as `35k1r-`), Testilo will score all the reports whose names begin with that prefix.
27
29
 
28
30
  This procedure has some preconditions:
29
- - The score proc is compatible with the report.
30
- - The full name of the report file is `abc.json`.
31
- - The report file is located in the directory whose relative path (relative to the project directory of Testilo) is the value of the `REPORTDIR_RAW` environment variable.
32
- - Testilo can read and write in the `REPORTDIR_RAW` directory.
33
- - Testilo can write in the `REPORTDIR_SCORED` directory.
31
+ - The score proc is compatible with the script that produced the report(s).
32
+ - The filename extension is `.json`.
33
+ - Testilo can find the report file(s) in the directory whose relative path (relative to the project directory of Testilo) is the value of the `REPORTDIR_RAW` environment variable.
34
+ - Testilo can read in the `REPORTDIR_RAW` directory.
35
+ - There is a `REPORTDIR_SCORED` environment variable, whose value is the relative path of a directory that Testilo can write to.
34
36
  - The `procs/score` directory contains a file named `xyz.js`.
35
37
 
36
- Thus, the script that Testaro ran in order to produce the report must be one that Testilo has a scoring algorithm (_score proc_) for. If so, Testilo can score the report.
37
-
38
- When Testilo scores a report, Testilo saves the scored report in the directory whose relative path is the value of the `REPORTDIR_SCORED`. The scored report file has the same name as the original.
38
+ When Testilo scores a report, Testilo saves the scored report in the directory whose relative path is the value of the `REPORTDIR_SCORED`. The scored report file has the same name as the original. The scored report has the same content as the original, plus a new property named `score`.
39
39
 
40
40
  ### Digesting
41
41
 
42
- To make a scored Testaro report more useful for humans, Testilo can create a digest of the report. This is an HTML document (a web page) summarizing and explaining the findings.
42
+ To make scored Testaro reports more useful for humans, Testilo can create digests of scored reports. A digest is an HTML document (a web page) summarizing and explaining the findings, with the scored report appended to it.
43
43
 
44
- To make Testilo digest a report, execute the statement `node digest abc xyz`, replacing `abc` (here and below) with the base of the name of the file containing the scored report and `xyz` with the base of the name of the digest proc.
44
+ To make Testilo digest reports, execute the statement `node digest abc xyz`, replacing `abc` (here and below) with a whole base name or prefix, as with scoring, and `xyz` with the base of the name of the digest proc.
45
45
 
46
46
  This procedure has some preconditions:
47
- - The digest proc is compatible with the report.
48
- - The full name of the report file is `abc.json`.
49
- - The report file is located in the directory whose relative path (relative to the project directory of Testilo) is the value of the `REPORTDIR_SCORED` environment variable.
50
- - Testilo can read and write in the `REPORTDIR_SCORED` directory.
51
- - Testilo can write in the `REPORTDIR_DIGESTED` directory.
47
+ - The digest proc is compatible with the score proc that scored the report.
48
+ - The filename extension is `.json`.
49
+ - Testilo can find the scored report file(s) in the directory whose relative path (relative to the project directory of Testilo) is the value of the `REPORTDIR_SCORED` environment variable.
50
+ - Testilo can read in the `REPORTDIR_SCORED` directory.
51
+ - There is a `REPORTDIR_DIGESTED` environment variable, whose value is the relative path of a directory that Testilo can write to.
52
52
  - The `procs/digest` directory contains a subdirectory named `xyz`, which in turn contains files named `index.html` and `index.js`.
53
53
  - You have copied the `reports/digested/style.css` file into the `REPORTDIR_DIGESTED` directory.
54
54
 
55
- When Testilo digests a report, Testilo saves the digest in the directory whose relative path is the value of the `REPORTDIR_DIGESTED`. The digest has the name `abc.html`.
55
+ When Testilo digests a report, Testilo saves the digest in the directory whose relative path is the value of the `REPORTDIR_DIGESTED` environment variable. The digest has the same name as the report on which it is based, except with `.html` as the extension.
56
+
57
+ ### Comparing
58
+
59
+ You can use Testilo to publish comparisons of accessibility scores. To do this, execute the statement `node compare abc xyz`, replacing `abc` with the prefix of the names of the reports and `xyz` with the name of a subdirectory of the `procs/compare` directory.
60
+
61
+ Testilo will use the comparison proc you name to compile the scores into a table and construct a web page containing that table. It will save the page in the `reports/comparative` directory. The name of the file will be `abc.html`.
62
+
63
+ In the table, the first column will contain descriptions of the pages (the `what` property of the hosts in the batch), such as “Wikipedia English”. Each such description will be a link to the page on the web. The second column will contain the scores of the pages. Each score will be a link to the digest for its page. The link will be `
64
+
65
+ This procedure has some preconditions:
66
+ - The comparison proc is compatible with the score proc that scored the report.
67
+ - Testilo can find the scored report files in the directory whose relative path (relative to the project directory of Testilo) is the value of the `REPORTDIR_SCORED` environment variable.
68
+ - Testilo can read in the `REPORTDIR_SCORED` directory.
69
+ - There is a `COMPARISONDIR` environment variable, whose value is the relative path of a directory that Testilo can write to.
70
+ - The `procs/compare` directory contains a subdirectory named `xyz`, which in turn contains files named `index.html` and `index.js`.
71
+ - You have copied the `reports/comparative/style.css` file into the `COMPARISONDIR` directory.
package/compare.js ADDED
@@ -0,0 +1,38 @@
1
+ /*
2
+ compare.js
3
+ Testilo comparison script.
4
+ Usage example: node compare 35k1r cp0
5
+ */
6
+
7
+ // ########## IMPORTS
8
+
9
+ // Module to keep secrets.
10
+ require('dotenv').config();
11
+ // Module to read and write files.
12
+ const fs = require('fs/promises');
13
+
14
+ // ########## CONSTANTS
15
+
16
+ const tableDir = process.env.COMPARISONDIR || 'reports/comparative';
17
+ const reportTimeStamp = process.argv[2];
18
+ const tableProcID = process.argv[3];
19
+
20
+ // ########## FUNCTIONS
21
+
22
+ // Replaces the placeholders in content with eponymous query parameters.
23
+ const replaceHolders = (content, query) => content
24
+ .replace(/__([a-zA-Z]+)__/g, (ph, qp) => query[qp]);
25
+ // Creates and saves a web page containing a comparative table.
26
+ const compare = async () => {
27
+ const tableDirAbs = `${__dirname}/${tableDir}`;
28
+ const {getQuery} = require(`./procs/compare/${tableProcID}/index`);
29
+ const query = await getQuery();
30
+ const pageRaw = await fs.readFile(`${__dirname}/procs/compare/${tableProcID}/index.html`, 'utf8');
31
+ const page = replaceHolders(pageRaw, query);
32
+ await fs.writeFile(`${tableDirAbs}/${reportTimeStamp}.html`, page);
33
+ console.log(`Page comparing ${reportTimeStamp} reports created and saved`);
34
+ };
35
+
36
+ // ########## OPERATION
37
+
38
+ compare();
package/digest.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /*
2
2
  digest.js
3
3
  Testilo digesting script.
4
+ Usage example: node digest 35k1r-railpass dp10a
4
5
  */
5
6
 
6
7
  // ########## IMPORTS
@@ -8,13 +9,13 @@
8
9
  // Module to keep secrets.
9
10
  require('dotenv').config();
10
11
  // Module to read and write files.
11
- const fs = require('fs').promises;
12
+ const fs = require('fs/promises');
12
13
 
13
14
  // ########## CONSTANTS
14
15
 
15
16
  const reportDirScored = process.env.REPORTDIR_SCORED || 'reports/scored';
16
17
  const reportDirDigested = process.env.REPORTDIR_DIGESTED || 'reports/digested';
17
- const reportID = process.argv[2];
18
+ const reportIDStart = process.argv[2];
18
19
  const digesterID = process.argv[3];
19
20
 
20
21
  // ########## FUNCTIONS
@@ -24,15 +25,23 @@ const replaceHolders = (content, query) => content
24
25
  .replace(/__([a-zA-Z]+)__/g, (ph, qp) => query[qp]);
25
26
  // Creates a digest.
26
27
  const digest = async () => {
27
- const reportJSON = await fs.readFile(`${__dirname}/${reportDirScored}/${reportID}.json`, 'utf8');
28
- const report = JSON.parse(reportJSON);
28
+ const reportDirScoredAbs = `${__dirname}/${reportDirScored}`;
29
+ const allReportFileNames = await fs.readdir(reportDirScoredAbs);
30
+ const sourceReportFileNames = allReportFileNames
31
+ .filter(fileName => fileName.startsWith(reportIDStart) && fileName.endsWith('.json'));
29
32
  const {makeQuery} = require(`${__dirname}/procs/digest/${digesterID}/index.js`);
30
- const query = {};
31
- makeQuery(report, query);
32
- const template = await fs.readFile(`${__dirname}/procs/digest/${digesterID}/index.html`, 'utf8');
33
- const digest = replaceHolders(template, query);
34
- await fs.writeFile(`${__dirname}/${reportDirDigested}/${reportID}.html`, digest);
35
- console.log(`Report ${reportID} digested and saved`);
33
+ for (const fileName of sourceReportFileNames) {
34
+ const reportJSON = await fs.readFile(`${reportDirScoredAbs}/${fileName}`, 'utf8');
35
+ const report = JSON.parse(reportJSON);
36
+ const query = {};
37
+ makeQuery(report, query);
38
+ const template = await fs
39
+ .readFile(`${__dirname}/procs/digest/${digesterID}/index.html`, 'utf8');
40
+ const digest = replaceHolders(template, query);
41
+ const fileNameBase = fileName.slice(0, -5);
42
+ await fs.writeFile(`${__dirname}/${reportDirDigested}/${fileNameBase}.html`, digest);
43
+ console.log(`Report ${fileNameBase} digested and saved`);
44
+ };
36
45
  };
37
46
 
38
47
  // ########## OPERATION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testilo",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "description": "Client that scores and digests Testaro reports",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,41 @@
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 <code>tp10</code> <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/">accessibility</a> testing procedure was executed by <a href="https://www.npmjs.com/package/testaro">Testaro</a> on __pageCount__ web pages. The procedure performed 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. Testaro produced reports enumerating the test results.</p>
22
+ <p>Given the reports produced by Testaro, another application, <a href="https://www.npmjs.com/package/testilo">Testilo</a>, used its <code>sp10a</code> procedure to assigned weights to the tests and compute a total score for each page (where 0 is the best possible score), adding a section on scoring to each report.</p>
23
+ <p>Testilo used a third procedure, <code>dp10a</code>, to create a digest from each report, summarizing the tests and how the score was computed. The report for each page is included, as an appendix, in the page&rsquo;s digest.</p>
24
+ <p>Testilo produced this comparison page with a fourth procedure, <code>cp0</code>, listing the tested web pages in order of their scores (best to worst) and showing their scores in a table. The table includes links to the pages and to the digests.</p>
25
+ <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 by any of the tests. Different reasonable procedures could yield different test results and different scores. Both Testaro and Testilo can be customized to fit different definitions and weightings of types of accessibility.</p>
26
+ <h2>Comparison</h2>
27
+ <table class="allBorder">
28
+ <caption>Accessibility scores of web pages</caption>
29
+ <thead>
30
+ <tr><th scope="col">Page</th><th scope="col" colspan="2">Score (lower is better)</tr>
31
+ </thead>
32
+ <tbody class="linkSmaller secondCellRight">
33
+ __tableBody__
34
+ </tbody>
35
+ </table>
36
+ <footer>
37
+ <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
38
+ </footer>
39
+ </main>
40
+ </body>
41
+ </html>
@@ -0,0 +1,72 @@
1
+ /*
2
+ ttp0.js
3
+ Returns a query for an HTML page including a bar-graph table.
4
+ */
5
+
6
+ // ########## IMPORTS
7
+
8
+ // Module to keep secrets local.
9
+ require('dotenv').config();
10
+ // Module to access files.
11
+ const fs = require('fs/promises');
12
+
13
+ // ########## CONSTANTS
14
+
15
+ const reportDirScored = process.env.REPORTDIR_SCORED || 'reports/scored';
16
+ const reportIDStart = process.argv[2];
17
+ const query = {};
18
+
19
+ // ########## FUNCTIONS
20
+
21
+ // Gets data on the hosts and their scores and adds query parameter.
22
+ const getData = async () => {
23
+ const reportDirAbs = `${__dirname}/../../../${reportDirScored}`;
24
+ const reportFileNamesAll = await fs.readdir(reportDirAbs);
25
+ const reportFileNamesSource = reportFileNamesAll
26
+ .filter(fileName => fileName.startsWith(reportIDStart) && fileName.endsWith('.json'));
27
+ const pageCount = reportFileNamesSource.length;
28
+ const bodyData = [];
29
+ for (const fileName of reportFileNamesSource) {
30
+ const fileJSON = await fs.readFile(`${reportDirAbs}/${fileName}`, 'utf8');
31
+ const file = JSON.parse(fileJSON);
32
+ const {id, host, score} = file;
33
+ bodyData.push({
34
+ id,
35
+ host,
36
+ score: score.scores.total
37
+ });
38
+ };
39
+ return {
40
+ pageCount,
41
+ bodyData
42
+ }
43
+ };
44
+ // Gets the maximum score.
45
+ const getMaxScore = tableData => tableData.reduce((max, item) => Math.max(max, item.score), 0);
46
+ // Converts report data to a table body.
47
+ const getTableBody = async bodyData => {
48
+ const maxScore = getMaxScore(bodyData);
49
+ const rows = bodyData
50
+ .sort((a, b) => a.score - b.score)
51
+ .map(item => {
52
+ const {id, host, score} = item;
53
+ const pageCell = `<th scope="row"><a href="${host.which}">${host.what}</a></th>`;
54
+ const numCell = `<td><a href="reports/${id}.html">${score}</a></td>`;
55
+ const barWidth = 100 * score / maxScore;
56
+ const bar = `<rect height="100%" width="${barWidth}%" fill="red"></rect>`;
57
+ const barCell = `<td aria-hidden="true"><svg width="100%" height="0.7em">${bar}</svg></td>`;
58
+ const row = `<tr>${pageCell}${numCell}${barCell}</tr>`;
59
+ return row;
60
+ });
61
+ return rows.join('\n ');
62
+ };
63
+ // Returns a query for a comparative table.
64
+ exports.getQuery = async () => {
65
+ const data = await getData();
66
+ query.pageCount = data.pageCount;
67
+ query.tableBody = await getTableBody(data.bodyData);
68
+ const date = new Date();
69
+ query.dateISO = date.toISOString().slice(0, 10);
70
+ query.dateSlash = query.dateISO.replace(/-/g, '/');
71
+ return query;
72
+ };
@@ -16,14 +16,20 @@
16
16
  <main>
17
17
  <header>
18
18
  <h1>Accessibility test digest</h1>
19
- <p class="summary bold">__org__</p>
20
- <p class="summary">Testilo, <code>tsp10</code> procedure</p>
21
- <p class="summary">Score: __totalScore__</p>
19
+ <h2>Summary</h2>
20
+ <div id="summary">
21
+ <p>Page: __org__</p>
22
+ <p>URL: __url__</p>
23
+ <p>Score: __totalScore__</p>
24
+ <p>Tested by: Testaro, <code>tp10</code></p>
25
+ <p>Scored by: Testilo, <code>sp10a</code></p>
26
+ <p>Digested by: Testilo, <code>dp10a</code></p>
27
+ </dl>
22
28
  </header>
23
29
  <h2>Introduction</h2>
24
- <p>The <code>tsp10</code> accessibility testing procedure was executed by <a href="https://www.npmjs.com/package/testaro">Testaro</a> on the web page at <a href="__url__">__url__</a>, belonging to __org__, on __dateSlash__. The procedure performed 808 tests. Of these, 16 tests are custom tests defined by Testaro, and the others belong to packages of tests created by others. Testaro produced a report enumerating the test results.</p>
30
+ <p>The <code>tp10</code> <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/">accessibility</a> testing procedure was executed by <a href="https://www.npmjs.com/package/testaro">Testaro</a> on the web page at <a href="__url__">__url__</a>, belonging to __org__, on __dateSlash__. The procedure performed 808 tests. Of these, 16 tests are custom tests defined by Testaro, and the others belong to packages of tests created by others. Testaro produced a report enumerating the test results. The report is appended, below, to this page.</p>
25
31
  <p>These tests&mdash;like all tests&mdash;are fallible. The failures described below merit investigation as <strong>potential</strong> opportunities for improved accessibility. But some reported faults may not actually harm accessibility, and some accessibility faults can escape detection by any of these tests.</p>
26
- <p>Given the report produced by Testaro, another procedure, <code>tsp10a</code>, assigned weights to the tests and computed a total score for the page, __totalScore__ (where 0 is the best possible score). Just as tests are fallible, any scoring procedure is subjective, and different reasonable procedures could assign different scores on the basis of the same report. This digest explains how <code>tsp10a</code> computed a score for the page.</p>
32
+ <p>Given the report produced by Testaro, another procedure, <code>sp10a</code>, was executed by <a href="https://www.npmjs.com/package/testilo">Testilo</a>. The procedure assigned weights to the tests and computed a total score for the page, __totalScore__ (where 0 is the best possible score). Just as tests are fallible, any scoring procedure is subjective, and different reasonable procedures could assign different scores on the basis of the same report. Testilo used procedure <code>dp10a</code> to produce this digest, explaining how <code>sp10a</code> computed the score.</p>
27
33
  <h2>Summary</h2>
28
34
  <p>The packages&rsquo; and custom tests&rsquo; contributions to the score were:</p>
29
35
  <table class="allBorder secondCellRight">
@@ -121,6 +127,8 @@
121
127
  <li>Measuring success is a prerequisite for achieving success, so interfering with accessibility measurement interferes with accessibility.</li>
122
128
  <li>Users with disabilities often rely on assistive technologies to mediate between them and web applications. Applications that interfere with automated testing are at risk of interfering with some assistive technologies, too.</li>
123
129
  </ul>
130
+ <h2>Report</h2>
131
+ <pre>__report__</pre>
124
132
  <footer>
125
133
  <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
126
134
  </footer>
@@ -1,6 +1,7 @@
1
1
  /*
2
- index: digester for procedure tsp10.
2
+ index: digester for scoring procedure sp10.
3
3
  Creator of parameters for substitution into index.html.
4
+ Usage example: node digest 35k1r-railpass dp10a
4
5
  */
5
6
  exports.makeQuery = (report, query) => {
6
7
  // Makes strings HTML-safe.
@@ -12,7 +13,12 @@ exports.makeQuery = (report, query) => {
12
13
  const joiner = '\n ';
13
14
  const innerJoiner = '\n ';
14
15
  // Create an HTML identification of the host report.
15
- const {id, script, acts, host, score} = report;
16
+ const {script, host, score} = report;
17
+ const reportJSON = JSON.stringify(report, null, 2);
18
+ const reportJSONSafe = reportJSON
19
+ .replace(/</g, '&lt;')
20
+ .replace(/&/g, '&amp;');
21
+ query.report = reportJSONSafe;
16
22
  // Creates a packaged-test success message.
17
23
  const packageSucceedText = package =>
18
24
  `<p>The page <strong>passed</strong> the <code>${package}</code> test.</p>`;
@@ -146,8 +152,9 @@ exports.makeQuery = (report, query) => {
146
152
  if (scores.tenon) {
147
153
  const testAct = actOf('tenon');
148
154
  const tenonResult = testAct.result.data.resultSet;
149
- const tenonItems = new Set(tenonResult.map(result => result.errorTitle));
150
- const tenonFailures = Array.from(tenonItems).join(innerJoiner);
155
+ const tenonSet = new Set(tenonResult.map(result => result.errorTitle));
156
+ const tenonItems = Array.from(tenonSet).map(item => `<li>${item}</li>`);
157
+ const tenonFailures = tenonItems.join(innerJoiner);
151
158
  query.tenonResult = packageFailText(scores.tenon, 'tenon', tenonFailures);
152
159
  }
153
160
  else if (inferences.tenon) {
File without changes
File without changes
@@ -1,8 +1,9 @@
1
1
  /*
2
- tsp10a
2
+ sp10a
3
3
  Testilo score proc 10a
4
- Computes scores from script tsp10 and adds them to a report. Does not discount tenon. Tenon
5
- discounting is planned future work.
4
+ Computes scores from Testaro script tp10 and adds them to a report. Does not discount tenon.
5
+ Tenon discounting is planned future work.
6
+ Usage example: node score 35k1r sp10a
6
7
  */
7
8
  exports.scorer = report => {
8
9
  // CONSTANTS
@@ -304,6 +305,33 @@ exports.scorer = report => {
304
305
  scores.total += scores.tenon;
305
306
  }
306
307
  }
308
+ else if (which === 'wave') {
309
+ facts = test.result && test.result.categories;
310
+ if (facts) {
311
+ rules.wave
312
+ = 'multiply alerts by 2*, contrast errors by 3*, errors by 4* (*discounted); sum';
313
+ const weights = {
314
+ error: 4,
315
+ contrast: 3,
316
+ alert: 2
317
+ };
318
+ const waveScores = {
319
+ error: 0,
320
+ contrast: 0,
321
+ alert: 0
322
+ };
323
+ ['error', 'contrast', 'alert'].forEach(level => {
324
+ const {items} = facts[level];
325
+ waveScores[level] = Math.round(Object.keys(items).reduce((total, ruleID) => {
326
+ const rawScore = items[ruleID].count * weights[level];
327
+ const divisor = duplications.wave[`${level.slice(0, 1)}:${ruleID}`] + 1 || 1;
328
+ return total + rawScore / divisor;
329
+ }, 0));
330
+ });
331
+ scores.wave = waveScores.error + waveScores.contrast + waveScores.alert;
332
+ scores.total += scores.wave;
333
+ }
334
+ }
307
335
  else if (which === 'bulk') {
308
336
  facts = test.result && test.result.visibleElements;
309
337
  if (typeof facts === 'number') {
@@ -0,0 +1,41 @@
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 <code>tp10</code> <a href="https://www.w3.org/WAI/fundamentals/accessibility-intro/">accessibility</a> testing procedure was executed by <a href="https://www.npmjs.com/package/testaro">Testaro</a> on 1 web pages. The procedure performed 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. Testaro produced reports enumerating the test results.</p>
22
+ <p>Given the reports produced by Testaro, another application, <a href="https://www.npmjs.com/package/testilo">Testilo</a>, used its <code>sp10a</code> procedure to assigned weights to the tests and compute a total score for each page (where 0 is the best possible score), adding a section on scoring to each report.</p>
23
+ <p>Testilo used a third procedure, <code>dp10a</code>, to create a digest from each report, summarizing the tests and how the score was computed. The report for each page is included, as an appendix, in the page&rsquo;s digest.</p>
24
+ <p>Testilo produced this comparison page with a fourth procedure, <code>cp0</code>, listing the tested web pages in order of their scores (best to worst) and showing their scores in a table. The table includes links to the pages and to the digests.</p>
25
+ <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 by any of the tests. Different reasonable procedures could yield different test results and different scores. Both Testaro and Testilo can be customized to fit different definitions and weightings of types of accessibility.</p>
26
+ <h2>Comparison</h2>
27
+ <table class="allBorder">
28
+ <caption>Accessibility scores of web pages</caption>
29
+ <thead>
30
+ <tr><th scope="col">Page</th><th scope="col" colspan="2">Score (lower is better)</tr>
31
+ </thead>
32
+ <tbody class="linkSmaller secondCellRight">
33
+ <tr><th scope="row"><a href="https://www.railpass.com/">Railpass</a></th><td><a href="reports/35k1r-railpass.html">1589</a></td><td aria-hidden="true"><svg width="100%" height="0.7em"><rect height="100%" width="100%" fill="red"></rect></svg></td></tr>
34
+ </tbody>
35
+ </table>
36
+ <footer>
37
+ <p class="date">Produced <time itemprop="datePublished" datetime="2022-06-08">2022/06/08</time></p>
38
+ </footer>
39
+ </main>
40
+ </body>
41
+ </html>
@@ -0,0 +1,85 @@
1
+ *:focus {
2
+ outline: solid 0.2rem #00f;
3
+ outline-offset: 0.2rem;
4
+ }
5
+ body {
6
+ margin: 2rem;
7
+ font-size: large;
8
+ }
9
+ .bold {
10
+ font-weight: 700;
11
+ }
12
+ button {
13
+ min-height: 44px;
14
+ min-width: 44px;
15
+ padding: 0.5rem;
16
+ border: solid 0.2rem #03a;
17
+ border-radius: 1rem;
18
+ font-size: inherit;
19
+ font-weight: 700;
20
+ color: #fff;
21
+ background-color: #03a;
22
+ }
23
+ button:hover {
24
+ color: #000;
25
+ background-color: #9df;
26
+ }
27
+ caption {
28
+ margin: 1rem 0;
29
+ font-weight: 700;
30
+ font-style: italic;
31
+ }
32
+ code {
33
+ font-family: sans-serif;
34
+ color: #832703;
35
+ }
36
+ .error {
37
+ font-weight: 700;
38
+ color: #c00;
39
+ }
40
+ fieldset {
41
+ width: max-content;
42
+ margin-top: 1rem;
43
+ }
44
+ .firstCellRight td:nth-child(1) {
45
+ text-align: right;
46
+ }
47
+ form {
48
+ margin-top: 1rem;
49
+ }
50
+ h2 {
51
+ margin: 1rem auto 0.5rem auto;
52
+ color: #006666;
53
+ }
54
+ input {
55
+ margin: 0.5rem 0;
56
+ font-size: inherit;
57
+ }
58
+ legend {
59
+ font-weight: 700;
60
+ }
61
+ .secondCellRight td:nth-child(2) {
62
+ text-align: right;
63
+ }
64
+ section:not(.wide) {
65
+ max-width: 36rem;
66
+ }
67
+ table {
68
+ border-collapse: collapse;
69
+ }
70
+ table.allBorder th {
71
+ padding-bottom: 0;
72
+ }
73
+ table.allBorder th, table.allBorder td, tbody td {
74
+ border: 1px gray solid;
75
+ }
76
+ tbody th {
77
+ padding-right: 1rem;
78
+ text-align: right;
79
+ }
80
+ td, th {
81
+ padding: 0 0.5rem;
82
+ }
83
+ thead th {
84
+ padding-bottom: 1rem;
85
+ }