testilo 3.12.2 → 3.12.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testilo",
3
- "version": "3.12.2",
3
+ "version": "3.12.3",
4
4
  "description": "Client that scores and digests Testaro reports",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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>tp16</code></li>
25
+ <li>Scored by <a href="https://www.npmjs.com/package/testilo">Testilo</a> with procedure <code>sp16a</code></li>
26
+ <li>Digested by Testilo with procedure <code>dp16a</code></li>
27
+ <li>Compared by Testilo with procedure <code>cp16a</code></li>
28
+ </ol>
29
+ <p>The Testaro procedure performs 1225 tests on each page. Of these, 19 tests are custom tests defined by Testaro, and the others belong to packages of tests created by others.</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 (lower is better)</tr>
35
+ </thead>
36
+ <tbody class="linkSmaller secondCellRight">
37
+ __tableBody__
38
+ </tbody>
39
+ </table>
40
+ <h2>Discussion</h2>
41
+ <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 are not detectable with these tests. 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>
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,74 @@
1
+ /*
2
+ cp16a.js
3
+ Returns a query for an HTML page including a bar-graph table.
4
+ Makes the bar widths the square roots of their proportional widths, for cases of extreme
5
+ score disparity.
6
+ */
7
+
8
+ // ########## IMPORTS
9
+
10
+ // Module to keep secrets local.
11
+ require('dotenv').config();
12
+ // Module to access files.
13
+ const fs = require('fs/promises');
14
+
15
+ // ########## CONSTANTS
16
+
17
+ const reportDirScored = process.env.REPORTDIR_SCORED || 'reports/scored';
18
+ const query = {};
19
+
20
+ // ########## FUNCTIONS
21
+
22
+ // Returns data on the hosts in the report directory.
23
+ const getData = async () => {
24
+ const reportDirAbs = `${__dirname}/../../../${reportDirScored}`;
25
+ const reportFileNamesAll = await fs.readdir(reportDirAbs);
26
+ const reportFileNamesSource = reportFileNamesAll.filter(fileName => 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
+ org: host.what,
36
+ url: host.which,
37
+ score: score.summary.total
38
+ });
39
+ };
40
+ return {
41
+ pageCount,
42
+ bodyData
43
+ }
44
+ };
45
+ // Returns the maximum score.
46
+ const getMaxScore = tableData => tableData.reduce((max, item) => Math.max(max, item.score), 0);
47
+ // Converts report data to a table body.
48
+ const getTableBody = async bodyData => {
49
+ const maxScore = getMaxScore(bodyData);
50
+ const rows = bodyData
51
+ .sort((a, b) => a.score - b.score)
52
+ .map(item => {
53
+ const {id, org, url, score} = item;
54
+ const pageCell = `<th scope="row"><a href="${url}">${org}</a></th>`;
55
+ const numCell = `<td><a href="digests/${id}.html">${score}</a></td>`;
56
+ // Make the bar width proportional.
57
+ const barWidth = 100 * score / maxScore;
58
+ const bar = `<rect height="100%" width="${barWidth}%" fill="red"></rect>`;
59
+ const barCell = `<td aria-hidden="true"><svg width="100%" height="0.7em">${bar}</svg></td>`;
60
+ const row = `<tr>${pageCell}${numCell}${barCell}</tr>`;
61
+ return row;
62
+ });
63
+ return rows.join('\n ');
64
+ };
65
+ // Returns a query for a comparative table.
66
+ exports.getQuery = async () => {
67
+ const data = await getData();
68
+ query.pageCount = data.pageCount;
69
+ query.tableBody = await getTableBody(data.bodyData);
70
+ const date = new Date();
71
+ query.dateISO = date.toISOString().slice(0, 10);
72
+ query.dateSlash = query.dateISO.replace(/-/g, '/');
73
+ return query;
74
+ };
@@ -81,7 +81,7 @@ const groups = {
81
81
  }
82
82
  },
