aria-ease 3.0.3 → 4.0.1
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 +207 -87
- package/bin/cli.cjs +32 -0
- package/bin/cli.js +1 -1
- package/bin/{contractTestRunnerPlaywright-3VJUZSYK.js → contractTestRunnerPlaywright-EZLNNJV5.js} +32 -0
- package/bin/{test-D374H2ZS.js → test-45KMD4F4.js} +1 -1
- package/dist/{contractTestRunnerPlaywright-4UOHWGWD.js → contractTestRunnerPlaywright-UQQI5MYS.js} +32 -0
- package/dist/index.cjs +624 -1
- package/dist/index.d.cts +83 -2
- package/dist/index.d.ts +83 -2
- package/dist/index.js +589 -2
- package/dist/src/{Types.d-uG0Hm1yK.d.ts → Types.d-BrHSyS03.d.cts} +17 -0
- package/dist/src/{Types.d-uG0Hm1yK.d.cts → Types.d-BrHSyS03.d.ts} +17 -0
- package/dist/src/accordion/index.cjs +159 -0
- package/dist/src/accordion/index.d.cts +19 -2
- package/dist/src/accordion/index.d.ts +19 -2
- package/dist/src/accordion/index.js +159 -1
- package/dist/src/block/index.cjs +1 -1
- package/dist/src/block/index.d.cts +6 -2
- package/dist/src/block/index.d.ts +6 -2
- package/dist/src/block/index.js +1 -1
- package/dist/src/checkbox/index.cjs +129 -0
- package/dist/src/checkbox/index.d.cts +15 -2
- package/dist/src/checkbox/index.d.ts +15 -2
- package/dist/src/checkbox/index.js +129 -1
- package/dist/src/combobox/index.d.cts +1 -1
- package/dist/src/combobox/index.d.ts +1 -1
- package/dist/src/menu/index.cjs +32 -0
- package/dist/src/menu/index.d.cts +1 -1
- package/dist/src/menu/index.d.ts +1 -1
- package/dist/src/menu/index.js +32 -0
- package/dist/src/radio/index.cjs +122 -0
- package/dist/src/radio/index.d.cts +17 -2
- package/dist/src/radio/index.d.ts +17 -2
- package/dist/src/radio/index.js +122 -1
- package/dist/src/toggle/index.cjs +145 -0
- package/dist/src/toggle/index.d.cts +17 -2
- package/dist/src/toggle/index.d.ts +17 -2
- package/dist/src/toggle/index.js +145 -1
- package/dist/src/utils/test/{contractTestRunnerPlaywright-4UOHWGWD.js → contractTestRunnerPlaywright-UQQI5MYS.js} +32 -0
- package/dist/src/utils/test/contracts/MenuContract.json +0 -1
- package/dist/src/utils/test/index.cjs +32 -0
- package/dist/src/utils/test/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -156,136 +156,255 @@ menu.refresh();
|
|
|
156
156
|
|
|
157
157
|
### 🪗 Accordion
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
Creates accessible accordions with keyboard navigation and automatic state management.
|
|
160
|
+
|
|
161
|
+
**Features:**
|
|
162
|
+
|
|
163
|
+
- Arrow key navigation between triggers
|
|
164
|
+
- Automatic ARIA attribute management
|
|
165
|
+
- Single or multiple panel expansion
|
|
166
|
+
- Enter/Space to toggle panels
|
|
167
|
+
- Home/End key support
|
|
160
168
|
|
|
161
169
|
```javascript
|
|
162
|
-
import {
|
|
170
|
+
import { makeAccordionAccessible } from "aria-ease/accordion";
|
|
171
|
+
|
|
172
|
+
// React Example
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
const accordion = makeAccordionAccessible({
|
|
175
|
+
accordionId: "accordion-container",
|
|
176
|
+
triggersClass: "accordion-trigger",
|
|
177
|
+
panelsClass: "accordion-panel",
|
|
178
|
+
allowMultiple: false, // Only one panel open at a time (default)
|
|
179
|
+
});
|
|
163
180
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
{ expanded: false },
|
|
167
|
-
{ expanded: false },
|
|
168
|
-
];
|
|
181
|
+
return () => accordion.cleanup();
|
|
182
|
+
}, []);
|
|
169
183
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
accordionStates, // State array
|
|
175
|
-
0, // Index of trigger that changed
|
|
176
|
-
);
|
|
184
|
+
// Programmatic control
|
|
185
|
+
accordion.expandItem(0); // Expand first panel
|
|
186
|
+
accordion.collapseItem(1); // Collapse second panel
|
|
187
|
+
accordion.toggleItem(2); // Toggle third panel
|
|
177
188
|
```
|
|
178
189
|
|
|
179
190
|
**HTML structure:**
|
|
180
191
|
|
|
181
192
|
```html
|
|
182
193
|
<div id="accordion-container">
|
|
183
|
-
<button
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
>
|
|
188
|
-
|
|
189
|
-
</button>
|
|
190
|
-
<div
|
|
191
|
-
|
|
192
|
-
<button
|
|
193
|
-
class="accordion-trigger"
|
|
194
|
-
aria-expanded="false"
|
|
195
|
-
aria-controls="panel-2"
|
|
196
|
-
>
|
|
197
|
-
Section 2
|
|
198
|
-
</button>
|
|
199
|
-
<div id="panel-2">Content 2</div>
|
|
194
|
+
<button class="accordion-trigger">Section 1</button>
|
|
195
|
+
<div class="accordion-panel">Content 1</div>
|
|
196
|
+
|
|
197
|
+
<button class="accordion-trigger">Section 2</button>
|
|
198
|
+
<div class="accordion-panel">Content 2</div>
|
|
199
|
+
|
|
200
|
+
<button class="accordion-trigger">Section 3</button>
|
|
201
|
+
<div class="accordion-panel">Content 3</div>
|
|
200
202
|
</div>
|
|
201
203
|
```
|
|
202
204
|
|
|
205
|
+
<details>
|
|
206
|
+
<summary>📌 Legacy API (Still Supported)</summary>
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
import { updateAccordionTriggerAriaAttributes } from "aria-ease/accordion";
|
|
210
|
+
|
|
211
|
+
const accordionStates = [{ display: true }, { display: false }];
|
|
212
|
+
|
|
213
|
+
updateAccordionTriggerAriaAttributes(
|
|
214
|
+
"accordion-container",
|
|
215
|
+
"accordion-trigger",
|
|
216
|
+
accordionStates,
|
|
217
|
+
0,
|
|
218
|
+
);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
</details>
|
|
222
|
+
|
|
203
223
|
---
|
|
204
224
|
|
|
205
225
|
### ✅ Checkbox
|
|
206
226
|
|
|
207
|
-
|
|
227
|
+
Creates accessible checkbox groups with keyboard navigation and state management.
|
|
228
|
+
|
|
229
|
+
**Features:**
|
|
230
|
+
|
|
231
|
+
- Arrow key navigation
|
|
232
|
+
- Space to toggle
|
|
233
|
+
- Independent state tracking
|
|
234
|
+
- Home/End key support
|
|
235
|
+
- Query checked states
|
|
208
236
|
|
|
209
237
|
```javascript
|
|
210
|
-
import {
|
|
238
|
+
import { makeCheckboxAccessible } from "aria-ease/checkbox";
|
|
211
239
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
);
|
|
228
|
-
}
|
|
240
|
+
// React Example
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
const checkboxGroup = makeCheckboxAccessible({
|
|
243
|
+
checkboxGroupId: "checkbox-group",
|
|
244
|
+
checkboxesClass: "custom-checkbox",
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return () => checkboxGroup.cleanup();
|
|
248
|
+
}, []);
|
|
249
|
+
|
|
250
|
+
// Programmatic control
|
|
251
|
+
checkboxGroup.toggleCheckbox(0); // Toggle first checkbox
|
|
252
|
+
checkboxGroup.setCheckboxState(1, true); // Check second checkbox
|
|
253
|
+
const states = checkboxGroup.getCheckedStates(); // [true, false, true]
|
|
254
|
+
const indices = checkboxGroup.getCheckedIndices(); // [0, 2]
|
|
229
255
|
```
|
|
230
256
|
|
|
231
257
|
**HTML structure:**
|
|
232
258
|
|
|
233
259
|
```html
|
|
234
260
|
<div id="checkbox-group">
|
|
235
|
-
<div
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
aria-checked="false"
|
|
239
|
-
aria-label="Option 1"
|
|
240
|
-
></div>
|
|
241
|
-
<div
|
|
242
|
-
class="custom-checkbox"
|
|
243
|
-
role="checkbox"
|
|
244
|
-
aria-checked="false"
|
|
245
|
-
aria-label="Option 2"
|
|
246
|
-
></div>
|
|
261
|
+
<div class="custom-checkbox" aria-label="Option 1"></div>
|
|
262
|
+
<div class="custom-checkbox" aria-label="Option 2"></div>
|
|
263
|
+
<div class="custom-checkbox" aria-label="Option 3"></div>
|
|
247
264
|
</div>
|
|
248
265
|
```
|
|
249
266
|
|
|
267
|
+
<details>
|
|
268
|
+
<summary>📌 Legacy API (Still Supported)</summary>
|
|
269
|
+
|
|
270
|
+
```javascript
|
|
271
|
+
import { updateCheckboxAriaAttributes } from "aria-ease/checkbox";
|
|
272
|
+
|
|
273
|
+
const checkboxStates = [{ checked: true }, { checked: false }];
|
|
274
|
+
|
|
275
|
+
updateCheckboxAriaAttributes(
|
|
276
|
+
"checkbox-group",
|
|
277
|
+
"custom-checkbox",
|
|
278
|
+
checkboxStates,
|
|
279
|
+
0,
|
|
280
|
+
);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
</details>
|
|
284
|
+
|
|
250
285
|
---
|
|
251
286
|
|
|
252
287
|
### 🔘 Radio Button
|
|
253
288
|
|
|
254
|
-
|
|
289
|
+
Creates accessible radio groups with keyboard navigation and automatic selection management.
|
|
255
290
|
|
|
256
|
-
|
|
257
|
-
|
|
291
|
+
**Features:**
|
|
292
|
+
|
|
293
|
+
- Arrow key navigation (all directions)
|
|
294
|
+
- Automatic unchecking of other radios
|
|
295
|
+
- Space to select
|
|
296
|
+
- Home/End key support
|
|
297
|
+
- Single selection enforcement
|
|
258
298
|
|
|
259
|
-
|
|
299
|
+
```javascript
|
|
300
|
+
import { makeRadioAccessible } from "aria-ease/radio";
|
|
260
301
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
302
|
+
// React Example
|
|
303
|
+
useEffect(() => {
|
|
304
|
+
const radioGroup = makeRadioAccessible({
|
|
305
|
+
radioGroupId: "radio-group",
|
|
306
|
+
radiosClass: "custom-radio",
|
|
307
|
+
defaultSelectedIndex: 0, // Initially selected (optional)
|
|
265
308
|
});
|
|
266
309
|
|
|
267
|
-
|
|
268
|
-
}
|
|
310
|
+
return () => radioGroup.cleanup();
|
|
311
|
+
}, []);
|
|
312
|
+
|
|
313
|
+
// Programmatic control
|
|
314
|
+
radioGroup.selectRadio(2); // Select third radio
|
|
315
|
+
const selected = radioGroup.getSelectedIndex(); // Get current selection
|
|
269
316
|
```
|
|
270
317
|
|
|
318
|
+
**HTML structure:**
|
|
319
|
+
|
|
320
|
+
```html
|
|
321
|
+
<div id="radio-group">
|
|
322
|
+
<div class="custom-radio" aria-label="Option 1"></div>
|
|
323
|
+
<div class="custom-radio" aria-label="Option 2"></div>
|
|
324
|
+
<div class="custom-radio" aria-label="Option 3"></div>
|
|
325
|
+
</div>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
<details>
|
|
329
|
+
<summary>📌 Legacy API (Still Supported)</summary>
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
import { updateRadioAriaAttributes } from "aria-ease/radio";
|
|
333
|
+
|
|
334
|
+
const radioStates = [{ checked: true }, { checked: false }];
|
|
335
|
+
|
|
336
|
+
updateRadioAriaAttributes("radio-group", "custom-radio", radioStates, 0);
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
</details>
|
|
340
|
+
|
|
271
341
|
---
|
|
272
342
|
|
|
273
343
|
### 🔀 Toggle Button
|
|
274
344
|
|
|
275
|
-
|
|
345
|
+
Creates accessible toggle buttons with keyboard interactions and state management.
|
|
346
|
+
|
|
347
|
+
**Features:**
|
|
348
|
+
|
|
349
|
+
- Enter/Space to toggle
|
|
350
|
+
- Single toggle or toggle groups
|
|
351
|
+
- Arrow key navigation (groups)
|
|
352
|
+
- Home/End support (groups)
|
|
353
|
+
- Query pressed states
|
|
276
354
|
|
|
277
355
|
```javascript
|
|
278
|
-
import {
|
|
356
|
+
import { makeToggleAccessible } from "aria-ease/toggle";
|
|
279
357
|
|
|
280
|
-
|
|
358
|
+
// Single toggle button
|
|
359
|
+
const toggle = makeToggleAccessible({
|
|
360
|
+
toggleId: "mute-button",
|
|
361
|
+
isSingleToggle: true,
|
|
362
|
+
});
|
|
281
363
|
|
|
282
|
-
|
|
283
|
-
|
|
364
|
+
// Toggle button group
|
|
365
|
+
const toggleGroup = makeToggleAccessible({
|
|
366
|
+
toggleId: "toolbar",
|
|
367
|
+
togglesClass: "toggle-btn",
|
|
368
|
+
isSingleToggle: false,
|
|
369
|
+
});
|
|
284
370
|
|
|
285
|
-
|
|
286
|
-
|
|
371
|
+
// Programmatic control
|
|
372
|
+
toggle.toggleButton(0); // Toggle the button
|
|
373
|
+
toggle.setPressed(0, true); // Set pressed state
|
|
374
|
+
const states = toggleGroup.getPressedStates(); // [false, true, false]
|
|
375
|
+
const indices = toggleGroup.getPressedIndices(); // [1]
|
|
376
|
+
|
|
377
|
+
// Cleanup
|
|
378
|
+
toggle.cleanup();
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**HTML structure:**
|
|
382
|
+
|
|
383
|
+
```html
|
|
384
|
+
<!-- Single toggle -->
|
|
385
|
+
<button id="mute-button">Mute</button>
|
|
386
|
+
|
|
387
|
+
<!-- Toggle group -->
|
|
388
|
+
<div id="toolbar">
|
|
389
|
+
<button class="toggle-btn">Bold</button>
|
|
390
|
+
<button class="toggle-btn">Italic</button>
|
|
391
|
+
<button class="toggle-btn">Underline</button>
|
|
392
|
+
</div>
|
|
287
393
|
```
|
|
288
394
|
|
|
395
|
+
<details>
|
|
396
|
+
<summary>📌 Legacy API (Still Supported)</summary>
|
|
397
|
+
|
|
398
|
+
```javascript
|
|
399
|
+
import { updateToggleAriaAttribute } from "aria-ease/toggle";
|
|
400
|
+
|
|
401
|
+
const toggleStates = [{ pressed: false }];
|
|
402
|
+
|
|
403
|
+
updateToggleAriaAttribute("toggle-container", "toggle-btn", toggleStates, 0);
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
</details>
|
|
407
|
+
|
|
289
408
|
---
|
|
290
409
|
|
|
291
410
|
### 🧱 Block (Generic Focusable Groups)
|
|
@@ -336,23 +455,24 @@ Aria-Ease is designed to be lightweight and tree-shakable:
|
|
|
336
455
|
|
|
337
456
|
| Import | Size (ESM) |
|
|
338
457
|
| ---------------------------- | --------------------- |
|
|
339
|
-
| `aria-ease/accordion` | ~
|
|
340
|
-
| `aria-ease/checkbox` | ~
|
|
341
|
-
| `aria-ease/radio` | ~
|
|
342
|
-
| `aria-ease/toggle` | ~
|
|
343
|
-
| `aria-ease/menu` | ~
|
|
458
|
+
| `aria-ease/accordion` | ~6.5KB |
|
|
459
|
+
| `aria-ease/checkbox` | ~6.0KB |
|
|
460
|
+
| `aria-ease/radio` | ~5.5KB |
|
|
461
|
+
| `aria-ease/toggle` | ~6.0KB |
|
|
462
|
+
| `aria-ease/menu` | ~6.7KB |
|
|
344
463
|
| `aria-ease/block` | ~1.7KB |
|
|
345
|
-
|
|
|
464
|
+
| `aria-ease/combobox` | ~8.1KB |
|
|
465
|
+
| Full bundle (all components) | ~459KB (uncompressed) |
|
|
346
466
|
|
|
347
467
|
**💡 Tip:** Always import individual components for optimal bundle size:
|
|
348
468
|
|
|
349
469
|
```javascript
|
|
350
|
-
// ✅ Good - only imports menu code (~
|
|
470
|
+
// ✅ Good - only imports menu code (~6.7KB)
|
|
351
471
|
import { makeMenuAccessible } from "aria-ease/menu";
|
|
352
472
|
//or
|
|
353
473
|
import * as Block from "aria-ease/block";
|
|
354
474
|
|
|
355
|
-
// ❌ Avoid - imports everything (~
|
|
475
|
+
// ❌ Avoid - imports everything (~459KB)
|
|
356
476
|
import { makeMenuAccessible } from "aria-ease";
|
|
357
477
|
```
|
|
358
478
|
|
package/bin/cli.cjs
CHANGED
|
@@ -13425,6 +13425,38 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13425
13425
|
}
|
|
13426
13426
|
}
|
|
13427
13427
|
}
|
|
13428
|
+
let shouldSkipTest = false;
|
|
13429
|
+
for (const act of action) {
|
|
13430
|
+
if (act.type === "keypress" && (act.target === "submenuTrigger" || act.target === "submenu")) {
|
|
13431
|
+
const submenuSelector = componentContract.selectors[act.target];
|
|
13432
|
+
if (submenuSelector) {
|
|
13433
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
13434
|
+
if (submenuCount === 0) {
|
|
13435
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
|
|
13436
|
+
shouldSkipTest = true;
|
|
13437
|
+
break;
|
|
13438
|
+
}
|
|
13439
|
+
}
|
|
13440
|
+
}
|
|
13441
|
+
}
|
|
13442
|
+
if (!shouldSkipTest) {
|
|
13443
|
+
for (const assertion of assertions) {
|
|
13444
|
+
if (assertion.target === "submenu" || assertion.target === "submenuTrigger") {
|
|
13445
|
+
const submenuSelector = componentContract.selectors[assertion.target];
|
|
13446
|
+
if (submenuSelector) {
|
|
13447
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
13448
|
+
if (submenuCount === 0) {
|
|
13449
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${assertion.target} element not found (optional submenu test)`);
|
|
13450
|
+
shouldSkipTest = true;
|
|
13451
|
+
break;
|
|
13452
|
+
}
|
|
13453
|
+
}
|
|
13454
|
+
}
|
|
13455
|
+
}
|
|
13456
|
+
}
|
|
13457
|
+
if (shouldSkipTest) {
|
|
13458
|
+
continue;
|
|
13459
|
+
}
|
|
13428
13460
|
for (const act of action) {
|
|
13429
13461
|
if (act.type === "focus") {
|
|
13430
13462
|
const focusSelector = componentContract.selectors[act.target];
|
package/bin/cli.js
CHANGED
|
@@ -204,7 +204,7 @@ program.command("audit").description("Run axe-core powered accessibility audit o
|
|
|
204
204
|
console.log(chalk.green("\n\u{1F389} All audits completed."));
|
|
205
205
|
});
|
|
206
206
|
program.command("test").description("Run core a11y accessibility standard tests on UI components").action(async () => {
|
|
207
|
-
const { runTest } = await import("./test-
|
|
207
|
+
const { runTest } = await import("./test-45KMD4F4.js");
|
|
208
208
|
runTest();
|
|
209
209
|
});
|
|
210
210
|
program.command("help").description("Display help information").action(() => {
|
package/bin/{contractTestRunnerPlaywright-3VJUZSYK.js → contractTestRunnerPlaywright-EZLNNJV5.js}
RENAMED
|
@@ -152,6 +152,38 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
let shouldSkipTest = false;
|
|
156
|
+
for (const act of action) {
|
|
157
|
+
if (act.type === "keypress" && (act.target === "submenuTrigger" || act.target === "submenu")) {
|
|
158
|
+
const submenuSelector = componentContract.selectors[act.target];
|
|
159
|
+
if (submenuSelector) {
|
|
160
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
161
|
+
if (submenuCount === 0) {
|
|
162
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
|
|
163
|
+
shouldSkipTest = true;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!shouldSkipTest) {
|
|
170
|
+
for (const assertion of assertions) {
|
|
171
|
+
if (assertion.target === "submenu" || assertion.target === "submenuTrigger") {
|
|
172
|
+
const submenuSelector = componentContract.selectors[assertion.target];
|
|
173
|
+
if (submenuSelector) {
|
|
174
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
175
|
+
if (submenuCount === 0) {
|
|
176
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${assertion.target} element not found (optional submenu test)`);
|
|
177
|
+
shouldSkipTest = true;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (shouldSkipTest) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
155
187
|
for (const act of action) {
|
|
156
188
|
if (act.type === "focus") {
|
|
157
189
|
const focusSelector = componentContract.selectors[act.target];
|
|
@@ -12776,7 +12776,7 @@ Error: ${error instanceof Error ? error.message : String(error)}`
|
|
|
12776
12776
|
URL must include protocol (e.g., "http://localhost:5173/test")`
|
|
12777
12777
|
);
|
|
12778
12778
|
}
|
|
12779
|
-
const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-
|
|
12779
|
+
const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-EZLNNJV5.js");
|
|
12780
12780
|
contract = await runContractTestsPlaywright(componentName, url);
|
|
12781
12781
|
} else {
|
|
12782
12782
|
console.log(`\u{1F9EA} Running jsdom tests (limited event handling)`);
|
package/dist/{contractTestRunnerPlaywright-4UOHWGWD.js → contractTestRunnerPlaywright-UQQI5MYS.js}
RENAMED
|
@@ -150,6 +150,38 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
let shouldSkipTest = false;
|
|
154
|
+
for (const act of action) {
|
|
155
|
+
if (act.type === "keypress" && (act.target === "submenuTrigger" || act.target === "submenu")) {
|
|
156
|
+
const submenuSelector = componentContract.selectors[act.target];
|
|
157
|
+
if (submenuSelector) {
|
|
158
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
159
|
+
if (submenuCount === 0) {
|
|
160
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
|
|
161
|
+
shouldSkipTest = true;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (!shouldSkipTest) {
|
|
168
|
+
for (const assertion of assertions) {
|
|
169
|
+
if (assertion.target === "submenu" || assertion.target === "submenuTrigger") {
|
|
170
|
+
const submenuSelector = componentContract.selectors[assertion.target];
|
|
171
|
+
if (submenuSelector) {
|
|
172
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
173
|
+
if (submenuCount === 0) {
|
|
174
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${assertion.target} element not found (optional submenu test)`);
|
|
175
|
+
shouldSkipTest = true;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (shouldSkipTest) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
153
185
|
for (const act of action) {
|
|
154
186
|
if (act.type === "focus") {
|
|
155
187
|
const focusSelector = componentContract.selectors[act.target];
|