testaro 56.0.0 → 57.1.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/package.json +1 -1
- package/procs/isInlineLink.js +1 -2
- package/run.js +44 -41
- package/testaro/hovInd.js +23 -23
- package/testaro/role.js +12 -3
- package/testaro/targetSmall.js +4 -3
- package/testaro/targetTiny.js +3 -2
- package/validation/tests/jobProperties/focInd.json +14 -14
- package/validation/tests/jobProperties/hovInd.json +1 -1
- package/validation/tests/jobProperties/role.json +14 -29
- package/validation/tests/jobProperties/{targetSize.json → targetSmall.json} +18 -18
- package/validation/tests/jobProperties/targetTiny.json +142 -0
- package/validation/tests/targets/focInd/bad.html +9 -9
- package/validation/tests/targets/hovInd/index.html +13 -11
- package/validation/tests/targets/role/bad.html +16 -20
- package/validation/tests/targets/targetSize/index.html +30 -19
- package/validation/validateTest.js +3 -1
package/package.json
CHANGED
package/procs/isInlineLink.js
CHANGED
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
/*
|
|
26
26
|
isInlineLink
|
|
27
27
|
Returns whether the link of a locator is inline.
|
|
28
|
-
A link is classified as inline unless
|
|
29
|
-
with no other nonspacing text content.
|
|
28
|
+
A link is classified as inline unless its declared or effective display is block.
|
|
30
29
|
*/
|
|
31
30
|
|
|
32
31
|
exports.isInlineLink = async loc => await loc.evaluate(element => {
|
package/run.js
CHANGED
|
@@ -686,50 +686,53 @@ const doActs = async (report) => {
|
|
|
686
686
|
const {toolTimes} = report.jobData;
|
|
687
687
|
toolTimes[act.which] ??= 0;
|
|
688
688
|
toolTimes[act.which] += time;
|
|
689
|
-
// If the act was not prevented
|
|
690
|
-
if (
|
|
691
|
-
//
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
standardize(act);
|
|
698
|
-
// Launch a browser and navigate to the page.
|
|
699
|
-
await launch(
|
|
700
|
-
report,
|
|
701
|
-
debug,
|
|
702
|
-
waits,
|
|
703
|
-
act.browserID || report.browserID || '',
|
|
704
|
-
act.target && act.target.url || report.target && report.target.url || ''
|
|
705
|
-
);
|
|
706
|
-
// If this failed:
|
|
707
|
-
if (page.prevented) {
|
|
708
|
-
// Add this to the act.
|
|
709
|
-
act.prevented = true;
|
|
710
|
-
act.error = page.error || '';
|
|
711
|
-
}
|
|
712
|
-
// Otherwise, i.e. if it succeeded:
|
|
713
|
-
else {
|
|
714
|
-
// Add a box ID and a path ID to each of its standard instances if missing.
|
|
715
|
-
for (const instance of act.standardResult.instances) {
|
|
716
|
-
const elementID = await identify(instance, page);
|
|
717
|
-
if (! instance.boxID) {
|
|
718
|
-
instance.boxID = elementID ? elementID.boxID : '';
|
|
719
|
-
}
|
|
720
|
-
if (! instance.pathID) {
|
|
721
|
-
instance.pathID = elementID ? elementID.pathID : '';
|
|
722
|
-
}
|
|
689
|
+
// If the act was not prevented:
|
|
690
|
+
if (act.data && ! act.data.prevented) {
|
|
691
|
+
// If standardization is required:
|
|
692
|
+
if (['also', 'only'].includes(standard)) {
|
|
693
|
+
// Initialize the standard result.
|
|
694
|
+
act.standardResult = {
|
|
695
|
+
totals: [0, 0, 0, 0],
|
|
696
|
+
instances: []
|
|
723
697
|
};
|
|
698
|
+
// Populate it.
|
|
699
|
+
standardize(act);
|
|
700
|
+
// Launch a browser and navigate to the page.
|
|
701
|
+
await launch(
|
|
702
|
+
report,
|
|
703
|
+
debug,
|
|
704
|
+
waits,
|
|
705
|
+
act.browserID || report.browserID || '',
|
|
706
|
+
act.target && act.target.url || report.target && report.target.url || ''
|
|
707
|
+
);
|
|
708
|
+
// If this failed:
|
|
709
|
+
if (page.prevented) {
|
|
710
|
+
// Add this to the act.
|
|
711
|
+
act.prevented = true;
|
|
712
|
+
act.error = page.error || '';
|
|
713
|
+
}
|
|
714
|
+
// Otherwise, i.e. if it succeeded:
|
|
715
|
+
else {
|
|
716
|
+
// Add a box ID and a path ID to each of its standard instances if missing.
|
|
717
|
+
for (const instance of act.standardResult.instances) {
|
|
718
|
+
const elementID = await identify(instance, page);
|
|
719
|
+
if (! instance.boxID) {
|
|
720
|
+
instance.boxID = elementID ? elementID.boxID : '';
|
|
721
|
+
}
|
|
722
|
+
if (! instance.pathID) {
|
|
723
|
+
instance.pathID = elementID ? elementID.pathID : '';
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
// If the original-format result is not to be included in the report:
|
|
728
|
+
if (standard === 'only') {
|
|
729
|
+
// Remove it.
|
|
730
|
+
delete act.result;
|
|
731
|
+
}
|
|
724
732
|
}
|
|
725
|
-
// If the
|
|
726
|
-
if (standard === 'only') {
|
|
727
|
-
// Remove it.
|
|
728
|
-
delete act.result;
|
|
729
|
-
}
|
|
733
|
+
// If the act has expectations:
|
|
730
734
|
const expectations = act.expect;
|
|
731
|
-
|
|
732
|
-
if (expectations && act.data && ! act.data.prevented) {
|
|
735
|
+
if (expectations) {
|
|
733
736
|
// Initialize whether they were fulfilled.
|
|
734
737
|
act.expectations = [];
|
|
735
738
|
let failureCount = 0;
|
package/testaro/hovInd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
2
|
+
© 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
3
|
|
|
4
4
|
MIT License
|
|
5
5
|
|
|
@@ -64,6 +64,7 @@ const getHoverStyles = async loc => await loc.evaluate(element => {
|
|
|
64
64
|
outlineStyle,
|
|
65
65
|
outlineWidth,
|
|
66
66
|
outlineOffset,
|
|
67
|
+
color,
|
|
67
68
|
backgroundColor
|
|
68
69
|
} = window.getComputedStyle(element);
|
|
69
70
|
return {
|
|
@@ -72,6 +73,7 @@ const getHoverStyles = async loc => await loc.evaluate(element => {
|
|
|
72
73
|
cursor: cursor.replace(/^.+, */, ''),
|
|
73
74
|
border: `${borderColor} ${borderStyle} ${borderWidth}`,
|
|
74
75
|
outline: `${outlineColor} ${outlineStyle} ${outlineWidth} ${outlineOffset}`,
|
|
76
|
+
color,
|
|
75
77
|
backgroundColor
|
|
76
78
|
};
|
|
77
79
|
});
|
|
@@ -109,7 +111,7 @@ const getCursorData = hovStyles => {
|
|
|
109
111
|
// Returns whether two hover styles are effectively identical.
|
|
110
112
|
const areAlike = (styles0, styles1) => {
|
|
111
113
|
// Return whether they are effectively identical.
|
|
112
|
-
const areAlike = ['
|
|
114
|
+
const areAlike = ['backgroundColor', 'border', 'color', 'outline']
|
|
113
115
|
.every(style => styles1[style] === styles0[style]);
|
|
114
116
|
return areAlike;
|
|
115
117
|
};
|
|
@@ -144,18 +146,16 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
144
146
|
await loc.focus({timeout: 500});
|
|
145
147
|
// If focusing succeeds, get its style properties.
|
|
146
148
|
const focStyles = await getHoverStyles(loc);
|
|
147
|
-
// Try to
|
|
149
|
+
// Try to blur it.
|
|
148
150
|
try {
|
|
149
|
-
await loc.
|
|
150
|
-
// If
|
|
151
|
-
const fhStyles = await getHoverStyles(loc);
|
|
152
|
-
// Try to blur it.
|
|
151
|
+
await loc.blur({timeout: 500});
|
|
152
|
+
// If blurring succeeds, try to hover over it.
|
|
153
153
|
try {
|
|
154
|
-
await loc.
|
|
155
|
-
// If
|
|
154
|
+
await loc.hover({timeout: 500});
|
|
155
|
+
// If hovering succeeds, get its style properties.
|
|
156
156
|
const hovStyles = await getHoverStyles(loc);
|
|
157
|
-
// If all
|
|
158
|
-
if ([focStyles,
|
|
157
|
+
// If all 3 style declarations belong to the same element:
|
|
158
|
+
if ([focStyles, hovStyles].every(style => style.code === preStyles.code)) {
|
|
159
159
|
// Get data on the element if itemization is required.
|
|
160
160
|
const elData = withItems ? await getLocatorData(loc) : null;
|
|
161
161
|
// If the hover cursor is nonstandard:
|
|
@@ -188,7 +188,7 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
188
188
|
// Add an instance to the result.
|
|
189
189
|
standardInstances.push({
|
|
190
190
|
ruleID: 'hovInd',
|
|
191
|
-
what: 'Element border, outline, and background color do not change when hovered over',
|
|
191
|
+
what: 'Element border, outline, color, and background color do not change when hovered over',
|
|
192
192
|
ordinalSeverity: 1,
|
|
193
193
|
tagName: elData.tagName,
|
|
194
194
|
id: elData.id,
|
|
@@ -197,7 +197,7 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
197
197
|
});
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
// If the hover and focus
|
|
200
|
+
// If the hover and focus states are indistinct but differ from the default state:
|
|
201
201
|
if (areAlike(hovStyles, focStyles) && ! areAlike(hovStyles, preStyles)) {
|
|
202
202
|
// Add to the totals.
|
|
203
203
|
totals[1] += psRatio;
|
|
@@ -207,7 +207,7 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
207
207
|
// Add an instance to the result.
|
|
208
208
|
standardInstances.push({
|
|
209
209
|
ruleID: 'hovInd',
|
|
210
|
-
what: 'Element border, outline, and background color are alike on hover and focus',
|
|
210
|
+
what: 'Element border, outline, color, and background color are alike on hover and focus',
|
|
211
211
|
ordinalSeverity: 1,
|
|
212
212
|
tagName: elData.tagName,
|
|
213
213
|
id: elData.id,
|
|
@@ -225,19 +225,19 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
225
225
|
break;
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
|
-
// If
|
|
228
|
+
// If hovering fails:
|
|
229
229
|
catch(error) {
|
|
230
230
|
// Report this.
|
|
231
231
|
data.prevented = true;
|
|
232
|
-
data.error = 'ERROR:
|
|
232
|
+
data.error = 'ERROR: Hovering failed';
|
|
233
233
|
break;
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
-
// If
|
|
236
|
+
// If blurring fails:
|
|
237
237
|
catch(error) {
|
|
238
238
|
// Report this.
|
|
239
239
|
data.prevented = true;
|
|
240
|
-
data.error = 'ERROR:
|
|
240
|
+
data.error = 'ERROR: Blurring failed';
|
|
241
241
|
break;
|
|
242
242
|
}
|
|
243
243
|
}
|
|
@@ -245,7 +245,7 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
245
245
|
catch(error) {
|
|
246
246
|
// Report this.
|
|
247
247
|
data.prevented = true;
|
|
248
|
-
data.error = 'ERROR:
|
|
248
|
+
data.error = 'ERROR: Focusing failed';
|
|
249
249
|
break;
|
|
250
250
|
}
|
|
251
251
|
}
|
|
@@ -294,14 +294,14 @@ exports.reporter = async (page, withItems, sampleSize = 20) => {
|
|
|
294
294
|
excerpt: ''
|
|
295
295
|
});
|
|
296
296
|
}
|
|
297
|
-
// If any triggers have
|
|
298
|
-
if (data.typeTotals.
|
|
297
|
+
// If any triggers have hover styles not distinct from their focus styles:
|
|
298
|
+
if (data.typeTotals.hoverLikeFocus) {
|
|
299
299
|
// Add a summary instance to the result.
|
|
300
300
|
standardInstances.push({
|
|
301
301
|
ruleID: 'hovInd',
|
|
302
|
-
what: 'Element borders, outlines, and background colors on focus
|
|
302
|
+
what: 'Element borders, outlines, and background colors on focus and on hover do not differ',
|
|
303
303
|
ordinalSeverity: 1,
|
|
304
|
-
count: data.typeTotals.
|
|
304
|
+
count: data.typeTotals.hoverLikeFocus,
|
|
305
305
|
tagName: '',
|
|
306
306
|
id: '',
|
|
307
307
|
location: {
|
package/testaro/role.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
© 2021–
|
|
2
|
+
© 2021–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
3
|
|
|
4
4
|
MIT License
|
|
5
5
|
|
|
@@ -47,8 +47,17 @@ const {init, report} = require('../procs/testaro');
|
|
|
47
47
|
dt: 'term',
|
|
48
48
|
fieldset: 'group',
|
|
49
49
|
figure: 'figure',
|
|
50
|
+
h1: 'heading',
|
|
51
|
+
h2: 'heading',
|
|
52
|
+
h3: 'heading',
|
|
53
|
+
h4: 'heading',
|
|
54
|
+
h5: 'heading',
|
|
55
|
+
h6: 'heading',
|
|
50
56
|
hr: 'separator',
|
|
51
57
|
html: 'document',
|
|
58
|
+
'input[type=number]': 'spinbutton',
|
|
59
|
+
'input[type=text]': 'textbox',
|
|
60
|
+
'input[type=text, list]': 'combobox',
|
|
52
61
|
li: 'listitem',
|
|
53
62
|
main: 'main',
|
|
54
63
|
math: 'math',
|
|
@@ -79,7 +88,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
79
88
|
for (const loc of all.allLocs) {
|
|
80
89
|
// Get the explicit role of the element.
|
|
81
90
|
const role = await loc.getAttribute('role');
|
|
82
|
-
// If it is implicit:
|
|
91
|
+
// If it is also implicit:
|
|
83
92
|
if (implicitRoles.has(role)) {
|
|
84
93
|
// Add the locator to the array of violators.
|
|
85
94
|
all.locs.push([loc, role]);
|
|
@@ -87,7 +96,7 @@ exports.reporter = async (page, withItems) => {
|
|
|
87
96
|
}
|
|
88
97
|
// Populate and return the result.
|
|
89
98
|
const whats = [
|
|
90
|
-
'Element has an explicit __param__ role,
|
|
99
|
+
'Element has an explicit __param__ role, which is also an implicit HTML element role',
|
|
91
100
|
'Elements have roles assigned that are also implicit roles of HTML elements'
|
|
92
101
|
];
|
|
93
102
|
return await report(withItems, all, 'role', whats, 0);
|
package/testaro/targetSmall.js
CHANGED
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
/*
|
|
26
26
|
targetSmall
|
|
27
27
|
Related to Tenon rule 152, but stricter.
|
|
28
|
-
This test reports buttons, inputs, and non-inline links with widths or heights smaller
|
|
28
|
+
This test reports visible buttons, inputs, and non-inline links with widths or heights smaller
|
|
29
|
+
than 44 pixels.
|
|
29
30
|
*/
|
|
30
31
|
|
|
31
32
|
// ########## IMPORTS
|
|
@@ -40,7 +41,7 @@ const {isTooSmall} = require('../procs/target');
|
|
|
40
41
|
// Runs the test and returns the result.
|
|
41
42
|
exports.reporter = async (page, withItems) => {
|
|
42
43
|
// Initialize the locators and result.
|
|
43
|
-
const all = await init(100, page, 'a, button, input');
|
|
44
|
+
const all = await init(100, page, 'a:visible, button:visible, input:visible');
|
|
44
45
|
// For each locator:
|
|
45
46
|
for (const loc of all.allLocs) {
|
|
46
47
|
// Get data on it if illicitly small.
|
|
@@ -56,5 +57,5 @@ exports.reporter = async (page, withItems) => {
|
|
|
56
57
|
'Interactive element pixel size (__param__) is less than 44 by 44',
|
|
57
58
|
'Interactive elements are smaller than 44 pixels wide and high'
|
|
58
59
|
];
|
|
59
|
-
return await report(withItems, all, 'targetSmall', whats,
|
|
60
|
+
return await report(withItems, all, 'targetSmall', whats, 0);
|
|
60
61
|
};
|
package/testaro/targetTiny.js
CHANGED
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
/*
|
|
26
26
|
targetTiny
|
|
27
27
|
Related to Tenon rule 152.
|
|
28
|
-
This test reports buttons, inputs, and non-inline links with widths or heights smaller
|
|
28
|
+
This test reports visible buttons, inputs, and non-inline links with widths or heights smaller
|
|
29
|
+
than 24 pixels.
|
|
29
30
|
*/
|
|
30
31
|
|
|
31
32
|
// ########## IMPORTS
|
|
@@ -40,7 +41,7 @@ const {isTooSmall} = require('../procs/target');
|
|
|
40
41
|
// Runs the test and returns the result.
|
|
41
42
|
exports.reporter = async (page, withItems) => {
|
|
42
43
|
// Initialize the locators and result.
|
|
43
|
-
const all = await init(100, page, 'a, button, input');
|
|
44
|
+
const all = await init(100, page, 'a:visible, button:visible, input:visible');
|
|
44
45
|
// For each locator:
|
|
45
46
|
for (const loc of all.allLocs) {
|
|
46
47
|
// Get data on it if illicitly small.
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
[
|
|
52
52
|
"standardResult.totals.1",
|
|
53
53
|
"=",
|
|
54
|
-
|
|
54
|
+
7
|
|
55
55
|
],
|
|
56
56
|
[
|
|
57
57
|
"standardResult.totals.3",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
[
|
|
67
67
|
"standardResult.instances.0.tagName",
|
|
68
68
|
"=",
|
|
69
|
-
"
|
|
69
|
+
"INPUT"
|
|
70
70
|
],
|
|
71
71
|
[
|
|
72
72
|
"standardResult.instances.0.location.doc",
|
|
@@ -76,40 +76,40 @@
|
|
|
76
76
|
[
|
|
77
77
|
"standardResult.instances.0.location.type",
|
|
78
78
|
"=",
|
|
79
|
-
"
|
|
79
|
+
"selector"
|
|
80
80
|
],
|
|
81
81
|
[
|
|
82
|
-
"standardResult.instances.0.location.spec
|
|
83
|
-
"
|
|
84
|
-
|
|
82
|
+
"standardResult.instances.0.location.spec",
|
|
83
|
+
"=",
|
|
84
|
+
"#textInput"
|
|
85
85
|
],
|
|
86
86
|
[
|
|
87
87
|
"standardResult.instances.0.excerpt",
|
|
88
88
|
"i",
|
|
89
|
-
"
|
|
89
|
+
"narrative"
|
|
90
90
|
],
|
|
91
91
|
[
|
|
92
|
-
"standardResult.instances.
|
|
92
|
+
"standardResult.instances.2.ruleID",
|
|
93
93
|
"=",
|
|
94
94
|
"focInd"
|
|
95
95
|
],
|
|
96
96
|
[
|
|
97
|
-
"standardResult.instances.
|
|
97
|
+
"standardResult.instances.2.ordinalSeverity",
|
|
98
98
|
"=",
|
|
99
99
|
1
|
|
100
100
|
],
|
|
101
101
|
[
|
|
102
|
-
"standardResult.instances.
|
|
102
|
+
"standardResult.instances.2.tagName",
|
|
103
103
|
"=",
|
|
104
104
|
"INPUT"
|
|
105
105
|
],
|
|
106
106
|
[
|
|
107
|
-
"standardResult.instances.
|
|
107
|
+
"standardResult.instances.2.id",
|
|
108
108
|
"=",
|
|
109
109
|
"thickOutlineInput"
|
|
110
110
|
],
|
|
111
111
|
[
|
|
112
|
-
"standardResult.instances.
|
|
112
|
+
"standardResult.instances.2.location.spec",
|
|
113
113
|
"=",
|
|
114
114
|
"#thickOutlineInput"
|
|
115
115
|
]
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
[
|
|
129
129
|
"standardResult.totals.1",
|
|
130
130
|
"=",
|
|
131
|
-
|
|
131
|
+
7
|
|
132
132
|
],
|
|
133
133
|
[
|
|
134
134
|
"standardResult.totals.0",
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
[
|
|
149
149
|
"standardResult.instances.0.count",
|
|
150
150
|
"=",
|
|
151
|
-
|
|
151
|
+
7
|
|
152
152
|
],
|
|
153
153
|
[
|
|
154
154
|
"standardResult.instances.0.what",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"stopOnFail": true,
|
|
48
48
|
"expect": [
|
|
49
49
|
[
|
|
50
|
-
"standardResult.totals.
|
|
50
|
+
"standardResult.totals.0",
|
|
51
51
|
"=",
|
|
52
|
-
|
|
52
|
+
8
|
|
53
53
|
],
|
|
54
54
|
[
|
|
55
55
|
"standardResult.totals.3",
|
|
56
56
|
"=",
|
|
57
|
-
|
|
57
|
+
0
|
|
58
58
|
],
|
|
59
59
|
[
|
|
60
60
|
"standardResult.instances.1.ruleID",
|
|
@@ -64,22 +64,17 @@
|
|
|
64
64
|
[
|
|
65
65
|
"standardResult.instances.1.what",
|
|
66
66
|
"i",
|
|
67
|
-
"
|
|
67
|
+
"which is also an implicit"
|
|
68
68
|
],
|
|
69
69
|
[
|
|
70
70
|
"standardResult.instances.1.ordinalSeverity",
|
|
71
71
|
"=",
|
|
72
|
-
|
|
73
|
-
],
|
|
74
|
-
[
|
|
75
|
-
"standardResult.instances.1.count",
|
|
76
|
-
"=",
|
|
77
|
-
1
|
|
72
|
+
0
|
|
78
73
|
],
|
|
79
74
|
[
|
|
80
75
|
"standardResult.instances.1.tagName",
|
|
81
76
|
"=",
|
|
82
|
-
"
|
|
77
|
+
"H2"
|
|
83
78
|
],
|
|
84
79
|
[
|
|
85
80
|
"standardResult.instances.2.ruleID",
|
|
@@ -89,37 +84,27 @@
|
|
|
89
84
|
[
|
|
90
85
|
"standardResult.instances.2.what",
|
|
91
86
|
"i",
|
|
92
|
-
"
|
|
87
|
+
"which is also an implicit"
|
|
93
88
|
],
|
|
94
89
|
[
|
|
95
90
|
"standardResult.instances.2.ordinalSeverity",
|
|
96
91
|
"=",
|
|
97
|
-
|
|
98
|
-
],
|
|
99
|
-
[
|
|
100
|
-
"standardResult.instances.2.count",
|
|
101
|
-
"=",
|
|
102
|
-
1
|
|
92
|
+
0
|
|
103
93
|
],
|
|
104
94
|
[
|
|
105
95
|
"standardResult.instances.2.tagName",
|
|
106
96
|
"=",
|
|
107
|
-
"
|
|
97
|
+
"H3"
|
|
108
98
|
],
|
|
109
99
|
[
|
|
110
100
|
"standardResult.instances.4.what",
|
|
111
101
|
"i",
|
|
112
|
-
"
|
|
102
|
+
"which is also an implicit"
|
|
113
103
|
],
|
|
114
104
|
[
|
|
115
105
|
"standardResult.instances.4.ordinalSeverity",
|
|
116
106
|
"=",
|
|
117
|
-
|
|
118
|
-
],
|
|
119
|
-
[
|
|
120
|
-
"standardResult.instances.4.count",
|
|
121
|
-
"=",
|
|
122
|
-
2
|
|
107
|
+
0
|
|
123
108
|
],
|
|
124
109
|
[
|
|
125
110
|
"standardResult.instances.4.tagName",
|
|
@@ -127,14 +112,14 @@
|
|
|
127
112
|
"H3"
|
|
128
113
|
],
|
|
129
114
|
[
|
|
130
|
-
"standardResult.instances.7.
|
|
115
|
+
"standardResult.instances.7.tagName",
|
|
131
116
|
"i",
|
|
132
|
-
"
|
|
117
|
+
"INPUT"
|
|
133
118
|
],
|
|
134
119
|
[
|
|
135
120
|
"standardResult.instances.4.ordinalSeverity",
|
|
136
121
|
"=",
|
|
137
|
-
|
|
122
|
+
0
|
|
138
123
|
]
|
|
139
124
|
],
|
|
140
125
|
"withItems": true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"rule": "
|
|
2
|
+
"rule": "targetSmall",
|
|
3
3
|
"timeLimit": 20,
|
|
4
4
|
"acts": [
|
|
5
5
|
{
|
|
@@ -18,27 +18,27 @@
|
|
|
18
18
|
[
|
|
19
19
|
"standardResult.totals.0",
|
|
20
20
|
"=",
|
|
21
|
-
|
|
21
|
+
6
|
|
22
22
|
],
|
|
23
23
|
[
|
|
24
24
|
"standardResult.totals.1",
|
|
25
25
|
"=",
|
|
26
|
-
|
|
26
|
+
0
|
|
27
27
|
],
|
|
28
28
|
[
|
|
29
29
|
"standardResult.instances.0.ruleID",
|
|
30
30
|
"=",
|
|
31
|
-
"
|
|
31
|
+
"targetSmall"
|
|
32
32
|
],
|
|
33
33
|
[
|
|
34
34
|
"standardResult.instances.0.what",
|
|
35
35
|
"i",
|
|
36
|
-
"is less than"
|
|
36
|
+
"is less than 44"
|
|
37
37
|
],
|
|
38
38
|
[
|
|
39
39
|
"standardResult.instances.0.ordinalSeverity",
|
|
40
40
|
"=",
|
|
41
|
-
|
|
41
|
+
0
|
|
42
42
|
],
|
|
43
43
|
[
|
|
44
44
|
"standardResult.instances.0.tagName",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
[
|
|
69
69
|
"standardResult.instances.0.excerpt",
|
|
70
70
|
"i",
|
|
71
|
-
"(
|
|
71
|
+
"Default (small)"
|
|
72
72
|
],
|
|
73
73
|
[
|
|
74
74
|
"standardResult.instances.2.what",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
[
|
|
84
84
|
"standardResult.instances.2.excerpt",
|
|
85
85
|
"i",
|
|
86
|
-
"
|
|
86
|
+
"Small box:"
|
|
87
87
|
],
|
|
88
88
|
[
|
|
89
89
|
"standardResult.instances.2.location.spec.y",
|
|
@@ -91,19 +91,19 @@
|
|
|
91
91
|
0
|
|
92
92
|
],
|
|
93
93
|
[
|
|
94
|
-
"standardResult.instances.
|
|
94
|
+
"standardResult.instances.4.tagName",
|
|
95
95
|
"=",
|
|
96
96
|
"A"
|
|
97
97
|
],
|
|
98
98
|
[
|
|
99
|
-
"standardResult.instances.
|
|
99
|
+
"standardResult.instances.4.excerpt",
|
|
100
100
|
"=",
|
|
101
|
-
"Wikimedia Foundation"
|
|
101
|
+
"Wikimedia Foundation (small)"
|
|
102
102
|
]
|
|
103
103
|
],
|
|
104
104
|
"rules": [
|
|
105
105
|
"y",
|
|
106
|
-
"
|
|
106
|
+
"targetSmall"
|
|
107
107
|
]
|
|
108
108
|
},
|
|
109
109
|
{
|
|
@@ -113,9 +113,9 @@
|
|
|
113
113
|
"stopOnFail": true,
|
|
114
114
|
"expect": [
|
|
115
115
|
[
|
|
116
|
-
"standardResult.totals.
|
|
116
|
+
"standardResult.totals.0",
|
|
117
117
|
"=",
|
|
118
|
-
|
|
118
|
+
6
|
|
119
119
|
],
|
|
120
120
|
[
|
|
121
121
|
"standardResult.totals.3",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
[
|
|
126
126
|
"standardResult.instances.0.ruleID",
|
|
127
127
|
"=",
|
|
128
|
-
"
|
|
128
|
+
"targetSmall"
|
|
129
129
|
],
|
|
130
130
|
[
|
|
131
131
|
"standardResult.instances.0.what",
|
|
@@ -135,17 +135,17 @@
|
|
|
135
135
|
[
|
|
136
136
|
"standardResult.instances.0.ordinalSeverity",
|
|
137
137
|
"=",
|
|
138
|
-
|
|
138
|
+
0
|
|
139
139
|
],
|
|
140
140
|
[
|
|
141
141
|
"standardResult.instances.0.count",
|
|
142
142
|
"=",
|
|
143
|
-
|
|
143
|
+
6
|
|
144
144
|
]
|
|
145
145
|
],
|
|
146
146
|
"rules": [
|
|
147
147
|
"y",
|
|
148
|
-
"
|
|
148
|
+
"targetSmall"
|
|
149
149
|
]
|
|
150
150
|
}
|
|
151
151
|
]
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rule": "targetTiny",
|
|
3
|
+
"timeLimit": 20,
|
|
4
|
+
"acts": [
|
|
5
|
+
{
|
|
6
|
+
"type": "launch",
|
|
7
|
+
"target": {
|
|
8
|
+
"url": "file://validation/tests/targets/targetSize/index.html",
|
|
9
|
+
"what": "page with variously sized interaction targets"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "test",
|
|
14
|
+
"which": "testaro",
|
|
15
|
+
"withItems": true,
|
|
16
|
+
"stopOnFail": true,
|
|
17
|
+
"expect": [
|
|
18
|
+
[
|
|
19
|
+
"standardResult.totals.0",
|
|
20
|
+
"=",
|
|
21
|
+
0
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
"standardResult.totals.1",
|
|
25
|
+
"=",
|
|
26
|
+
3
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
"standardResult.instances.0.ruleID",
|
|
30
|
+
"=",
|
|
31
|
+
"targetTiny"
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
"standardResult.instances.0.what",
|
|
35
|
+
"i",
|
|
36
|
+
"is less than 24"
|
|
37
|
+
],
|
|
38
|
+
[
|
|
39
|
+
"standardResult.instances.0.ordinalSeverity",
|
|
40
|
+
"=",
|
|
41
|
+
1
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
"standardResult.instances.0.tagName",
|
|
45
|
+
"=",
|
|
46
|
+
"BUTTON"
|
|
47
|
+
],
|
|
48
|
+
[
|
|
49
|
+
"standardResult.instances.0.id",
|
|
50
|
+
"=",
|
|
51
|
+
""
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
"standardResult.instances.0.location.doc",
|
|
55
|
+
"=",
|
|
56
|
+
"dom"
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"standardResult.instances.0.location.type",
|
|
60
|
+
"=",
|
|
61
|
+
"box"
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
"standardResult.instances.0.location.spec.y",
|
|
65
|
+
">",
|
|
66
|
+
0
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
"standardResult.instances.0.excerpt",
|
|
70
|
+
"=",
|
|
71
|
+
"Tiny"
|
|
72
|
+
],
|
|
73
|
+
[
|
|
74
|
+
"standardResult.instances.2.what",
|
|
75
|
+
"i",
|
|
76
|
+
"is less than 24"
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
"standardResult.instances.2.tagName",
|
|
80
|
+
"=",
|
|
81
|
+
"A"
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
"standardResult.instances.2.excerpt",
|
|
85
|
+
"=",
|
|
86
|
+
"Wikimedia Foundation (tiny)"
|
|
87
|
+
],
|
|
88
|
+
[
|
|
89
|
+
"standardResult.instances.2.location.spec.x",
|
|
90
|
+
">",
|
|
91
|
+
0
|
|
92
|
+
]
|
|
93
|
+
],
|
|
94
|
+
"rules": [
|
|
95
|
+
"y",
|
|
96
|
+
"targetTiny"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"type": "test",
|
|
101
|
+
"which": "testaro",
|
|
102
|
+
"withItems": false,
|
|
103
|
+
"stopOnFail": true,
|
|
104
|
+
"expect": [
|
|
105
|
+
[
|
|
106
|
+
"standardResult.totals.1",
|
|
107
|
+
"=",
|
|
108
|
+
3
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"standardResult.totals.3",
|
|
112
|
+
"=",
|
|
113
|
+
0
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
"standardResult.instances.0.ruleID",
|
|
117
|
+
"=",
|
|
118
|
+
"targetTiny"
|
|
119
|
+
],
|
|
120
|
+
[
|
|
121
|
+
"standardResult.instances.0.what",
|
|
122
|
+
"i",
|
|
123
|
+
"are smaller"
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"standardResult.instances.0.ordinalSeverity",
|
|
127
|
+
"=",
|
|
128
|
+
1
|
|
129
|
+
],
|
|
130
|
+
[
|
|
131
|
+
"standardResult.instances.0.count",
|
|
132
|
+
"=",
|
|
133
|
+
3
|
|
134
|
+
]
|
|
135
|
+
],
|
|
136
|
+
"rules": [
|
|
137
|
+
"y",
|
|
138
|
+
"targetTiny"
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<!--
|
|
3
|
-
© 2022–
|
|
3
|
+
© 2022–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
4
4
|
|
|
5
5
|
MIT License
|
|
6
6
|
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
<body>
|
|
76
76
|
<main>
|
|
77
77
|
<h1>Page with mixed focus indication</h1>
|
|
78
|
-
<p>
|
|
78
|
+
<p>Nondefect 1: This paragraph contains a link to <a href="https://en.wikipedia.org">English information</a>, which exhibits a default focus indicator (outline), which may be hard to perceive but is generally classified as a non-defect.</p>
|
|
79
79
|
<p>This paragraph contains a <button id="button" type="button">button</button> with a custom outline as its focus indicator (outline).</p>
|
|
80
|
-
<p>Defect
|
|
81
|
-
<p>Defect
|
|
82
|
-
<p>Defect
|
|
83
|
-
<p>Defect
|
|
84
|
-
<p>Defect
|
|
85
|
-
<p>Defect
|
|
86
|
-
<p>Defect
|
|
80
|
+
<p>Defect 1: This paragraph contains a <label>narrative input <input id="textInput" type="text"></label> with the focus indicator suppressed (none).</p>
|
|
81
|
+
<p>Defect 2: This paragraph contains a <label>text input <input id="outlinedInput" type="text"></label> with a custom outline, which changes only color when the input is focused (other).</p>
|
|
82
|
+
<p>Defect 3: This paragraph contains a <label>text input <input id="thickOutlineInput" type="text"></label> with a custom outline, which changes only thickness when the input is focused (other).</p>
|
|
83
|
+
<p>Defect 4: This paragraph contains a checkbox with a custom focus-indication outline that finishes appearing 75 ms after the checkbox becomes focused (outline). <label><input id="checkbox" type="checkbox"> I am a bad page.</label></p>
|
|
84
|
+
<p>Defect 5: This paragraph contains a link to <a id="slowLink" href="https://fr.wikipedia.org">French information</a> with a custom border as its only focus indicator. The border appears 125 ms after the link becomes focused (other).</p>
|
|
85
|
+
<p>Defect 6: This paragraph contains a link to <a id="sluggishLink" href="https://de.wikipedia.org">German information</a> with a custom border as its only focus indicator. The border appears 525 ms after the link becomes focused (none).</p>
|
|
86
|
+
<p>Defect 7: This paragraph contains a button with a focus indicator consisting solely of an underline and an overline (other). <button id="special" type="button">special button</button></p>
|
|
87
87
|
</main>
|
|
88
88
|
</body>
|
|
89
89
|
</html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<!--
|
|
3
|
-
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
4
4
|
|
|
5
5
|
MIT License
|
|
6
6
|
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
.ambig:hover, .ambig:focus {
|
|
33
33
|
color: blue;
|
|
34
34
|
background-color: yellow;
|
|
35
|
-
|
|
35
|
+
border: 1px solid black;
|
|
36
|
+
outline: 2px solid yellow;
|
|
37
|
+
outline-offset: 2px;
|
|
36
38
|
}
|
|
37
39
|
.cursorless {
|
|
38
40
|
cursor: none;
|
|
@@ -52,15 +54,15 @@
|
|
|
52
54
|
<body>
|
|
53
55
|
<main>
|
|
54
56
|
<h1>Page with various hover indicators</h1>
|
|
55
|
-
<p>This <a href="https://www.w3.org/">Trigger 0</a> is plain.</p>
|
|
56
|
-
<p>Here is a link named <a id="trigger1" class="qCursor" href="https://en.wikipedia.org">Trigger 1</a>. When hovered over, it wrongly changes the cursor to a question mark.</p>
|
|
57
|
-
<p>This is a button named <button class="cursorless">Trigger 2</button>. It makes the cursor invisible when being hovered over. It also makes no change to its other styles on hover. The browser may slightly darken the background color on hover, but keeps the computed background-color style unchanged. Since the change by the browser is almost imperceptible, this test treats it as no change.</p>
|
|
58
|
-
<p>This is an input with a default type. <label>Trigger 3: Enter something <input></label></p>
|
|
59
|
-
<p>This is an email input that fails to distinguish hover from focus states. <label>Trigger 4: Enter an email address <input class="ambig" type="email"></label></p>
|
|
60
|
-
<p>This is a button named <button class="inert">Trigger 5</button>. It does not change when hovered over.</p>
|
|
61
|
-
<p>This is a button named <button class="hoverBC">Trigger 6</button>. Its background color changes when hovered over.</p>
|
|
62
|
-
<p>Trigger 1 has a bad hover cursor. Trigger 2 has no hover cursor. Trigger 4 has the same focus and hover indicator. Trigger 5 has no hover indicator.</p>
|
|
63
|
-
<p>Impact severities: bad cursor 2 (2 instances), ambiguous
|
|
57
|
+
<p>This <a href="https://www.w3.org/">Trigger 0</a> is plain. No violation.</p>
|
|
58
|
+
<p>Here is a link named <a id="trigger1" class="qCursor" href="https://en.wikipedia.org">Trigger 1</a>. When hovered over, it wrongly changes the cursor to a question mark. This is violation 0.</p>
|
|
59
|
+
<p>This is a button named <button class="cursorless">Trigger 2</button>. It makes the cursor invisible when being hovered over (violation 1). It also makes no change to its other styles on hover (violation 2). The browser may slightly darken the background color on hover, but keeps the computed background-color style unchanged. Since the change by the browser is almost imperceptible, this test treats it as no change.</p>
|
|
60
|
+
<p>This is an input with a default type; no violation. <label>Trigger 3: Enter something <input></label></p>
|
|
61
|
+
<p>This is an email input that fails to distinguish hover from focus states (violation 3). <label>Trigger 4: Enter an email address <input class="ambig" type="email"></label></p>
|
|
62
|
+
<p>This is a button named <button class="inert">Trigger 5</button>. It does not change when hovered over. This is violation 4.</p>
|
|
63
|
+
<p>This is a button named <button class="hoverBC">Trigger 6</button>. Its background color changes when hovered over. No violation.</p>
|
|
64
|
+
<p>Trigger 1 has a bad hover cursor (violation 0). Trigger 2 has no hover cursor (violation 1). Trigger 2 has missing hover indicator (violation 2). Trigger 4 has the same focus and hover indicator (violation 3). Trigger 5 has no hover indicator (violation 4).</p>
|
|
65
|
+
<p>Impact severities: bad hover cursor 2 (2 instances, 0 and 1), ambiguous indicators 1 (1 instance, 3), missing hover indicator 1 (2 instances, 2 and 4).
|
|
64
66
|
</main>
|
|
65
67
|
</body>
|
|
66
68
|
</html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<!--
|
|
3
|
-
© 2021–
|
|
3
|
+
© 2021–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
4
4
|
|
|
5
5
|
MIT License
|
|
6
6
|
|
|
@@ -25,52 +25,48 @@
|
|
|
25
25
|
<html lang="en-US">
|
|
26
26
|
<head>
|
|
27
27
|
<meta charset="utf-8">
|
|
28
|
-
<title>Page with
|
|
28
|
+
<title>Page with elements having explicit native-replacing roles</title>
|
|
29
29
|
<meta name="description" content="tester">
|
|
30
30
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
33
33
|
<section role="main">
|
|
34
|
-
<h1>Page with
|
|
34
|
+
<h1>Page with elements having explicit native-replacing roles</h1>
|
|
35
|
+
<section>
|
|
36
|
+
<h2>Conflict</h2>
|
|
37
|
+
<p>The parent section of these sections has an unnecessary explicit role <code>main</code>, instead of a <code>main</code> element with the same implicit role. Violation 0.</p>
|
|
38
|
+
</section>
|
|
35
39
|
<section role="section">
|
|
36
40
|
<h2>Abstraction</h2>
|
|
37
|
-
<p>This section has an abstract role,
|
|
41
|
+
<p>This section has an abstract role, which is invalid, but it does not violate this rule.</p>
|
|
38
42
|
</section>
|
|
39
43
|
<section>
|
|
40
44
|
<h2 role="heading">Redundancy</h2>
|
|
41
|
-
<p>The heading of this section has a redundant role, with an inferred level.</p>
|
|
45
|
+
<p>The heading of this section has a redundant role, with an inferred level. Violation 1.</p>
|
|
42
46
|
<section>
|
|
43
47
|
<h3 role="heading" aria-level="3">Redundancy with explicit level</h3>
|
|
44
|
-
<p>The heading of this section has a redundant role because the stated level is 3 and the implicit level is 3.</p>
|
|
48
|
+
<p>The heading of this section has a redundant role because the stated level is 3 and the implicit level is 3. Violation 2.</p>
|
|
45
49
|
</section>
|
|
46
50
|
<section>
|
|
47
51
|
<h3 role="heading">Failed redundancy for missing level</h3>
|
|
48
|
-
<p>The heading of this section has a heading that fails redundancy because the inferred level is 2 but the explicit level is 3.
|
|
52
|
+
<p>The heading of this section has a heading that fails redundancy because the inferred level is 2 but the explicit level is 3. It violates this rule regardless of the missing level. Violation 3.</p>
|
|
49
53
|
</section>
|
|
50
54
|
<section>
|
|
51
55
|
<h3 role="heading" aria-level="4">Failed redundancy for wrong level</h3>
|
|
52
|
-
<p>The heading of this section has a heading that fails redundancy because the attributional level is 4 but the explicit level is 3. So the element role is bad.</p>
|
|
56
|
+
<p>The heading of this section has a heading that fails redundancy because the attributional level is 4 but the explicit level is 3. So the element role is bad. It violates the rule regardless of the level error. Violation 4.</p>
|
|
53
57
|
</section>
|
|
54
58
|
</section>
|
|
55
|
-
<section>
|
|
56
|
-
<h2>Conflict</h2>
|
|
57
|
-
<p>The parent section of these sections has an unnecessary explicit role <code>main</code>, instead of a <code>main</code> element with the same implicit role.</p>
|
|
58
|
-
</section>
|
|
59
59
|
<section>
|
|
60
60
|
<h2>Attributes</h2>
|
|
61
61
|
<h3>Valid redundancy</h3>
|
|
62
|
-
<p>This paragraph contains an input for a number. It has an implicit <code>spinbutton</code> role and the same redundant explicit role. <input type="number" role="spinbutton"></p>
|
|
62
|
+
<p>This paragraph contains an input for a number. It has an implicit <code>spinbutton</code> role and the same redundant explicit role. Violation 5. <input type="number" role="spinbutton"></p>
|
|
63
63
|
<h3>Failed redundancy</h3>
|
|
64
|
-
<p>This paragraph contains an input for a number. It has an implicit <code>spinbutton</code> role but an explicit <code>textbox</code> role, so its role is bad. <input type="number" role="textbox"></p>
|
|
64
|
+
<p>This paragraph contains an input for a number. It has an implicit <code>spinbutton</code> role but an explicit <code>textbox</code> role, so its role is bad. Violation 6. <input type="number" role="textbox"></p>
|
|
65
65
|
<h3>Attribute existence</h3>
|
|
66
66
|
<datalist id="options"><option value="a"></option><option value="b"></option></datalist>
|
|
67
|
-
<p>This input is identical, except that it omits the <code>list</code> attribute. That makes its implicit role <code>textbox</code>, so the explicit role of <code>combobox</code> is bad. <input role="combobox"></p>
|
|
67
|
+
<p>This input is identical, except that it omits the <code>list</code> attribute. That makes its implicit role <code>textbox</code>, so the explicit role of <code>combobox</code> is bad. Violation 7. <input role="combobox"></p>
|
|
68
68
|
</section>
|
|
69
|
-
<p>
|
|
70
|
-
<p>Bad: section/section, h3/heading(2), input/textbox, input/combobox</p>
|
|
71
|
-
<p>Redundant order: section/main, h2/heading, h3/heading, input/spinbutton</p>
|
|
72
|
-
<p>Bad order: section/section, h3/heading, input/textbox, input/combobox</p>
|
|
73
|
-
<p>Instance order: section(main, section), h2(heading), h3(heading[3]), input(spinbutton, textbox, combobox)</p>
|
|
69
|
+
<p>8 rule violations, ordinal severity 0</p>
|
|
74
70
|
</section>
|
|
75
71
|
</body>
|
|
76
72
|
</html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<!--
|
|
3
|
-
© 2023 CVS Health and/or one of its affiliates. All rights reserved.
|
|
3
|
+
© 2023–2025 CVS Health and/or one of its affiliates. All rights reserved.
|
|
4
4
|
|
|
5
5
|
MIT License
|
|
6
6
|
|
|
@@ -38,16 +38,24 @@
|
|
|
38
38
|
padding-top: 1.5rem;
|
|
39
39
|
padding-bottom: 1.5rem;
|
|
40
40
|
}
|
|
41
|
+
a.normal {
|
|
42
|
+
display: inline-block;
|
|
43
|
+
padding-top: 0.5rem;
|
|
44
|
+
padding-bottom: 0.5rem;
|
|
45
|
+
}
|
|
46
|
+
a.shallow {
|
|
47
|
+
display: inline-block;
|
|
48
|
+
padding-top: 0;
|
|
49
|
+
padding-bottom: 0;
|
|
50
|
+
}
|
|
51
|
+
#defaultbutton {
|
|
52
|
+
min-height: 25px;
|
|
53
|
+
}
|
|
41
54
|
li {
|
|
42
55
|
text-align: left;
|
|
43
56
|
background-color: #ccc;
|
|
44
57
|
margin: 0.5rem 0;
|
|
45
58
|
}
|
|
46
|
-
ul {
|
|
47
|
-
display: flex;
|
|
48
|
-
flex-direction: column;
|
|
49
|
-
align-items: flex-start;
|
|
50
|
-
}
|
|
51
59
|
</style>
|
|
52
60
|
</head>
|
|
53
61
|
<body>
|
|
@@ -56,25 +64,28 @@
|
|
|
56
64
|
<h2>Buttons</h2>
|
|
57
65
|
<p>Here are three buttons:</p>
|
|
58
66
|
<p><button style="min-width: 3rem; min-height: 3rem" type="button">Big enough</button></p>
|
|
59
|
-
<p><button id="defaultbutton" type="button">Default (
|
|
60
|
-
<p><button style="height: 1.
|
|
67
|
+
<p><button id="defaultbutton" type="button">Default (small)</button></p>
|
|
68
|
+
<p><button style="height: 1.25rem" type="button">Tiny</button></p>
|
|
61
69
|
<h2>Inputs</h2>
|
|
62
|
-
<p>Here are
|
|
63
|
-
<p><label>
|
|
64
|
-
<p><label>
|
|
70
|
+
<p>Here are three inputs:</p>
|
|
71
|
+
<p><label>Big box: <input style="min-width: 3rem; min-height: 3rem" size="20" maxlength="30"></label></p>
|
|
72
|
+
<p><label>Small box: <input style="min-height: 1.5rem" size="20" maxlength="30"></label></p>
|
|
73
|
+
<p><label>Tiny box: <input style="max-height: 1rem" size="20" maxlength="30"></label></p>
|
|
65
74
|
<h2>Links</h2>
|
|
75
|
+
<p>Here are three links:</p>
|
|
66
76
|
<ul>
|
|
67
|
-
<li
|
|
68
|
-
<li><a href="https://wikimedia.org">Wikimedia Foundation</a></li>
|
|
77
|
+
<li><a class="deep" href="https://w3c.org">World Wide Web Consortium (big)</a></li>
|
|
78
|
+
<li><a class="normal" href="https://wikimedia.org">Wikimedia Foundation (small)</a></li>
|
|
79
|
+
<li><a class="shallow" href="https://wikimedia.org">Wikimedia Foundation (tiny)</a></li>
|
|
69
80
|
</ul>
|
|
70
81
|
<ul>
|
|
71
|
-
<li style="min-height: 3rem">W3C: <a class="deep" href="https://w3c.org">World Wide Web Consortium</a></li>
|
|
72
|
-
<li>WF: <a href="https://wikimedia.org">Wikimedia Foundation</a></li>
|
|
82
|
+
<li style="min-height: 3rem">W3C: <a class="deep" href="https://w3c.org">World Wide Web Consortium (big)</a></li>
|
|
83
|
+
<li>WF: <a href="https://wikimedia.org">Wikimedia Foundation (small but inline)</a></li>
|
|
84
|
+
<li>WF: <a href="https://wikimedia.org">Wikimedia Foundation (tiny but inline)</a></li>
|
|
85
|
+
<h2>Violations</h2>
|
|
86
|
+
<p>Small: 2 buttons, 2 inputs, 2 links</p>
|
|
87
|
+
<p>Tiny: 1 button, 1 input, 1 link</p>
|
|
73
88
|
</ul>
|
|
74
|
-
<h2>Conclusion</h2>
|
|
75
|
-
<p>2 buttons are too small.</p>
|
|
76
|
-
<p>1 input is too small.</p>
|
|
77
|
-
<p>1 link is too small.</p>
|
|
78
89
|
</main>
|
|
79
90
|
</body>
|
|
80
91
|
</html>
|
|
@@ -35,7 +35,6 @@ const fs = require('fs').promises;
|
|
|
35
35
|
const {doJob} = require('../run');
|
|
36
36
|
|
|
37
37
|
// CONSTANTS
|
|
38
|
-
|
|
39
38
|
const job = {
|
|
40
39
|
id: '250101T0000-aaa-00',
|
|
41
40
|
what: '',
|
|
@@ -73,6 +72,9 @@ exports.validateTest = async testID => {
|
|
|
73
72
|
// Get data for a job for the test.
|
|
74
73
|
const jobProperties = require(`./tests/jobProperties/${testID}.json`);
|
|
75
74
|
// Use the data to complete the job.
|
|
75
|
+
if (jobProperties.standard) {
|
|
76
|
+
job.standard = jobProperties.standard;
|
|
77
|
+
}
|
|
76
78
|
job.what = `validate Testaro test ${jobProperties.rule}`;
|
|
77
79
|
job.timeLimit = jobProperties.timeLimit;
|
|
78
80
|
job.acts = jobProperties.acts;
|