83
83
  duplicateID: {
84
- weight: 3,
84
+ weight: 4,
85
85
  packages: {
86
86
  alfa: {
87
87
  r3: {
@@ -3043,7 +3043,7 @@ const groups = {
3043
3043
  }
3044
3044
  },
3045
3045
  docType: {
3046
- weight: 3,
3046
+ weight: 10,
3047
3047
  packages: {
3048
3048
  nuVal: {
3049
3049
  'Start tag seen without seeing a doctype first. Expected <!DOCTYPE html>.': {
@@ -3056,13 +3056,13 @@ const groups = {
3056
3056
  docType: {
3057
3057
  variable: false,
3058
3058
  quality: 1,
3059
- what: 'document has no doctype property'
3059
+ what: 'document has no valid doctype property'
3060
3060
  }
3061
3061
  }
3062
3062
  }
3063
3063
  },
3064
3064
  pageTitle: {
3065
- weight: 3,
3065
+ weight: 10,
3066
3066
  packages: {
3067
3067
  alfa: {
3068
3068
  r1: {
@@ -3199,7 +3199,7 @@ const groups = {
3199
3199
  }
3200
3200
  },
3201
3201
  h1Missing: {
3202
- weight: 2,
3202
+ weight: 3,
3203
3203
  packages: {
3204
3204
  alfa: {
3205
3205
  r61: {
@@ -4657,6 +4657,18 @@ const groups = {
4657
4657
  }
4658
4658
  }
4659
4659
  },
4660
+ contentHidden: {
4661
+ weight: 10,
4662
+ packages: {
4663
+ testaro: {
4664
+ allHidden: {
4665
+ variable: false,
4666
+ quality: 1,
4667
+ what: 'Content is entirely or mainly hidden'
4668
+ }
4669
+ }
4670
+ }
4671
+ },
4660
4672
  hiddenContentRisk: {
4661
4673
  weight: 1,
4662
4674
  packages: {
@@ -5943,6 +5955,32 @@ exports.scorer = async report => {
5943
5955
  });
5944
5956
  }
5945
5957
  }
5958
+ else if (which === 'allHidden') {
5959
+ const {result} = test;
5960
+ if (
5961
+ ['hidden', 'reallyHidden', 'visHidden', 'ariaHidden']
5962
+ .every(
5963
+ key => (result[key])
5964
+ && ['document', 'body', 'main'].every(element => typeof result[key][element] === 'boolean')
5965
+ )
5966
+ ) {
5967
+ // Get a score for the test.
5968
+ const score = 8 * result.hidden.document
5969
+ + 8 * result.hidden.body
5970
+ + 6 * result.hidden.main
5971
+ + 10 * result.reallyHidden.document
5972
+ + 10 * result.reallyHidden.body
5973
+ + 8 * result.reallyHidden.main
5974
+ + 8 * result.visHidden.document
5975
+ + 8 * result.visHidden.body
5976
+ + 6 * result.visHidden.main
5977
+ + 10 * result.ariaHidden.document
5978
+ + 10 * result.ariaHidden.body
5979
+ + 8 * result.ariaHidden.main;
5980
+ // Add the score.
5981
+ addDetail('testaro', which, score);
5982
+ }
5983
+ }
5946
5984
  else if (which === 'bulk') {
5947
5985
  const count = test.result && test.result.visibleElements;
5948
5986
  if (typeof count === 'number') {
@@ -5950,6 +5988,13 @@ exports.scorer = async report => {
5950
5988
  addDetail('testaro', which, Math.max(0, count / 300 - 1));
5951
5989
  }
5952
5990
  }
5991
+ else if (which === 'docType') {
5992
+ const hasType = test.result && test.result.docHasType;
5993
+ if (typeof hasType === 'boolean') {
5994
+ // Add 10 if document has no doctype.
5995
+ addDetail('testaro', which, 10);
5996
+ }
5997
+ }
5953
5998
  else if (which === 'embAc') {
5954
5999
  const issueCounts = test.result && test.result.totals;
5955
6000
  if (issueCounts) {