testilo 13.10.4 → 14.0.1

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/script.js CHANGED
@@ -14,7 +14,7 @@ require('dotenv').config();
14
14
  // ########## VARIABLES
15
15
 
16
16
  let toolIDs = [
17
- 'alfa', 'axe', 'continuum', 'htmlcs', 'ibm', 'nuVal', 'qualWeb', 'tenon', 'testaro', 'wave'
17
+ 'alfa', 'axe', 'continuum', 'htmlcs', 'ibm', 'nuVal', 'qualWeb', 'testaro', 'wave'
18
18
  ];
19
19
 
20
20
  // ########## FUNCTIONS
@@ -79,16 +79,6 @@ exports.script = (id, issues = null, ... issueIDs) => {
79
79
  }
80
80
  ]
81
81
  };
82
- // If Tenon is one of the identified tools:
83
- if (toolIDs.includes('tenon')) {
84
- // Add a Tenon request act to the script.
85
- scriptObj.acts.push({
86
- type: 'tenonRequest',
87
- id: 'a',
88
- withNewContent: false,
89
- what: 'Tenon API version 2 test request, with page content'
90
- });
91
- }
92
82
  // For each identified tool:
93
83
  toolIDs.forEach(toolID => {
94
84
  // Initialize a test act for it.
@@ -117,11 +107,9 @@ exports.script = (id, issues = null, ... issueIDs) => {
117
107
  else if (toolID === 'qualWeb') {
118
108
  toolAct.withNewContent = false;
119
109
  }
120
- else if (toolID === 'tenon') {
121
- toolAct.id = 'a';
122
- }
123
110
  else if (toolID === 'testaro') {
124
111
  toolAct.withItems = true;
112
+ toolAct.stopOnFail = false;
125
113
  }
126
114
  else if (toolID === 'wave') {
127
115
  toolAct.reportType = 4;
@@ -1,27 +1,9 @@
1
1
  {
2
- "id": "ts27",
2
+ "id": "ts31",
3
3
  "what": "accessibility tests",
4
4
  "strict": true,
5
5
  "timeLimit": 330,
6
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
7
  {
26
8
  "type": "placeholder",
27
9
  "which": "main",
@@ -59,16 +41,11 @@
59
41
  "which": "qualWeb",
60
42
  "withNewContent": false
61
43
  },
62
- {
63
- "type": "test",
64
- "which": "tenon",
65
- "id": "a"
66
- },
67
44
  {
68
45
  "type": "test",
69
46
  "which": "testaro",
70
47
  "withItems": true,
71
- "rules": ["n", "motion"]
48
+ "stopOnFail": false
72
49
  },
73
50
  {
74
51
  "type": "test",
@@ -1,48 +0,0 @@
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 script <code>ts20</code></li>
25
- <li>Scored by <a href="https://www.npmjs.com/package/testilo">Testilo</a> with procedure <code>sp20b</code></li>
26
- <li>Digested by Testilo with procedure <code>dp20d</code></li>
27
- <li>Compared by Testilo with procedure <code>cp20a</code></li>
28
- </ol>
29
- <p>The script made Testaro perform 1230 automated accessibility tests drawn from nine different packages: Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, Tenon, Testaro, and WAVE. The scoring procedure made Testilo 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 (lower is better)</tr>
35
- </thead>
36
- <tbody class="linkSmaller secondCellRight">
37
- __tableBody__
38
- </tbody>
39
- </table>
40
- <h2>Discussion</h2>
41
- <p>The widths of the bars in the above table are proportional to the square roots of the scores that the bars represent. For example, if score A is 4 times score B, then bar A is 2 times as wide as bar B.</p>
42
- <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>
43
- <footer>
44
- <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
45
- </footer>
46
- </main>
47
- </body>
48
- </html>
@@ -1,66 +0,0 @@
1
- /*
2
- cp20sqrt.js
3
- Returns a query for replacing placeholders in the associated template.
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 query = {};
18
-
19
- // ########## FUNCTIONS
20
-
21
- // Returns data on the targets.
22
- const getData = async scoredReports => {
23
- const bodyData = [];
24
- for (const report of scoredReports) {
25
- const {id, acts, sources, score} = report;
26
- bodyData.push({
27
- id,
28
- org: sources.target.what,
29
- url: acts[1].which,
30
- score: score.summary.total
31
- });
32
- };
33
- return {
34
- pageCount: scoredReports.length,
35
- bodyData
36
- }
37
- };
38
- // Returns the maximum score.
39
- const getMaxScore = tableData => tableData.reduce((max, item) => Math.max(max, item.score), 0);
40
- // Converts report data to a table body.
41
- const getTableBody = async bodyData => {
42
- const maxScore = getMaxScore(bodyData);
43
- const rows = bodyData
44
- .sort((a, b) => a.score - b.score)
45
- .map(item => {
46
- const {id, org, url, score} = item;
47
- const pageCell = `<th scope="row"><a href="${url}">${org}</a></th>`;
48
- const numCell = `<td><a href="digests/${id}.html">${score}</a></td>`;
49
- // Make the bar width proportional.
50
- const barWidth = 100 * score / maxScore;
51
- const bar = `<rect height="100%" width="${barWidth}%" fill="red"></rect>`;
52
- const barCell = `<td aria-hidden="true"><svg width="100%" height="0.7em">${bar}</svg></td>`;
53
- const row = `<tr>${pageCell}${numCell}${barCell}</tr>`;
54
- return row;
55
- });
56
- return rows.join('\n ');
57
- };
58
- // Populates a query for a comparative table.
59
- exports.getQuery = async (scoredReports, query) => {
60
- const data = await getData(scoredReports);
61
- query.pageCount = data.pageCount;
62
- query.tableBody = await getTableBody(data.bodyData);
63
- const date = new Date();
64
- query.dateISO = date.toISOString().slice(0, 10);
65
- query.dateSlash = query.dateISO.replace(/-/g, '/');
66
- };
@@ -1,47 +0,0 @@
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 script <code>ts20</code></li>
25
- <li>Scored by <a href="https://www.npmjs.com/package/testilo">Testilo</a> with procedure <code>sp20b</code></li>
26
- <li>Digested by Testilo with procedure <code>dp20d</code></li>
27
- <li>Compared by Testilo with procedure <code>cp20a</code></li>
28
- </ol>
29
- <p>The script made Testaro perform 1230 automated accessibility tests drawn from nine different packages: Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, Tenon, Testaro, and WAVE. The scoring procedure made Testilo 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 (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>
@@ -1,64 +0,0 @@
1
- /*
2
- cp24.js
3
- Returns a query for replacing placeholders in the associated template.
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 query = {};
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, acts, sources, score} = report;
24
- bodyData.push({
25
- id,
26
- org: sources.target.what,
27
- url: acts[1].which,
28
- score: score.summary.total
29
- });
30
- };
31
- return {
32
- pageCount: scoredReports.length,
33
- bodyData
34
- }
35
- };
36
- // Returns the maximum score.
37
- const getMaxScore = tableData => tableData.reduce((max, item) => Math.max(max, item.score), 0);
38
- // Converts report data to a table body.
39
- const getTableBody = async bodyData => {
40
- const maxScore = getMaxScore(bodyData);
41
- const rows = bodyData
42
- .sort((a, b) => a.score - b.score)
43
- .map(item => {
44
- const {id, org, url, score} = item;
45
- const pageCell = `<th scope="row"><a href="${url}">${org}</a></th>`;
46
- const numCell = `<td><a href="digests/${id}.html">${score}</a></td>`;
47
- // Make the bar width proportional.
48
- const barWidth = 100 * score / maxScore;
49
- const bar = `<rect height="100%" width="${barWidth}%" fill="red"></rect>`;
50
- const barCell = `<td aria-hidden="true"><svg width="100%" height="0.7em">${bar}</svg></td>`;
51
- const row = `<tr>${pageCell}${numCell}${barCell}</tr>`;
52
- return row;
53
- });
54
- return rows.join('\n ');
55
- };
56
- // Populates a query for a comparative table.
57
- exports.getQuery = async (scoredReports, query) => {
58
- const data = await getData(scoredReports);
59
- query.pageCount = data.pageCount;
60
- query.tableBody = await getTableBody(data.bodyData);
61
- const date = new Date();
62
- query.dateISO = date.toISOString().slice(0, 10);
63
- query.dateSlash = query.dateISO.replace(/-/g, '/');
64
- };
@@ -1,83 +0,0 @@
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
- };
@@ -1,47 +0,0 @@
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>
@@ -1,54 +0,0 @@
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="report of accessibility testing of a web page">
10
- <meta name="keywords" content="accessibility a11y web testing">
11
- <title>Accessibility digest</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 digest</h1>
19
- <table class="allBorder">
20
- <caption>Synopsis</caption>
21
- <tr><th>Page</th><td>__org__</td></tr>
22
- <tr><th>URL</th><td>__url__</td></tr>
23
- <tr><th>Requester</th><td>__requester__</td></tr>
24
- <tr><th>Test date</th><td>__dateSlash__</td></tr>
25
- <tr><th>Score</th><td>__totalScore__</td></tr>
26
- <tr><th>Tested by</th><td>Testaro, procedure <code>__ts__</code></td></tr>
27
- <tr><th>Scored by</th><td>Testilo, procedure <code>__sp__</code></td></tr>
28
- <tr><th>Digested by</th><td>Testilo, procedure <code>__dp__</code></td></tr>
29
- </table>
30
- </header>
31
- <h2>Introduction</h2>
32
- <p>This is a digest of results from 1353 automated accessibility tests drawn from ten different tools: Alfa, Axe, Continuum, Equal Access, HTML CodeSniffer, Nu Html Checker, QualWeb, Tenon, Testaro, and WAVE.</p>
33
- <p>These tests were run on the web page named above and gave the page a score of __totalScore__, where 0 would be <q>perfect</q>.</p>
34
- <p>The total score is based mainly on the severities and instance counts of issues discovered. Secondary components include obviousness (how many tools reported issues), incompatibility (how many tools the page interfered with), nonconformity (how much error and notice logging the page provoked), and unresponsiveness (how slowly the page loaded).</p>
35
- <h2>Score summary</h2>
36
- <table class="allBorder secondCellRight">
37
- <caption>Score components</caption>
38
- <tbody class="headersLeft">
39
- __scoreRows__
40
- </tbody>
41
- </table>
42
- <h2>Issue summary</h2>
43
- <h3>Special issues</h3>
44
- __specialSummary__
45
- <h3>Classified issues</h3>
46
- __issueSummary__
47
- <h2>Complete report</h2>
48
- <pre>__report__</pre>
49
- <footer>
50
- <p class="date">Produced <time itemprop="datePublished" datetime="__dateISO__">__dateSlash__</time></p>
51
- </footer>
52
- </main>
53
- </body>
54
- </html>
@@ -1,117 +0,0 @@
1
- /*
2
- index: digester for scoring procedure tsp24.
3
- Creator of parameters for substitution into index.html.
4
- */
5
-
6
- // CONSTANTS
7
-
8
- const id = 'tdp27';
9
- // Newlines with indentations.
10
- const joiner = '\n ';
11
- const innerJoiner = '\n ';
12
-
13
- // FUNCTIONS
14
-
15
- // Makes strings HTML-safe.
16
- const htmlEscape = textOrNumber => textOrNumber
17
- .toString()
18
- .replace(/&/g, '&amp;')
19
- .replace(/</g, '&lt;');
20
- // Gets a row of the score-summary table.
21
- const getScoreRow = (component, score) => `<tr><th>${component}</th><td>${score}</td></tr>`;
22
- // Gets the start of a paragraph about a special score.
23
- const getSpecialPStart = (summary, scoreID) =>
24
- `<p><span class="componentID">${scoreID}</span>: Score ${summary[scoreID]}.`;
25
- // Adds parameters to a query for a digest.
26
- exports.makeQuery = (report, query) => {
27
- // Add an HTML-safe copy of the report to the query to be appended to the digest.
28
- const {acts, sources, jobData, score} = report;
29
- const {script, target, requester} = sources;
30
- const reportJSON = JSON.stringify(report, null, 2);
31
- const reportJSONSafe = htmlEscape(reportJSON);
32
- query.report = reportJSONSafe;
33
- const {scoreProcID, summary, issues, tools, preventions} = score;
34
- query.ts = script;
35
- query.sp = scoreProcID;
36
- query.dp = id;
37
- // Add the job data to the query.
38
- query.dateISO = jobData.endTime.slice(0, 10);
39
- query.dateSlash = query.dateISO.replace(/-/g, '/');
40
- query.url = target.which;
41
- query.org = target.what;
42
- query.requester = requester;
43
- const {total} = summary;
44
- const issueTotal = summary.issues;
45
- if (typeof total === 'number') {
46
- query.totalScore = total;
47
- }
48
- else {
49
- console.log('ERROR: missing or invalid total score');
50
- return;
51
- }
52
- // Add the total and the rows of the score-summary table to the query.
53
- const scoreRows = [];
54
- const componentIDs = ['issues', 'tools', 'preventions', 'log', 'latency'];
55
- ['total'].concat(componentIDs).forEach(itemID => {
56
- if (summary[itemID]) {
57
- scoreRows.push(getScoreRow(itemID, summary[itemID]));
58
- }
59
- });
60
- // Add the issue rows of the score-summary table to the query.
61
- Object.keys(issues).forEach(issueID => {
62
- scoreRows.push(getScoreRow(issueID, issues[issueID]));
63
- });
64
- query.scoreRows = scoreRows.join(innerJoiner);
65
- // If the score has any special components:
66
- const scoredSpecialIDs = specialComponentIDs.filter(item => summary[item]);
67
- if (scoredSpecialIDs.length) {
68
- // Add paragraphs about them for the issue summary to the query.
69
- const specialPs = [];
70
- scoredSpecialIDs.forEach(id => {
71
- specialPs.push(`${getSpecialPStart(summary, id)} ${specialMessages[id]}`);
72
- });
73
- query.specialSummary = specialPs.join(joiner);
74
- }
75
- // Otherwise, i.e. if the score has no special components:
76
- else {
77
- // Add a paragraph stating this for the issue summary to the query.
78
- query.specialSummary = '<p>No special issues contributed to the score.</p>'
79
- }
80
- // If the score has any classified issues as components:
81
- if (issues.length) {
82
- // Add paragraphs about them for the group summary to the query.
83
- const issueSummaryItems = [];
84
- issues.forEach(issue => {
85
- const {issueName, score} = issue;
86
- const issueHeading = `<h4>Issue ${issueName}</h4>`;
87
- const wcagP = `<p>WCAG: ${issueDetails.issues[issueName].wcag || 'N/A'}</p>`;
88
- const scoreP = `<p>Score: ${score}</p>`;
89
- const issueIntroP = '<p>Issue reports in this category:</p>';
90
- const issueListItems = [];
91
- const issueData = issueDetails.issues[issueName];
92
- const toolIDs = Object.keys(issueData.tools);
93
- toolIDs.forEach(toolID => {
94
- const testIDs = Object.keys(issueData.tools[toolID]);
95
- testIDs.forEach(testID => {
96
- const testData = issueData.tools[toolID][testID];
97
- const {score, what} = testData;
98
- const listItem =
99
- `<li>Package <code>${toolID}</code>, test <code>${testID}</code>, score ${score} (${what})</li>`;
100
- issueListItems.push(listItem);
101
- });
102
- });
103
- const issueList = [
104
- '<ul>',
105
- issueListItems.join('\n '),
106
- '</ul>'
107
- ].join(joiner);
108
- issueSummaryItems.push(issueHeading, wcagP, scoreP, issueIntroP, issueList);
109
- });
110
- query.issueSummary = issueSummaryItems.join(joiner);
111
- }
112
- // Otherwise, i.e. if the score has no classified issues as components:
113
- else {
114
- // Add a paragraph stating this for the issue summary to the query.
115
- query.issueSummary = '<p>No classified issues contributed to the score.</p>'
116
- }
117
- };