aria-ease 6.2.2 → 6.3.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/README.md +91 -12
- package/bin/{chunk-7RMRFSJL.js → chunk-XLG3MIPQ.js} +5 -1
- package/bin/cli.cjs +52 -11
- package/bin/cli.js +1 -1
- package/bin/{contractTestRunnerPlaywright-ACAWN34W.js → contractTestRunnerPlaywright-JXQUUKFO.js} +48 -11
- package/bin/{test-A3ESFXOR.js → test-XSDP2NX3.js} +2 -2
- package/dist/{chunk-PDZQOXUN.js → chunk-RDEAG4KE.js} +5 -1
- package/dist/{contractTestRunnerPlaywright-O7FF7GV4.js → contractTestRunnerPlaywright-EUXD6ZZK.js} +48 -11
- package/dist/index.cjs +316 -69
- package/dist/index.d.cts +34 -4
- package/dist/index.d.ts +34 -4
- package/dist/index.js +265 -60
- package/dist/src/{Types.d-CRjhbrcw.d.cts → Types.d-DYfYR3Vc.d.cts} +18 -1
- package/dist/src/{Types.d-CRjhbrcw.d.ts → Types.d-DYfYR3Vc.d.ts} +18 -1
- package/dist/src/accordion/index.d.cts +2 -2
- package/dist/src/accordion/index.d.ts +2 -2
- package/dist/src/block/index.d.cts +1 -1
- package/dist/src/block/index.d.ts +1 -1
- package/dist/src/checkbox/index.cjs +0 -22
- package/dist/src/checkbox/index.d.cts +2 -2
- package/dist/src/checkbox/index.d.ts +2 -2
- package/dist/src/checkbox/index.js +0 -22
- package/dist/src/combobox/index.d.cts +1 -1
- package/dist/src/combobox/index.d.ts +1 -1
- package/dist/src/menu/index.d.cts +1 -1
- package/dist/src/menu/index.d.ts +1 -1
- package/dist/src/radio/index.cjs +0 -8
- package/dist/src/radio/index.d.cts +2 -2
- package/dist/src/radio/index.d.ts +2 -2
- package/dist/src/radio/index.js +0 -8
- package/dist/src/tabs/index.cjs +265 -0
- package/dist/src/tabs/index.d.cts +16 -0
- package/dist/src/tabs/index.d.ts +16 -0
- package/dist/src/tabs/index.js +263 -0
- package/dist/src/toggle/index.cjs +0 -28
- package/dist/src/toggle/index.d.cts +1 -1
- package/dist/src/toggle/index.d.ts +1 -1
- package/dist/src/toggle/index.js +0 -28
- package/dist/src/utils/test/{chunk-7RMRFSJL.js → chunk-XLG3MIPQ.js} +5 -1
- package/dist/src/utils/test/{contractTestRunnerPlaywright-7BPRTIN4.js → contractTestRunnerPlaywright-N77NEY25.js} +48 -11
- package/dist/src/utils/test/contracts/AccordionContract.json +18 -17
- package/dist/src/utils/test/contracts/ComboboxContract.json +32 -48
- package/dist/src/utils/test/contracts/MenuContract.json +19 -25
- package/dist/src/utils/test/contracts/TabsContract.json +348 -0
- package/dist/src/utils/test/index.cjs +52 -11
- package/dist/src/utils/test/index.js +2 -2
- package/package.json +8 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContractReporter, contract_default, createTestPage } from './chunk-
|
|
1
|
+
import { ContractReporter, contract_default, createTestPage } from './chunk-XLG3MIPQ.js';
|
|
2
2
|
import { expect } from '@playwright/test';
|
|
3
3
|
import { readFileSync } from 'fs';
|
|
4
4
|
|
|
@@ -39,9 +39,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
39
39
|
}
|
|
40
40
|
await page.addStyleTag({ content: `* { transition: none !important; animation: none !important; }` });
|
|
41
41
|
}
|
|
42
|
-
const mainSelector = componentContract.selectors.trigger || componentContract.selectors.input || componentContract.selectors.container;
|
|
42
|
+
const mainSelector = componentContract.selectors.trigger || componentContract.selectors.input || componentContract.selectors.container || componentContract.selectors.tablist || componentContract.selectors.tab;
|
|
43
43
|
if (!mainSelector) {
|
|
44
|
-
throw new Error(`CRITICAL: No main selector (trigger, input, or
|
|
44
|
+
throw new Error(`CRITICAL: No main selector (trigger, input, container, tablist, or tab) found in contract for ${componentName}`);
|
|
45
45
|
}
|
|
46
46
|
try {
|
|
47
47
|
await page.locator(mainSelector).first().waitFor({ state: "attached", timeout: 3e4 });
|
|
@@ -103,28 +103,52 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
103
103
|
failures.push(`Target ${test.target} not found.`);
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
|
+
const isRedundantCheck = (selector, attrName, expectedVal) => {
|
|
107
|
+
const attrPattern = new RegExp(`\\[${attrName}(?:=["']?([^\\]"']+)["']?)?\\]`);
|
|
108
|
+
const match = selector.match(attrPattern);
|
|
109
|
+
if (!match) return false;
|
|
110
|
+
if (!expectedVal) return true;
|
|
111
|
+
const selectorValue = match[1];
|
|
112
|
+
if (selectorValue) {
|
|
113
|
+
const expectedValues = expectedVal.split(" | ");
|
|
114
|
+
return expectedValues.includes(selectorValue);
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
};
|
|
106
118
|
if (!test.expectedValue) {
|
|
107
119
|
const attributes = test.attribute.split(" | ");
|
|
108
120
|
let hasAny = false;
|
|
121
|
+
let allRedundant = true;
|
|
109
122
|
for (const attr of attributes) {
|
|
110
|
-
const
|
|
123
|
+
const attrTrimmed = attr.trim();
|
|
124
|
+
if (isRedundantCheck(targetSelector, attrTrimmed)) {
|
|
125
|
+
passes.push(`${attrTrimmed} on ${test.target} verified by selector (already present in: ${targetSelector}).`);
|
|
126
|
+
hasAny = true;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
allRedundant = false;
|
|
130
|
+
const value = await target.getAttribute(attrTrimmed);
|
|
111
131
|
if (value !== null) {
|
|
112
132
|
hasAny = true;
|
|
113
133
|
break;
|
|
114
134
|
}
|
|
115
135
|
}
|
|
116
|
-
if (!hasAny) {
|
|
136
|
+
if (!hasAny && !allRedundant) {
|
|
117
137
|
failures.push(test.failureMessage + ` None of the attributes "${test.attribute}" are present.`);
|
|
118
|
-
} else {
|
|
138
|
+
} else if (!allRedundant && hasAny) {
|
|
119
139
|
passes.push(`At least one of the attributes "${test.attribute}" exists on the element.`);
|
|
120
140
|
}
|
|
121
141
|
} else {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (!attributeValue || !expectedValues.includes(attributeValue)) {
|
|
125
|
-
failures.push(test.failureMessage + ` Attribute value does not match expected value. Expected: ${test.expectedValue}, Found: ${attributeValue}`);
|
|
142
|
+
if (isRedundantCheck(targetSelector, test.attribute, test.expectedValue)) {
|
|
143
|
+
passes.push(`${test.attribute}="${test.expectedValue}" on ${test.target} verified by selector (already present in: ${targetSelector}).`);
|
|
126
144
|
} else {
|
|
127
|
-
|
|
145
|
+
const attributeValue = await target.getAttribute(test.attribute);
|
|
146
|
+
const expectedValues = test.expectedValue.split(" | ");
|
|
147
|
+
if (!attributeValue || !expectedValues.includes(attributeValue)) {
|
|
148
|
+
failures.push(test.failureMessage + ` Attribute value does not match expected value. Expected: ${test.expectedValue}, Found: ${attributeValue}`);
|
|
149
|
+
} else {
|
|
150
|
+
passes.push(`Attribute value matches expected value. Expected: ${test.expectedValue}, Found: ${attributeValue}`);
|
|
151
|
+
}
|
|
128
152
|
}
|
|
129
153
|
}
|
|
130
154
|
}
|
|
@@ -233,6 +257,19 @@ This indicates a problem with the menu component's close functionality.`
|
|
|
233
257
|
if (shouldSkipTest) {
|
|
234
258
|
continue;
|
|
235
259
|
}
|
|
260
|
+
if (componentContract.selectors.panel && componentContract.selectors.tab && componentContract.selectors.tablist) {
|
|
261
|
+
if (dynamicTest.isVertical !== void 0 && componentContract.selectors.tablist) {
|
|
262
|
+
const tablistSelector = componentContract.selectors.tablist;
|
|
263
|
+
const tablist = page.locator(tablistSelector).first();
|
|
264
|
+
const orientation = await tablist.getAttribute("aria-orientation");
|
|
265
|
+
const isVertical = orientation === "vertical";
|
|
266
|
+
if (dynamicTest.isVertical !== isVertical) {
|
|
267
|
+
const skipReason = dynamicTest.isVertical ? `Skipping vertical tabs test - component has horizontal orientation` : `Skipping horizontal tabs test - component has vertical orientation`;
|
|
268
|
+
reporter.reportTest(dynamicTest, "skip", skipReason);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
236
273
|
for (const act of action) {
|
|
237
274
|
if (!page || page.isClosed()) {
|
|
238
275
|
failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"meta": {
|
|
3
3
|
"id": "aria-ease.accordion",
|
|
4
4
|
"version": "1.0.0",
|
|
5
|
-
"
|
|
5
|
+
"created": "09-02-2026",
|
|
6
|
+
"lastUpdated": "28-02-2026",
|
|
6
7
|
"description": "ARIA Accordion interaction contract. Validates the ARIA and interaction contract for a custom accordion component following the ARIA Authoring Practices Guide accordion with show/hide pattern.",
|
|
7
8
|
"source": {
|
|
8
9
|
"apg": "https://www.w3.org/WAI/ARIA/apg/patterns/accordion/",
|
|
@@ -101,7 +102,7 @@
|
|
|
101
102
|
]
|
|
102
103
|
},
|
|
103
104
|
{
|
|
104
|
-
"description": "Pressing Enter
|
|
105
|
+
"description": "Pressing Enter on trigger expands a collapsed panel.",
|
|
105
106
|
"action": [
|
|
106
107
|
{ "type": "keypress", "target": "trigger", "key": "Enter" }
|
|
107
108
|
],
|
|
@@ -116,12 +117,12 @@
|
|
|
116
117
|
"assertion": "toHaveAttribute",
|
|
117
118
|
"attribute": "aria-expanded",
|
|
118
119
|
"expectedValue": "true",
|
|
119
|
-
"failureMessage": "Trigger's aria-expanded
|
|
120
|
+
"failureMessage": "Trigger's should have aria-expanded=true after pressing Enter."
|
|
120
121
|
}
|
|
121
122
|
]
|
|
122
123
|
},
|
|
123
124
|
{
|
|
124
|
-
"description": "Pressing Space
|
|
125
|
+
"description": "Pressing Space on trigger expands a collapsed panel.",
|
|
125
126
|
"action": [
|
|
126
127
|
{ "type": "keypress", "target": "trigger", "key": "Space" }
|
|
127
128
|
],
|
|
@@ -136,12 +137,12 @@
|
|
|
136
137
|
"assertion": "toHaveAttribute",
|
|
137
138
|
"attribute": "aria-expanded",
|
|
138
139
|
"expectedValue": "true",
|
|
139
|
-
"failureMessage": "Trigger's aria-expanded
|
|
140
|
+
"failureMessage": "Trigger's should have aria-expanded=true after pressing Space."
|
|
140
141
|
}
|
|
141
142
|
]
|
|
142
143
|
},
|
|
143
144
|
{
|
|
144
|
-
"description": "Pressing Enter
|
|
145
|
+
"description": "Pressing Enter on trigger collapses an expanded panel.",
|
|
145
146
|
"action": [
|
|
146
147
|
{ "type": "keypress", "target": "trigger", "key": "Enter" },
|
|
147
148
|
{ "type": "keypress", "target": "trigger", "key": "Enter" }
|
|
@@ -162,7 +163,7 @@
|
|
|
162
163
|
]
|
|
163
164
|
},
|
|
164
165
|
{
|
|
165
|
-
"description": "Pressing Space
|
|
166
|
+
"description": "Pressing Space on trigger collapses an expanded panel.",
|
|
166
167
|
"action": [
|
|
167
168
|
{ "type": "keypress", "target": "trigger", "key": "Space" },
|
|
168
169
|
{ "type": "keypress", "target": "trigger", "key": "Space" }
|
|
@@ -183,7 +184,7 @@
|
|
|
183
184
|
]
|
|
184
185
|
},
|
|
185
186
|
{
|
|
186
|
-
"description": "
|
|
187
|
+
"description": "Down Arrow moves focus to next accordion trigger.",
|
|
187
188
|
"isMultiple": true,
|
|
188
189
|
"isOptional": true,
|
|
189
190
|
"action": [
|
|
@@ -194,12 +195,12 @@
|
|
|
194
195
|
"target": "relative",
|
|
195
196
|
"assertion": "toHaveFocus",
|
|
196
197
|
"expectedValue": "second",
|
|
197
|
-
"failureMessage": "Focus should move to the next accordion trigger after pressing
|
|
198
|
+
"failureMessage": "Focus should move to the next accordion trigger after pressing Down Arrow."
|
|
198
199
|
}
|
|
199
200
|
]
|
|
200
201
|
},
|
|
201
202
|
{
|
|
202
|
-
"description": "
|
|
203
|
+
"description": "Up Arrow moves focus to previous accordion trigger.",
|
|
203
204
|
"isMultiple": true,
|
|
204
205
|
"isOptional": true,
|
|
205
206
|
"action": [
|
|
@@ -210,12 +211,12 @@
|
|
|
210
211
|
"target": "relative",
|
|
211
212
|
"assertion": "toHaveFocus",
|
|
212
213
|
"expectedValue": "first",
|
|
213
|
-
"failureMessage": "Focus should move to the previous accordion trigger after pressing
|
|
214
|
+
"failureMessage": "Focus should move to the previous accordion trigger after pressing Up Arrow."
|
|
214
215
|
}
|
|
215
216
|
]
|
|
216
217
|
},
|
|
217
218
|
{
|
|
218
|
-
"description": "Home
|
|
219
|
+
"description": "Home moves focus to first accordion trigger.",
|
|
219
220
|
"isMultiple": true,
|
|
220
221
|
"isOptional": true,
|
|
221
222
|
"action": [
|
|
@@ -231,7 +232,7 @@
|
|
|
231
232
|
]
|
|
232
233
|
},
|
|
233
234
|
{
|
|
234
|
-
"description": "End
|
|
235
|
+
"description": "End moves focus to last accordion trigger.",
|
|
235
236
|
"isMultiple": true,
|
|
236
237
|
"isOptional": true,
|
|
237
238
|
"action": [
|
|
@@ -247,7 +248,7 @@
|
|
|
247
248
|
]
|
|
248
249
|
},
|
|
249
250
|
{
|
|
250
|
-
"description": "Arrow
|
|
251
|
+
"description": "Down Arrow wraps focus from last trigger to first trigger.",
|
|
251
252
|
"isMultiple": true,
|
|
252
253
|
"isOptional": true,
|
|
253
254
|
"action": [
|
|
@@ -258,12 +259,12 @@
|
|
|
258
259
|
"target": "relative",
|
|
259
260
|
"assertion": "toHaveFocus",
|
|
260
261
|
"expectedValue": "first",
|
|
261
|
-
"failureMessage": "Focus should wrap from last to first accordion trigger after pressing
|
|
262
|
+
"failureMessage": "Focus should wrap from last to first accordion trigger after pressing Down Arrow."
|
|
262
263
|
}
|
|
263
264
|
]
|
|
264
265
|
},
|
|
265
266
|
{
|
|
266
|
-
"description": "Arrow
|
|
267
|
+
"description": "Up Arrow wraps focus from first trigger to last trigger.",
|
|
267
268
|
"isMultiple": true,
|
|
268
269
|
"isOptional": true,
|
|
269
270
|
"action": [
|
|
@@ -274,7 +275,7 @@
|
|
|
274
275
|
"target": "relative",
|
|
275
276
|
"assertion": "toHaveFocus",
|
|
276
277
|
"expectedValue": "last",
|
|
277
|
-
"failureMessage": "Focus should wrap from first to last accordion trigger after pressing
|
|
278
|
+
"failureMessage": "Focus should wrap from first to last accordion trigger after pressing Up Arrow."
|
|
278
279
|
}
|
|
279
280
|
]
|
|
280
281
|
}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
"meta": {
|
|
3
3
|
"id": "aria-ease.combobox",
|
|
4
4
|
"version": "1.0.0",
|
|
5
|
-
"
|
|
5
|
+
"created": "11-02-2026",
|
|
6
|
+
"lastUpdated": "28-02-2026",
|
|
6
7
|
"description": "ARIA Combobox interaction contract. Validates the ARIA and interaction contract for a custom combobox component following the ARIA Authoring Practices Guide combobox with listbox popup pattern.",
|
|
7
8
|
"source": {
|
|
8
9
|
"apg": "https://www.w3.org/WAI/ARIA/apg/patterns/combobox/",
|
|
@@ -91,37 +92,35 @@
|
|
|
91
92
|
|
|
92
93
|
"dynamic": [
|
|
93
94
|
{
|
|
94
|
-
"description": "Pressing
|
|
95
|
+
"description": "Pressing Down Arrow on closed combobox opens the listbox without selecting first item.",
|
|
95
96
|
"action": [
|
|
96
|
-
{ "type": "focus", "target": "input" },
|
|
97
97
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" }
|
|
98
98
|
],
|
|
99
99
|
"assertions": [
|
|
100
100
|
{
|
|
101
101
|
"target": "listbox",
|
|
102
102
|
"assertion": "toBeVisible",
|
|
103
|
-
"failureMessage": "Listbox should be visible after pressing
|
|
103
|
+
"failureMessage": "Listbox should be visible after pressing Down Arrow on closed combobox."
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
"target": "input",
|
|
107
107
|
"assertion": "toHaveAttribute",
|
|
108
108
|
"attribute": "aria-expanded",
|
|
109
109
|
"expectedValue": "true",
|
|
110
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
110
|
+
"failureMessage": "Combobox input's should have aria-expanded=true after pressing Down Arrow."
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
113
|
"target": "input",
|
|
114
114
|
"assertion": "toHaveAttribute",
|
|
115
115
|
"attribute": "aria-activedescendant",
|
|
116
116
|
"expectedValue": "",
|
|
117
|
-
"failureMessage": "First
|
|
117
|
+
"failureMessage": "First Down Arrow should open listbox without setting active descendant (no item selected yet)."
|
|
118
118
|
}
|
|
119
119
|
]
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
|
-
"description": "Second
|
|
122
|
+
"description": "Second Down Arrow press navigates to first listbox option.",
|
|
123
123
|
"action": [
|
|
124
|
-
{ "type": "focus", "target": "input" },
|
|
125
124
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
126
125
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" }
|
|
127
126
|
],
|
|
@@ -131,7 +130,7 @@
|
|
|
131
130
|
"assertion": "toHaveAttribute",
|
|
132
131
|
"attribute": "aria-activedescendant",
|
|
133
132
|
"expectedValue": "!empty",
|
|
134
|
-
"failureMessage": "Second
|
|
133
|
+
"failureMessage": "Second Down Arrow should set first listbox option as active descendant."
|
|
135
134
|
},
|
|
136
135
|
{
|
|
137
136
|
"target": "relative",
|
|
@@ -139,14 +138,13 @@
|
|
|
139
138
|
"attribute": "aria-selected",
|
|
140
139
|
"expectedValue": "true",
|
|
141
140
|
"relativeTarget": "first",
|
|
142
|
-
"failureMessage": "First listbox option should have aria-selected=true after second
|
|
141
|
+
"failureMessage": "First listbox option should have aria-selected=true after second Down Arrow."
|
|
143
142
|
}
|
|
144
143
|
]
|
|
145
144
|
},
|
|
146
145
|
{
|
|
147
|
-
"description": "
|
|
146
|
+
"description": "Down Arrow navigates to next listbox option with wrapping.",
|
|
148
147
|
"action": [
|
|
149
|
-
{ "type": "focus", "target": "input" },
|
|
150
148
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
151
149
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
152
150
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" }
|
|
@@ -158,14 +156,13 @@
|
|
|
158
156
|
"attribute": "aria-selected",
|
|
159
157
|
"expectedValue": "true",
|
|
160
158
|
"relativeTarget": "second",
|
|
161
|
-
"failureMessage": "Second listbox option should be selected after third
|
|
159
|
+
"failureMessage": "Second listbox option should be selected after third Down Arrow."
|
|
162
160
|
}
|
|
163
161
|
]
|
|
164
162
|
},
|
|
165
163
|
{
|
|
166
|
-
"description": "
|
|
164
|
+
"description": "Up Arrow does not open closed listbox.",
|
|
167
165
|
"action": [
|
|
168
|
-
{ "type": "focus", "target": "input" },
|
|
169
166
|
{ "type": "keypress", "target": "input", "key": "ArrowUp" }
|
|
170
167
|
],
|
|
171
168
|
"assertions": [
|
|
@@ -174,14 +171,13 @@
|
|
|
174
171
|
"assertion": "toHaveAttribute",
|
|
175
172
|
"attribute": "aria-expanded",
|
|
176
173
|
"expectedValue": "false",
|
|
177
|
-
"failureMessage": "
|
|
174
|
+
"failureMessage": "Up Arrow should not open a closed listbox. Combobox input should have aria-expanded=false."
|
|
178
175
|
}
|
|
179
176
|
]
|
|
180
177
|
},
|
|
181
178
|
{
|
|
182
179
|
"description": "ArrowUp navigates to previous option when listbox is open.",
|
|
183
180
|
"action": [
|
|
184
|
-
{ "type": "focus", "target": "input" },
|
|
185
181
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
186
182
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
187
183
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
@@ -199,10 +195,9 @@
|
|
|
199
195
|
]
|
|
200
196
|
},
|
|
201
197
|
{
|
|
202
|
-
"description": "Home
|
|
198
|
+
"description": "Home navigates to first listbox option.",
|
|
203
199
|
"isOptional": true,
|
|
204
200
|
"action": [
|
|
205
|
-
{ "type": "focus", "target": "input" },
|
|
206
201
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
207
202
|
{ "type": "keypress", "target": "input", "key": "End" },
|
|
208
203
|
{ "type": "keypress", "target": "input", "key": "Home" }
|
|
@@ -214,15 +209,14 @@
|
|
|
214
209
|
"attribute": "aria-selected",
|
|
215
210
|
"expectedValue": "true",
|
|
216
211
|
"relativeTarget": "first",
|
|
217
|
-
"failureMessage": "Home
|
|
212
|
+
"failureMessage": "Home should navigate to first listbox option."
|
|
218
213
|
}
|
|
219
214
|
]
|
|
220
215
|
},
|
|
221
216
|
{
|
|
222
|
-
"description": "End
|
|
217
|
+
"description": "End navigates to last listbox option.",
|
|
223
218
|
"isOptional": true,
|
|
224
219
|
"action": [
|
|
225
|
-
{ "type": "focus", "target": "input" },
|
|
226
220
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
227
221
|
{ "type": "keypress", "target": "input", "key": "End" }
|
|
228
222
|
],
|
|
@@ -233,14 +227,13 @@
|
|
|
233
227
|
"attribute": "aria-selected",
|
|
234
228
|
"expectedValue": "true",
|
|
235
229
|
"relativeTarget": "last",
|
|
236
|
-
"failureMessage": "End
|
|
230
|
+
"failureMessage": "End should navigate to last listbox option."
|
|
237
231
|
}
|
|
238
232
|
]
|
|
239
233
|
},
|
|
240
234
|
{
|
|
241
|
-
"description": "Enter
|
|
235
|
+
"description": "Enter selects active option and closes listbox.",
|
|
242
236
|
"action": [
|
|
243
|
-
{ "type": "focus", "target": "input" },
|
|
244
237
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
245
238
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
246
239
|
{ "type": "keypress", "target": "input", "key": "Enter" }
|
|
@@ -256,7 +249,7 @@
|
|
|
256
249
|
"assertion": "toHaveAttribute",
|
|
257
250
|
"attribute": "aria-expanded",
|
|
258
251
|
"expectedValue": "false",
|
|
259
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
252
|
+
"failureMessage": "Combobox input's should have aria-expanded=false after selection."
|
|
260
253
|
},
|
|
261
254
|
{
|
|
262
255
|
"target": "input",
|
|
@@ -267,9 +260,8 @@
|
|
|
267
260
|
]
|
|
268
261
|
},
|
|
269
262
|
{
|
|
270
|
-
"description": "Escape
|
|
263
|
+
"description": "Escape closes open listbox.",
|
|
271
264
|
"action": [
|
|
272
|
-
{ "type": "focus", "target": "input" },
|
|
273
265
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
274
266
|
{ "type": "keypress", "target": "input", "key": "Escape" }
|
|
275
267
|
],
|
|
@@ -284,14 +276,13 @@
|
|
|
284
276
|
"assertion": "toHaveAttribute",
|
|
285
277
|
"attribute": "aria-expanded",
|
|
286
278
|
"expectedValue": "false",
|
|
287
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
279
|
+
"failureMessage": "Combobox input's should have aria-expanded=false after Escape."
|
|
288
280
|
}
|
|
289
281
|
]
|
|
290
282
|
},
|
|
291
283
|
{
|
|
292
|
-
"description": "Escape
|
|
284
|
+
"description": "Escape clears input value when listbox is closed.",
|
|
293
285
|
"action": [
|
|
294
|
-
{ "type": "focus", "target": "input" },
|
|
295
286
|
{ "type": "type", "target": "input", "value": "test" },
|
|
296
287
|
{ "type": "keypress", "target": "input", "key": "Escape" }
|
|
297
288
|
],
|
|
@@ -305,9 +296,8 @@
|
|
|
305
296
|
]
|
|
306
297
|
},
|
|
307
298
|
{
|
|
308
|
-
"description": "Tab
|
|
299
|
+
"description": "Tab closes the listbox.",
|
|
309
300
|
"action": [
|
|
310
|
-
{ "type": "focus", "target": "input" },
|
|
311
301
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
312
302
|
{ "type": "keypress", "target": "input", "key": "Tab" }
|
|
313
303
|
],
|
|
@@ -317,14 +307,13 @@
|
|
|
317
307
|
"assertion": "toHaveAttribute",
|
|
318
308
|
"attribute": "aria-expanded",
|
|
319
309
|
"expectedValue": "false",
|
|
320
|
-
"failureMessage": "Tab
|
|
310
|
+
"failureMessage": "Tab should close the listbox, and should have aria-expanded=false."
|
|
321
311
|
}
|
|
322
312
|
]
|
|
323
313
|
},
|
|
324
314
|
{
|
|
325
315
|
"description": "Clicking option selects it and closes listbox.",
|
|
326
316
|
"action": [
|
|
327
|
-
{ "type": "focus", "target": "input" },
|
|
328
317
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
329
318
|
{ "type": "click", "target": "relative", "relativeTarget": "first" }
|
|
330
319
|
],
|
|
@@ -339,7 +328,7 @@
|
|
|
339
328
|
"assertion": "toHaveAttribute",
|
|
340
329
|
"attribute": "aria-expanded",
|
|
341
330
|
"expectedValue": "false",
|
|
342
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
331
|
+
"failureMessage": "Combobox input's should have aria-expanded=false after clicking option."
|
|
343
332
|
},
|
|
344
333
|
{
|
|
345
334
|
"target": "input",
|
|
@@ -351,9 +340,7 @@
|
|
|
351
340
|
},
|
|
352
341
|
{
|
|
353
342
|
"description": "Mouse hover sets aria-selected on hovered listbox option.",
|
|
354
|
-
"requiresBrowser": true,
|
|
355
343
|
"action": [
|
|
356
|
-
{ "type": "focus", "target": "input" },
|
|
357
344
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
358
345
|
{ "type": "hover", "target": "relative", "relativeTarget": "second" }
|
|
359
346
|
],
|
|
@@ -371,7 +358,6 @@
|
|
|
371
358
|
{
|
|
372
359
|
"description": "Clicking outside closes the listbox.",
|
|
373
360
|
"action": [
|
|
374
|
-
{ "type": "focus", "target": "input" },
|
|
375
361
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
376
362
|
{ "type": "click", "target": "document" }
|
|
377
363
|
],
|
|
@@ -386,7 +372,7 @@
|
|
|
386
372
|
"assertion": "toHaveAttribute",
|
|
387
373
|
"attribute": "aria-expanded",
|
|
388
374
|
"expectedValue": "false",
|
|
389
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
375
|
+
"failureMessage": "Combobox input's should have aria-expanded=false after clicking outside."
|
|
390
376
|
}
|
|
391
377
|
]
|
|
392
378
|
},
|
|
@@ -406,7 +392,7 @@
|
|
|
406
392
|
"assertion": "toHaveAttribute",
|
|
407
393
|
"attribute": "aria-expanded",
|
|
408
394
|
"expectedValue": "true",
|
|
409
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
395
|
+
"failureMessage": "Combobox input's should have aria-expanded=true after clicking button."
|
|
410
396
|
},
|
|
411
397
|
{
|
|
412
398
|
"target": "input",
|
|
@@ -432,14 +418,13 @@
|
|
|
432
418
|
"assertion": "toHaveAttribute",
|
|
433
419
|
"attribute": "aria-expanded",
|
|
434
420
|
"expectedValue": "false",
|
|
435
|
-
"failureMessage": "Combobox input's aria-expanded
|
|
421
|
+
"failureMessage": "Combobox input's should have aria-expanded=false after toggling closed."
|
|
436
422
|
}
|
|
437
423
|
]
|
|
438
424
|
},
|
|
439
425
|
{
|
|
440
|
-
"description": "Navigation wraps from last to first listbox option on
|
|
426
|
+
"description": "Navigation wraps from last to first listbox option on Down Arrow.",
|
|
441
427
|
"action": [
|
|
442
|
-
{ "type": "focus", "target": "input" },
|
|
443
428
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
444
429
|
{ "type": "keypress", "target": "input", "key": "End" },
|
|
445
430
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" }
|
|
@@ -451,14 +436,13 @@
|
|
|
451
436
|
"attribute": "aria-selected",
|
|
452
437
|
"expectedValue": "true",
|
|
453
438
|
"relativeTarget": "first",
|
|
454
|
-
"failureMessage": "Navigation should wrap from last to first listbox option on
|
|
439
|
+
"failureMessage": "Navigation should wrap from last to first listbox option on Down Arrow."
|
|
455
440
|
}
|
|
456
441
|
]
|
|
457
442
|
},
|
|
458
443
|
{
|
|
459
|
-
"description": "Navigation wraps from first to last listbox option on
|
|
444
|
+
"description": "Navigation wraps from first to last listbox option on Up Arrow.",
|
|
460
445
|
"action": [
|
|
461
|
-
{ "type": "focus", "target": "input" },
|
|
462
446
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
463
447
|
{ "type": "keypress", "target": "input", "key": "ArrowDown" },
|
|
464
448
|
{ "type": "keypress", "target": "input", "key": "ArrowUp" }
|
|
@@ -470,7 +454,7 @@
|
|
|
470
454
|
"attribute": "aria-selected",
|
|
471
455
|
"expectedValue": "true",
|
|
472
456
|
"relativeTarget": "last",
|
|
473
|
-
"failureMessage": "Navigation should wrap from first to last listbox option on
|
|
457
|
+
"failureMessage": "Navigation should wrap from first to last listbox option on Up Arrow."
|
|
474
458
|
}
|
|
475
459
|
]
|
|
476
460
|
}
|