testaro 12.2.6 → 12.3.2
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/actSpecs.js +6 -0
- package/package.json +1 -1
- package/run.js +4 -2
- package/tests/autocomplete.js +75 -0
- package/tests/ibm.js +13 -4
- package/validation/tests/jobs/autocomplete.json +51 -0
- package/validation/tests/targets/autocomplete/bad.html +20 -0
- package/validation/tests/targets/autocomplete/good.html +22 -0
- package/watch.js +4 -3
package/actSpecs.js
CHANGED
|
@@ -168,6 +168,12 @@ exports.actSpecs = {
|
|
|
168
168
|
withItems: [true, 'boolean', '', 'itemize']
|
|
169
169
|
}
|
|
170
170
|
],
|
|
171
|
+
autocomplete: [
|
|
172
|
+
'Perform an autocomplete test',
|
|
173
|
+
{
|
|
174
|
+
withItems: [true, 'boolean', '', 'itemize']
|
|
175
|
+
}
|
|
176
|
+
],
|
|
171
177
|
axe: [
|
|
172
178
|
'Perform an Axe test',
|
|
173
179
|
{
|
package/package.json
CHANGED
package/run.js
CHANGED
|
@@ -34,6 +34,7 @@ const tests = {
|
|
|
34
34
|
alfa: 'alfa',
|
|
35
35
|
allHidden: 'page that is entirely or mostly hidden',
|
|
36
36
|
attVal: 'elements with attributes having illicit values',
|
|
37
|
+
autocomplete: 'name and email inputs without autocomplete attributes',
|
|
37
38
|
axe: 'Axe',
|
|
38
39
|
bulk: 'count of visible elements',
|
|
39
40
|
continuum: 'Level Access Continuum, community edition',
|
|
@@ -264,8 +265,9 @@ const isValidReport = report => {
|
|
|
264
265
|
if (! acts[1].which || typeof acts[1].which !== 'string' || ! isURL(acts[1].which)) {
|
|
265
266
|
return 'Second act which not a URL';
|
|
266
267
|
}
|
|
267
|
-
|
|
268
|
-
|
|
268
|
+
const invalidAct = acts.find(act => ! isValidAct(act));
|
|
269
|
+
if (invalidAct) {
|
|
270
|
+
return `Invalid act:\n${JSON.stringify(invalidAct, null, 2)}`;
|
|
269
271
|
}
|
|
270
272
|
if (! sources || typeof sources !== 'object') {
|
|
271
273
|
return 'Bad report sources';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
autocomplete
|
|
3
|
+
This test reports failures to equip name and email inputs with correct autocomplete attributes.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ########## IMPORTS
|
|
7
|
+
|
|
8
|
+
// Returns text associated with an element.
|
|
9
|
+
const {allText} = require('../procs/allText');
|
|
10
|
+
|
|
11
|
+
// ########## FUNCTIONS
|
|
12
|
+
|
|
13
|
+
// Adds a failure, if any, to the data.
|
|
14
|
+
const addFailure = async (withItems, input, inputText, autocomplete, data) => {
|
|
15
|
+
// If it does not have the required autocomplete attribute:
|
|
16
|
+
const autoValue = await input.getAttribute('autocomplete');
|
|
17
|
+
if (autoValue !== autocomplete) {
|
|
18
|
+
// Add this to the total.
|
|
19
|
+
data.total++;
|
|
20
|
+
// If itemization is required:
|
|
21
|
+
if (withItems) {
|
|
22
|
+
// Add the item to the data.
|
|
23
|
+
data.items.push([autocomplete, inputText.slice(0, 100)]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
// Reports failures.
|
|
28
|
+
exports.reporter = async (page, withItems) => {
|
|
29
|
+
const data = {total: 0};
|
|
30
|
+
if (withItems) {
|
|
31
|
+
data.items = [];
|
|
32
|
+
}
|
|
33
|
+
// Identify the inputs.
|
|
34
|
+
const inputs = await page.$$('input');
|
|
35
|
+
// If there are any:
|
|
36
|
+
if (inputs.length) {
|
|
37
|
+
// For each one:
|
|
38
|
+
for (const input of inputs) {
|
|
39
|
+
const inputText = await allText(page, input);
|
|
40
|
+
// If it is a text input:
|
|
41
|
+
const inputType = await input.getAttribute('type');
|
|
42
|
+
if (inputType === 'text' || ! inputType) {
|
|
43
|
+
const inputTextLC = inputText.toLowerCase();
|
|
44
|
+
// If it requests a given name:
|
|
45
|
+
if (
|
|
46
|
+
inputTextLC === 'first'
|
|
47
|
+
|| ['first name', 'given name'].some(phrase => inputTextLC.includes(phrase))
|
|
48
|
+
) {
|
|
49
|
+
// Add any failure to the data.
|
|
50
|
+
await addFailure(withItems, input, inputText, 'given-name', data);
|
|
51
|
+
}
|
|
52
|
+
// Otherwise, if it requests a family name:
|
|
53
|
+
else if (
|
|
54
|
+
inputTextLC === 'last'
|
|
55
|
+
|| ['last name', 'family name'].some(phrase => inputTextLC.includes(phrase))
|
|
56
|
+
) {
|
|
57
|
+
// Add any failure to the data.
|
|
58
|
+
await addFailure(withItems, input, inputText, 'family-name', data);
|
|
59
|
+
}
|
|
60
|
+
// Otherwise, if it requests an email address:
|
|
61
|
+
else if (inputTextLC.includes('email')) {
|
|
62
|
+
// Add any failure to the data.
|
|
63
|
+
await addFailure(withItems, input, inputText, 'email', data);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Otherwise, if it is an email input:
|
|
67
|
+
else if (inputType === 'email') {
|
|
68
|
+
// Add any failure to the data.
|
|
69
|
+
await addFailure(withItems, input, inputText, 'email', data);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Return the data.
|
|
74
|
+
return {result: data};
|
|
75
|
+
};
|
package/tests/ibm.js
CHANGED
|
@@ -120,11 +120,20 @@ const doTest = async (content, withItems, timeLimit, rules) => {
|
|
|
120
120
|
};
|
|
121
121
|
// Returns results of one or two IBM tests.
|
|
122
122
|
exports.reporter = async (page, withItems, withNewContent, rules) => {
|
|
123
|
+
let contentType = 'both';
|
|
124
|
+
if (withNewContent) {
|
|
125
|
+
contentType = 'new';
|
|
126
|
+
}
|
|
127
|
+
else if (withNewContent === false) {
|
|
128
|
+
contentType = 'existing';
|
|
129
|
+
}
|
|
130
|
+
console.log(`>>>>>> Content type: ${contentType}`);
|
|
123
131
|
// If a test with existing content is to be performed:
|
|
124
132
|
const result = {};
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
const timeLimit = 20;
|
|
134
|
+
if (['existing', 'both'].includes(contentType)) {
|
|
127
135
|
try {
|
|
136
|
+
console.log('>>>>>> With existing content');
|
|
128
137
|
const typeContent = await page.content();
|
|
129
138
|
result.content = await doTest(typeContent, withItems, timeLimit, rules);
|
|
130
139
|
if (result.content.prevented) {
|
|
@@ -138,9 +147,9 @@ exports.reporter = async (page, withItems, withNewContent, rules) => {
|
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
// If a test with new content is to be performed:
|
|
141
|
-
if ([
|
|
142
|
-
const timeLimit = 20;
|
|
150
|
+
if (['new', 'both'].includes(contentType)) {
|
|
143
151
|
try {
|
|
152
|
+
console.log('>>>>>> With new content');
|
|
144
153
|
const typeContent = page.url();
|
|
145
154
|
result.url = await doTest(typeContent, withItems, timeLimit, rules);
|
|
146
155
|
if (result.url.prevented) {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "autocompleteVal",
|
|
3
|
+
"what": "validation of autocomplete test",
|
|
4
|
+
"strict": true,
|
|
5
|
+
"timeLimit": 20,
|
|
6
|
+
"acts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "launch",
|
|
9
|
+
"which": "chromium",
|
|
10
|
+
"what": "usual browser"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "url",
|
|
14
|
+
"which": "__targets__/autocomplete/good.html",
|
|
15
|
+
"what": "page with correct autocomplete attributes"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "test",
|
|
19
|
+
"which": "autocomplete",
|
|
20
|
+
"what": "autocomplete attributes for name and email",
|
|
21
|
+
"withItems": true,
|
|
22
|
+
"expect": [
|
|
23
|
+
["totals", "=", 0],
|
|
24
|
+
["items.1"]
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "url",
|
|
29
|
+
"which": "__targets__/autocomplete/bad.html",
|
|
30
|
+
"what": "page with incorrect autocomplete attributes"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "test",
|
|
34
|
+
"which": "autocomplete",
|
|
35
|
+
"what": "autocomplete attributes for name and email",
|
|
36
|
+
"withItems": true,
|
|
37
|
+
"expect": [
|
|
38
|
+
["totals", "=", 4],
|
|
39
|
+
["items.1.0", "=", "family-name"],
|
|
40
|
+
["items.2.1", "=", "Your email address"]
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"sources": {
|
|
45
|
+
"script": "",
|
|
46
|
+
"host": {},
|
|
47
|
+
"requester": ""
|
|
48
|
+
},
|
|
49
|
+
"creationTime": "2003-04-16T21:06:00",
|
|
50
|
+
"timeStamp": "00000"
|
|
51
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page with incorrect autocomplete attributes</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page with incorrect autocomplete attributes</h1>
|
|
12
|
+
<p><label>Your first name <input width="40rem" autocomplete="first-name"></label></p>
|
|
13
|
+
<p><label>Your last name <input type="text" width="40rem"></label></p>
|
|
14
|
+
<p><label>Your email address <input width="40rem"></label></p>
|
|
15
|
+
<p><label>
|
|
16
|
+
Your email address again <input type="email" width="40rem" autocomplete="email-address">
|
|
17
|
+
</label></p>
|
|
18
|
+
</main>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Page with correct autocomplete attributes</title>
|
|
6
|
+
<meta name="description" content="tester">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main>
|
|
11
|
+
<h1>Page with correct autocomplete attributes</h1>
|
|
12
|
+
<p><label>Your first name <input width="40rem" autocomplete="given-name"></label></p>
|
|
13
|
+
<p><label>
|
|
14
|
+
Your last name <input type="text" width="40rem" autocomplete="family-name">
|
|
15
|
+
</label></p>
|
|
16
|
+
<p><label>Your email address <input width="40rem" autocomplete="email"></label></p>
|
|
17
|
+
<p><label>
|
|
18
|
+
Your email address again <input type="email" width="40rem" autocomplete="email">
|
|
19
|
+
</label></p>
|
|
20
|
+
</main>
|
|
21
|
+
</body>
|
|
22
|
+
</html>
|
package/watch.js
CHANGED
|
@@ -92,7 +92,7 @@ const checkNetJob = async watchee => {
|
|
|
92
92
|
console.log(job.message);
|
|
93
93
|
}
|
|
94
94
|
else {
|
|
95
|
-
console.log(job);
|
|
95
|
+
console.log('No network job to do');
|
|
96
96
|
}
|
|
97
97
|
return job;
|
|
98
98
|
};
|
|
@@ -138,7 +138,7 @@ const writeNetReport = async report => {
|
|
|
138
138
|
error: 'ERROR: Response was not JSON',
|
|
139
139
|
message: error.message,
|
|
140
140
|
status: response.statusCode,
|
|
141
|
-
content: content.slice(0,
|
|
141
|
+
content: content.slice(0, 3000)
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
144
|
});
|
|
@@ -152,7 +152,8 @@ const writeNetReport = async report => {
|
|
|
152
152
|
});
|
|
153
153
|
});
|
|
154
154
|
// Send the report to the server.
|
|
155
|
-
|
|
155
|
+
const reportJSON = JSON.stringify(report, null, 2);
|
|
156
|
+
request.write(reportJSON);
|
|
156
157
|
request.end();
|
|
157
158
|
console.log(`Report ${report.id} submitted`);
|
|
158
159
|
}
|