testaro 16.0.0 → 16.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/actSpecs.js +1 -1
- package/package.json +1 -1
- package/procs/visChange.js +112 -0
- package/testaro/hover.js +117 -374
- package/testaro/motion.js +43 -132
- package/validation/tests/jobs/hovInd.json +320 -0
- package/validation/tests/jobs/hover.json +89 -143
- package/validation/tests/jobs/motion.json +27 -18
- package/validation/tests/targets/hover/bad.html +10 -9
- package/validation/tests/targets/motion/bad.css +4 -3
- package/procs/getKeyNav.js +0 -40
- /package/validation/tests/targets/{hover → hovInd}/styleBad.html +0 -0
package/testaro/motion.js
CHANGED
|
@@ -4,131 +4,46 @@
|
|
|
4
4
|
brief, or else stoppable by the user. But stopping motion can be difficult or impossible, and,
|
|
5
5
|
by the time a user manages to stop motion, the motion may have caused annoyance or harm. For
|
|
6
6
|
superior accessibility, a page contains no motion until and unless the user authorizes it. The
|
|
7
|
-
test compares screen shots of the
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
screen shots and reports 9 statistics:
|
|
11
|
-
0. bytes: an array of the sizes of the screen shots, in bytes
|
|
12
|
-
1. localRatios: an array of the ratios of bytes of the larger to the smaller of adjacent pairs
|
|
13
|
-
of screen shots
|
|
14
|
-
2. meanLocalRatio: the mean of the ratios in the localRatios array
|
|
15
|
-
3. maxLocalRatio: the greatest of the ratios in the localRatios array
|
|
16
|
-
4. globalRatio: the ratio of bytes of the largest to the smallest screen shot
|
|
17
|
-
5. pixelChanges: an array of counts of differing pixels between adjacent pairs of screen shots
|
|
18
|
-
6. meanPixelChange: the mean of the counts in the pixelChanges array
|
|
19
|
-
7. maxPixelChange: the greatest of the counts in the pixelChanges array
|
|
20
|
-
8. changeFrequency: what fraction of the adjacent pairs of screen shots has pixel differences
|
|
7
|
+
test compares two screen shots of the viewport 2 seconds and 6 seconds after page load. It
|
|
8
|
+
reports a rule violation if any pixels change. The larger the change fraction, the greater the
|
|
9
|
+
ordinal severity.
|
|
21
10
|
|
|
22
|
-
WARNING: This test uses the Playwright page.screenshot method, which
|
|
23
|
-
|
|
24
|
-
browser type usable with this test is webkit.
|
|
11
|
+
WARNING: This test uses the Playwright page.screenshot method, which is not implemented for the
|
|
12
|
+
firefox browser type.
|
|
25
13
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
timeout: 3000
|
|
35
|
-
})
|
|
36
|
-
.catch(error => {
|
|
37
|
-
console.log(`ERROR: Screenshot failed(${error.message})`);
|
|
38
|
-
return '';
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
// Recursively creates and returns screenshots.
|
|
42
|
-
const shootAll = async (page, delay, interval, count, toDo, buffers) => {
|
|
43
|
-
// Wait.
|
|
44
|
-
await page.waitForTimeout(toDo === count ? delay : interval);
|
|
45
|
-
// Make a screenshot.
|
|
46
|
-
const buffer = await shoot(
|
|
47
|
-
page, `${page.url().replace(/^.+\/\/|\/$/g, '').replace(/\//g, '+')}-${count - toDo}`
|
|
48
|
-
);
|
|
49
|
-
// Get its dimensions.
|
|
50
|
-
if (buffer.length) {
|
|
51
|
-
buffers.push(buffer);
|
|
52
|
-
if (toDo > 1) {
|
|
53
|
-
return shootAll(page, delay, interval, count, toDo - 1, buffers);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
return buffers;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
return '';
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
// Returns a number rounded to 2 decimal digits.
|
|
64
|
-
const round = (num, precision) => Number.parseFloat(num.toPrecision(precision));
|
|
14
|
+
|
|
15
|
+
// IMPORTS
|
|
16
|
+
|
|
17
|
+
// Module to get pixel changes between two times.
|
|
18
|
+
const {visChange} = require('../procs/visChange');
|
|
19
|
+
|
|
20
|
+
// FUNCTIONS
|
|
21
|
+
|
|
65
22
|
// Reports motion in a page.
|
|
66
|
-
exports.reporter = async
|
|
67
|
-
//
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const pngs = shots.map(shot => PNG.sync.read(shot));
|
|
86
|
-
// Get their dimensions.
|
|
87
|
-
const {width, height} = pngs[0];
|
|
88
|
-
// Get the counts of differing pixels between adjacent pairs of shots.
|
|
89
|
-
const pixelChanges = pngs
|
|
90
|
-
.slice(1)
|
|
91
|
-
.map((png, index) => pixelmatch(pngs[index].data, png.data, null, width, height));
|
|
92
|
-
// Get the mean and maximum of those counts.
|
|
93
|
-
const meanPixelChange = Math.floor(
|
|
94
|
-
pixelChanges.reduce((sum, currentChange) => sum + currentChange) / pixelChanges.length
|
|
95
|
-
);
|
|
96
|
-
const maxPixelChange = Math.max(...pixelChanges);
|
|
97
|
-
const changeFrequency = round(
|
|
98
|
-
pixelChanges.reduce((count, change) => count + (change ? 1 : 0), 0) / pixelChanges.length, 2
|
|
99
|
-
);
|
|
100
|
-
// Return the result.
|
|
101
|
-
const rawCount = 2 * (meanLocalRatio - 1)
|
|
102
|
-
+ maxLocalRatio - 1
|
|
103
|
-
+ globalRatio - 1
|
|
104
|
-
+ meanPixelChange / 10000
|
|
105
|
-
+ maxPixelChange / 25000
|
|
106
|
-
+ 3 * changeFrequency;
|
|
107
|
-
const count = rawCount ? Math.round(rawCount) : 0;
|
|
108
|
-
return {
|
|
109
|
-
data: {
|
|
110
|
-
bytes,
|
|
111
|
-
localRatios,
|
|
112
|
-
meanLocalRatio,
|
|
113
|
-
maxLocalRatio,
|
|
114
|
-
globalRatio,
|
|
115
|
-
pixelChanges,
|
|
116
|
-
meanPixelChange,
|
|
117
|
-
maxPixelChange,
|
|
118
|
-
changeFrequency
|
|
119
|
-
},
|
|
120
|
-
totals: [
|
|
121
|
-
0,
|
|
122
|
-
0,
|
|
123
|
-
count,
|
|
124
|
-
0
|
|
125
|
-
],
|
|
126
|
-
standardInstances: count ? [{
|
|
23
|
+
exports.reporter = async page => {
|
|
24
|
+
// Initialize the totals and standard instances.
|
|
25
|
+
const totals = [0, 0, 0, 0];
|
|
26
|
+
const standardInstances = [];
|
|
27
|
+
// Make screenshots and get the result.
|
|
28
|
+
const data = await visChange(page, {
|
|
29
|
+
delayBefore: 2000,
|
|
30
|
+
delayBetween: 3000
|
|
31
|
+
});
|
|
32
|
+
// If the screenshots succeeded:
|
|
33
|
+
if (data.success) {
|
|
34
|
+
// If any pixels were changed:
|
|
35
|
+
if (data.pixelChanges) {
|
|
36
|
+
// Get the ordinal severity from the fractional pixel change.
|
|
37
|
+
const ordinalSeverity = Math.floor(Math.min(3, 0.4 * Math.sqrt(data.changePercent)));
|
|
38
|
+
// Add to the totals.
|
|
39
|
+
totals[ordinalSeverity] = 1;
|
|
40
|
+
// Get a summary standard instance.
|
|
41
|
+
standardInstances.push({
|
|
127
42
|
ruleID: 'motion',
|
|
128
43
|
what: 'Content moves or changes without user request',
|
|
129
|
-
count,
|
|
130
|
-
ordinalSeverity
|
|
131
|
-
tagName: '',
|
|
44
|
+
count: 1,
|
|
45
|
+
ordinalSeverity,
|
|
46
|
+
tagName: 'HTML',
|
|
132
47
|
id: '',
|
|
133
48
|
location: {
|
|
134
49
|
doc: '',
|
|
@@ -136,17 +51,13 @@ exports.reporter = async (page, withItems, delay = 2500, interval = 2500, count
|
|
|
136
51
|
spec: ''
|
|
137
52
|
},
|
|
138
53
|
excerpt: ''
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// Otherwise, i.e. if the shooting failed:
|
|
143
|
-
else {
|
|
144
|
-
// Return failure.
|
|
145
|
-
return {
|
|
146
|
-
data: {
|
|
147
|
-
prevented: true,
|
|
148
|
-
error: 'ERROR: screenshots failed'
|
|
149
|
-
}
|
|
150
|
-
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
151
56
|
}
|
|
57
|
+
// Return the result.
|
|
58
|
+
return {
|
|
59
|
+
data,
|
|
60
|
+
totals,
|
|
61
|
+
standardInstances
|
|
62
|
+
};
|
|
152
63
|
};
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "hover",
|
|
3
|
+
"what": "validation of hover test",
|
|
4
|
+
"strict": true,
|
|
5
|
+
"timeLimit": 40,
|
|
6
|
+
"acts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "launch",
|
|
9
|
+
"which": "webkit",
|
|
10
|
+
"what": "only compatible browser"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "url",
|
|
14
|
+
"which": "__targets__/hover/good.html",
|
|
15
|
+
"what": "page with standard hover behavior"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "test",
|
|
19
|
+
"which": "testaro",
|
|
20
|
+
"withItems": true,
|
|
21
|
+
"expect": [
|
|
22
|
+
[
|
|
23
|
+
"standardResult.totals.0",
|
|
24
|
+
"=",
|
|
25
|
+
0
|
|
26
|
+
],
|
|
27
|
+
[
|
|
28
|
+
"standardResult.totals.2",
|
|
29
|
+
"=",
|
|
30
|
+
0
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
"standardResult.instances.length",
|
|
34
|
+
"=",
|
|
35
|
+
0
|
|
36
|
+
]
|
|
37
|
+
],
|
|
38
|
+
"rules": [
|
|
39
|
+
"y",
|
|
40
|
+
"hover"
|
|
41
|
+
],
|
|
42
|
+
"args": {
|
|
43
|
+
"hover": [5]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "url",
|
|
48
|
+
"which": "__targets__/hover/bad.html",
|
|
49
|
+
"what": "page with deviant hover behavior"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "test",
|
|
53
|
+
"which": "testaro",
|
|
54
|
+
"withItems": true,
|
|
55
|
+
"expect": [
|
|
56
|
+
[
|
|
57
|
+
"standardResult.totals.3",
|
|
58
|
+
">",
|
|
59
|
+
0
|
|
60
|
+
],
|
|
61
|
+
[
|
|
62
|
+
"standardResult.instances.0.ruleID",
|
|
63
|
+
"=",
|
|
64
|
+
"hover"
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
"standardResult.instances.0.what",
|
|
68
|
+
"i",
|
|
69
|
+
"over the element"
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"standardResult.instances.0.tagName",
|
|
73
|
+
"=",
|
|
74
|
+
"A"
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
"standardResult.instances.0.location.doc",
|
|
78
|
+
"=",
|
|
79
|
+
"dom"
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"standardResult.instances.0.location.type",
|
|
83
|
+
"=",
|
|
84
|
+
"box"
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"standardResult.instances.0.location.spec.height",
|
|
88
|
+
"<",
|
|
89
|
+
"20"
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
"standardResult.instances.0.excerpt",
|
|
93
|
+
"i",
|
|
94
|
+
"Trigger 1"
|
|
95
|
+
],
|
|
96
|
+
[
|
|
97
|
+
"standardResult.instances.2.what",
|
|
98
|
+
"i",
|
|
99
|
+
"is not hoverable"
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"standardResult.instances.2.ordinalSeverity",
|
|
103
|
+
"=",
|
|
104
|
+
3
|
|
105
|
+
],
|
|
106
|
+
[
|
|
107
|
+
"standardResult.instances.2.tagName",
|
|
108
|
+
"=",
|
|
109
|
+
"BUTTON"
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
"standardResult.instances.2.id",
|
|
113
|
+
"=",
|
|
114
|
+
"smallButton"
|
|
115
|
+
],
|
|
116
|
+
[
|
|
117
|
+
"standardResult.instances.0.location.doc",
|
|
118
|
+
"=",
|
|
119
|
+
"dom"
|
|
120
|
+
],
|
|
121
|
+
[
|
|
122
|
+
"standardResult.instances.0.location.type",
|
|
123
|
+
"=",
|
|
124
|
+
"selector"
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
"standardResult.instances.0.location.spec",
|
|
128
|
+
"=",
|
|
129
|
+
"#smallButton"
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
"standardResult.instances.2.excerpt",
|
|
133
|
+
"i",
|
|
134
|
+
"Trigger 3"
|
|
135
|
+
]
|
|
136
|
+
],
|
|
137
|
+
"rules": [
|
|
138
|
+
"y",
|
|
139
|
+
"hover"
|
|
140
|
+
],
|
|
141
|
+
"args": {
|
|
142
|
+
"hover": [6]
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"type": "test",
|
|
147
|
+
"which": "testaro",
|
|
148
|
+
"withItems": false,
|
|
149
|
+
"expect": [
|
|
150
|
+
[
|
|
151
|
+
"standardResult.totals.3",
|
|
152
|
+
">",
|
|
153
|
+
0
|
|
154
|
+
],
|
|
155
|
+
[
|
|
156
|
+
"standardResult.instances.length",
|
|
157
|
+
">",
|
|
158
|
+
0
|
|
159
|
+
],
|
|
160
|
+
[
|
|
161
|
+
"standardResult.instances.0.ruleID",
|
|
162
|
+
"=",
|
|
163
|
+
"hover"
|
|
164
|
+
],
|
|
165
|
+
[
|
|
166
|
+
"standardResult.instances.0.what",
|
|
167
|
+
"i",
|
|
168
|
+
"over elements"
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
"standardResult.instances.0.ordinalSeverity",
|
|
172
|
+
">",
|
|
173
|
+
-1
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
"standardResult.instances.0.count",
|
|
177
|
+
">",
|
|
178
|
+
0
|
|
179
|
+
]
|
|
180
|
+
],
|
|
181
|
+
"rules": [
|
|
182
|
+
"y",
|
|
183
|
+
"hover"
|
|
184
|
+
],
|
|
185
|
+
"args": {
|
|
186
|
+
"hover": [6]
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"type": "test",
|
|
191
|
+
"which": "testaro",
|
|
192
|
+
"withItems": false,
|
|
193
|
+
"expect": [
|
|
194
|
+
[
|
|
195
|
+
"standardResult.totals.3",
|
|
196
|
+
"<",
|
|
197
|
+
7
|
|
198
|
+
],
|
|
199
|
+
[
|
|
200
|
+
"standardResult.totals.2",
|
|
201
|
+
"<",
|
|
202
|
+
4
|
|
203
|
+
],
|
|
204
|
+
[
|
|
205
|
+
"standardResult.totals.1",
|
|
206
|
+
"<",
|
|
207
|
+
13
|
|
208
|
+
],
|
|
209
|
+
[
|
|
210
|
+
"standardResult.totals.0",
|
|
211
|
+
"<",
|
|
212
|
+
4
|
|
213
|
+
]
|
|
214
|
+
],
|
|
215
|
+
"rules": [
|
|
216
|
+
"y",
|
|
217
|
+
"hover"
|
|
218
|
+
],
|
|
219
|
+
"args": {
|
|
220
|
+
"hover": [2]
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"type": "url",
|
|
225
|
+
"which": "__targets__/hover/styleBad.html",
|
|
226
|
+
"what": "page with deviant trigger styles"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"type": "test",
|
|
230
|
+
"which": "testaro",
|
|
231
|
+
"withItems": true,
|
|
232
|
+
"expect": [
|
|
233
|
+
[
|
|
234
|
+
"standardResult.totals.1",
|
|
235
|
+
"=",
|
|
236
|
+
0
|
|
237
|
+
],
|
|
238
|
+
[
|
|
239
|
+
"standardResult.totals.2",
|
|
240
|
+
"=",
|
|
241
|
+
2
|
|
242
|
+
],
|
|
243
|
+
[
|
|
244
|
+
"standardResult.totals.3",
|
|
245
|
+
"=",
|
|
246
|
+
1
|
|
247
|
+
],
|
|
248
|
+
[
|
|
249
|
+
"standardResult.instances.0.ruleID",
|
|
250
|
+
"=",
|
|
251
|
+
"hover"
|
|
252
|
+
],
|
|
253
|
+
[
|
|
254
|
+
"standardResult.instances.0.what",
|
|
255
|
+
"i",
|
|
256
|
+
"hides"
|
|
257
|
+
],
|
|
258
|
+
[
|
|
259
|
+
"standardResult.instances.0.tagName",
|
|
260
|
+
"=",
|
|
261
|
+
"LI"
|
|
262
|
+
],
|
|
263
|
+
[
|
|
264
|
+
"standardResult.instances.0.ordinalSeverity",
|
|
265
|
+
"=",
|
|
266
|
+
3
|
|
267
|
+
],
|
|
268
|
+
[
|
|
269
|
+
"standardResult.instances.0.excerpt",
|
|
270
|
+
"i",
|
|
271
|
+
"loses its cursor"
|
|
272
|
+
],
|
|
273
|
+
[
|
|
274
|
+
"standardResult.instances.1.ruleID",
|
|
275
|
+
"=",
|
|
276
|
+
"hover"
|
|
277
|
+
],
|
|
278
|
+
[
|
|
279
|
+
"standardResult.instances.1.what",
|
|
280
|
+
"i",
|
|
281
|
+
"cursor nonstandard"
|
|
282
|
+
],
|
|
283
|
+
[
|
|
284
|
+
"standardResult.instances.1.tagName",
|
|
285
|
+
"=",
|
|
286
|
+
"A"
|
|
287
|
+
],
|
|
288
|
+
[
|
|
289
|
+
"standardResult.instances.1.id",
|
|
290
|
+
"=",
|
|
291
|
+
"trigger1"
|
|
292
|
+
],
|
|
293
|
+
[
|
|
294
|
+
"standardResult.instances.1.ordinalSeverity",
|
|
295
|
+
"=",
|
|
296
|
+
2
|
|
297
|
+
],
|
|
298
|
+
[
|
|
299
|
+
"standardResult.instances.1.excerpt",
|
|
300
|
+
"i",
|
|
301
|
+
"Trigger 1"
|
|
302
|
+
]
|
|
303
|
+
],
|
|
304
|
+
"rules": [
|
|
305
|
+
"y",
|
|
306
|
+
"hover"
|
|
307
|
+
],
|
|
308
|
+
"args": {
|
|
309
|
+
"hover": [4]
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
],
|
|
313
|
+
"sources": {
|
|
314
|
+
"script": "",
|
|
315
|
+
"host": {},
|
|
316
|
+
"requester": ""
|
|
317
|
+
},
|
|
318
|
+
"creationTime": "2013-05-28T12:00:00",
|
|
319
|
+
"timeStamp": "00000"
|
|
320
|
+
}
|