testaro 28.2.3 → 28.2.5
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/CONTRIBUTING.md +2 -3
- package/package.json +1 -1
- package/procs/tellServer.js +28 -0
- package/run.js +14 -31
- package/tests/testaro.js +22 -8
package/CONTRIBUTING.md
CHANGED
|
@@ -12,7 +12,6 @@ Testaro can benefit from contributions of various types, such as:
|
|
|
12
12
|
|
|
13
13
|
Tools that may merit consideration include:
|
|
14
14
|
- Arc (by TPGi). Costs $0.05 per page tested, and requires each user to have an account with the tool maker and to allow the tool maker to charge a charge account for payment.
|
|
15
|
-
- Aslint (by Essential Accessibility). Apparently requires using a bundle file that is in the repository but is also listed in the `.gitignore` file and is missing from the published package, so would need to be physically included in the Testaro code rather than referenced as a dependency.
|
|
16
15
|
|
|
17
16
|
## Improving execution speed
|
|
18
17
|
|
|
@@ -24,13 +23,13 @@ To come.
|
|
|
24
23
|
|
|
25
24
|
## Implementing new rules
|
|
26
25
|
|
|
27
|
-
Testaro has about 50 of its own rules, in addition to the approximately
|
|
26
|
+
Testaro has about 50 of its own rules, in addition to the approximately 900 rules of the other tools that it integrates. According to the issue classifications in the [Testilo](https://www.npmjs.com/package/testilo) package, these 950 or so rules can be classified into about 290 accessibility _issues_, because some rules of some tools at least approximately duplicate some rules of other tools.
|
|
28
27
|
|
|
29
28
|
However, many other significant accessibility issues exist that are not covered by any of the existing rules. Thus, Testaro welcomes contributions of new rules for such issues.
|
|
30
29
|
|
|
31
30
|
### Step 1
|
|
32
31
|
|
|
33
|
-
The first step in contributing a new rule to Testaro is to satisfy yourself that it will not duplicate existing rules. The `procs/score/
|
|
32
|
+
The first step in contributing a new rule to Testaro is to satisfy yourself that it will not duplicate existing rules. The `procs/score/tic36.js` file in the Testilo package should be helpful here.
|
|
34
33
|
|
|
35
34
|
### Step 2
|
|
36
35
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
tellServer
|
|
3
|
+
Notify the server.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// CONSTANTS
|
|
7
|
+
|
|
8
|
+
const httpClient = require('http');
|
|
9
|
+
const httpsClient = require('https');
|
|
10
|
+
const agent = process.env.AGENT;
|
|
11
|
+
|
|
12
|
+
// FUNCTIONS
|
|
13
|
+
|
|
14
|
+
exports.tellServer = (report, messageParams, logMessage) => {
|
|
15
|
+
const observer = report.sources.sendReportTo.replace(/report$/, 'granular');
|
|
16
|
+
const whoParams = `agent=${agent}&jobID=${report.id || ''}`;
|
|
17
|
+
const wholeURL = `${observer}?${whoParams}&${messageParams}`;
|
|
18
|
+
const client = wholeURL.startsWith('https://') ? httpsClient : httpClient;
|
|
19
|
+
const request = client.request(wholeURL);
|
|
20
|
+
// If the notification threw an error:
|
|
21
|
+
request.on('error', error => {
|
|
22
|
+
// Report the error.
|
|
23
|
+
const errorMessage = 'ERROR notifying the server';
|
|
24
|
+
console.log(`${errorMessage} (${error.message})`);
|
|
25
|
+
});
|
|
26
|
+
request.end();
|
|
27
|
+
console.log(`${logMessage} (server notified)`);
|
|
28
|
+
};
|
package/run.js
CHANGED
|
@@ -13,9 +13,8 @@ const {actSpecs} = require('./actSpecs');
|
|
|
13
13
|
const {browserClose, getNonce, goTo, launch} = require('./procs/nav');
|
|
14
14
|
// Module to standardize report formats.
|
|
15
15
|
const {standardize} = require('./procs/standardize');
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
const https = require('https');
|
|
16
|
+
// Module to send a notice to the server.
|
|
17
|
+
const {tellServer} = require('./procs/tellServer');
|
|
19
18
|
|
|
20
19
|
// ########## CONSTANTS
|
|
21
20
|
|
|
@@ -48,10 +47,6 @@ const tests = {
|
|
|
48
47
|
testaro: 'Testaro',
|
|
49
48
|
wave: 'WAVE',
|
|
50
49
|
};
|
|
51
|
-
// Observation items.
|
|
52
|
-
const httpClient = require('http');
|
|
53
|
-
const httpsClient = require('https');
|
|
54
|
-
const agent = process.env.AGENT;
|
|
55
50
|
|
|
56
51
|
// ########## VARIABLES
|
|
57
52
|
|
|
@@ -118,7 +113,7 @@ const hasSubtype = (variable, subtype) => {
|
|
|
118
113
|
return tests[variable];
|
|
119
114
|
}
|
|
120
115
|
else if (subtype === 'isWaitable') {
|
|
121
|
-
return
|
|
116
|
+
return ['url', 'title', 'body'].includes(variable);
|
|
122
117
|
}
|
|
123
118
|
else if (subtype === 'areNumbers') {
|
|
124
119
|
return areNumbers(variable);
|
|
@@ -469,26 +464,12 @@ const doActs = async (report, actIndex, page) => {
|
|
|
469
464
|
actInfo = act.which;
|
|
470
465
|
}
|
|
471
466
|
}
|
|
472
|
-
const whichSuffix = actInfo ? ` (${actInfo})` : '';
|
|
473
467
|
// If granular reporting has been specified:
|
|
474
|
-
let granularSuffix = '';
|
|
475
468
|
if (report.observe) {
|
|
476
469
|
// Notify the server of the act.
|
|
477
|
-
const
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
const wholeURL = `${observer}?${whoParams}&${actParams}`;
|
|
481
|
-
const client = wholeURL.startsWith('https://') ? httpsClient : httpClient;
|
|
482
|
-
const request = client.request(wholeURL);
|
|
483
|
-
// If the notification threw an error:
|
|
484
|
-
request.on('error', error => {
|
|
485
|
-
// Report the error.
|
|
486
|
-
const errorMessage = `ERROR notifying the server of an act`;
|
|
487
|
-
console.log(`${errorMessage} (${error.message})`);
|
|
488
|
-
});
|
|
489
|
-
request.end();
|
|
490
|
-
granularSuffix = ' with notice to server';
|
|
491
|
-
console.log(`>>>> ${act.type}${whichSuffix}${granularSuffix}`);
|
|
470
|
+
const whichParam = act.which ? `&which=${act.which}` : '';
|
|
471
|
+
const messageParams = `act=${act.type}${whichParam}`;
|
|
472
|
+
tellServer(report, messageParams, `>>>> ${act.type}: ${actInfo}`);
|
|
492
473
|
}
|
|
493
474
|
// Increment the count of acts performed.
|
|
494
475
|
actCount++;
|
|
@@ -582,12 +563,12 @@ const doActs = async (report, actIndex, page) => {
|
|
|
582
563
|
addError(act, 'badRedirection', 'ERROR: Navigation illicitly redirected');
|
|
583
564
|
await abortActs();
|
|
584
565
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
566
|
+
// Otherwise, i.e. if the visit failed:
|
|
567
|
+
else {
|
|
568
|
+
// Report this and quit.
|
|
569
|
+
addError(act, 'failure', 'ERROR: Visit failed');
|
|
570
|
+
await abortActs();
|
|
571
|
+
}
|
|
591
572
|
}
|
|
592
573
|
}
|
|
593
574
|
// Otherwise, if the act is a wait for text:
|
|
@@ -712,7 +693,9 @@ const doActs = async (report, actIndex, page) => {
|
|
|
712
693
|
act.what = tests[act.which];
|
|
713
694
|
// Initialize the options argument.
|
|
714
695
|
const options = {
|
|
696
|
+
report,
|
|
715
697
|
act,
|
|
698
|
+
granular: report.observe,
|
|
716
699
|
scriptNonce: report.jobData.lastScriptNonce || ''
|
|
717
700
|
};
|
|
718
701
|
// Add any specified arguments to it.
|
package/tests/testaro.js
CHANGED
|
@@ -9,21 +9,27 @@
|
|
|
9
9
|
const {init, report} = require('../procs/testaro');
|
|
10
10
|
// Module to handle files.
|
|
11
11
|
const fs = require('fs/promises');
|
|
12
|
+
// Module to send a notice to the server.
|
|
13
|
+
const {tellServer} = require('../procs/tellServer');
|
|
12
14
|
|
|
13
15
|
// ######## CONSTANTS
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
/*
|
|
18
|
+
const futureEvalRulesTraining = {
|
|
17
19
|
altScheme: 'img elements with alt attributes having URLs as their entire values',
|
|
18
20
|
captionLoc: 'caption elements that are not first children of table elements',
|
|
19
21
|
datalistRef: 'elements with ambiguous or missing referenced datalist elements',
|
|
22
|
+
secHeading: 'headings that violate the logical level order in their sectioning containers',
|
|
23
|
+
textSem: 'semantically vague elements i, b, and/or small'
|
|
24
|
+
};
|
|
25
|
+
const futureEvalRulesCleanRoom = {
|
|
26
|
+
adbID: 'elements with ambiguous or missing referenced descriptions',
|
|
20
27
|
imageLink: 'links with image files as their destinations',
|
|
21
28
|
legendLoc: 'legend elements that are not first children of fieldset elements',
|
|
22
29
|
optRoleSel: 'Non-option elements with option roles that have no aria-selected attributes',
|
|
23
|
-
phOnly: 'input elements with placeholders but no accessible names'
|
|
24
|
-
secHeading: 'headings that violate the logical level order in their sectioning containers',
|
|
25
|
-
textSem: 'semantically vague elements i, b, and/or small',
|
|
30
|
+
phOnly: 'input elements with placeholders but no accessible names'
|
|
26
31
|
};
|
|
32
|
+
*/
|
|
27
33
|
const evalRules = {
|
|
28
34
|
allCaps: 'leaf elements with entirely upper-case text longer than 7 characters',
|
|
29
35
|
allHidden: 'page that is entirely or mostly hidden',
|
|
@@ -95,7 +101,7 @@ const jsonTest = async (ruleID, ruleArgs) => {
|
|
|
95
101
|
};
|
|
96
102
|
// Conducts and reports Testaro tests.
|
|
97
103
|
exports.reporter = async (page, options) => {
|
|
98
|
-
const {withItems, stopOnFail, args} = options;
|
|
104
|
+
const {withItems, stopOnFail, granular, args} = options;
|
|
99
105
|
const argRules = args ? Object.keys(args) : null;
|
|
100
106
|
const rules = options.rules || ['y', ... Object.keys(evalRules)];
|
|
101
107
|
// Initialize the data.
|
|
@@ -129,13 +135,21 @@ exports.reporter = async (page, options) => {
|
|
|
129
135
|
// Add them to the argument array.
|
|
130
136
|
ruleArgs.push(... args[rule]);
|
|
131
137
|
}
|
|
132
|
-
//
|
|
138
|
+
// If granular reporting is specified:
|
|
133
139
|
const what = evalRules[rule] || etcRules[rule];
|
|
140
|
+
if (granular) {
|
|
141
|
+
// Report the rule to the server.
|
|
142
|
+
tellServer(
|
|
143
|
+
options.report,
|
|
144
|
+
`act=test&which=testaro&rule=${rule}&ruleWhat=${what}`,
|
|
145
|
+
`>>>>>> ${rule} (${what})`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
// Test the page.
|
|
134
149
|
if (! data.rules[rule]) {
|
|
135
150
|
data.rules[rule] = {};
|
|
136
151
|
}
|
|
137
152
|
data.rules[rule].what = what;
|
|
138
|
-
console.log(`>>>>>> ${rule} (${what})`);
|
|
139
153
|
try {
|
|
140
154
|
const startTime = Date.now();
|
|
141
155
|
const ruleReport = isJS
|