aria-ease 4.0.1 → 5.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 +22 -24
- package/bin/cli.cjs +85 -13
- package/bin/cli.js +1 -1
- package/bin/{contractTestRunnerPlaywright-EZLNNJV5.js → contractTestRunnerPlaywright-YPBTKJP7.js} +85 -13
- package/bin/{test-45KMD4F4.js → test-TAH4VGZV.js} +1 -1
- package/dist/{contractTestRunnerPlaywright-UQQI5MYS.js → contractTestRunnerPlaywright-45CFWUOD.js} +85 -13
- package/dist/index.cjs +97 -157
- package/dist/index.d.cts +1 -57
- package/dist/index.d.ts +1 -57
- package/dist/index.js +12 -140
- package/dist/src/{Types.d-BrHSyS03.d.ts → Types.d-COr5IFp5.d.cts} +1 -17
- package/dist/src/{Types.d-BrHSyS03.d.cts → Types.d-COr5IFp5.d.ts} +1 -17
- package/dist/src/accordion/index.cjs +0 -27
- package/dist/src/accordion/index.d.cts +2 -12
- package/dist/src/accordion/index.d.ts +2 -12
- package/dist/src/accordion/index.js +1 -27
- 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 -32
- package/dist/src/checkbox/index.d.cts +2 -12
- package/dist/src/checkbox/index.d.ts +2 -12
- package/dist/src/checkbox/index.js +1 -32
- package/dist/src/combobox/index.cjs +1 -1
- package/dist/src/combobox/index.d.cts +1 -1
- package/dist/src/combobox/index.d.ts +1 -1
- package/dist/src/combobox/index.js +1 -1
- package/dist/src/menu/index.cjs +9 -18
- package/dist/src/menu/index.d.cts +1 -1
- package/dist/src/menu/index.d.ts +1 -1
- package/dist/src/menu/index.js +9 -18
- package/dist/src/radio/index.cjs +0 -31
- package/dist/src/radio/index.d.cts +2 -12
- package/dist/src/radio/index.d.ts +2 -12
- package/dist/src/radio/index.js +1 -31
- package/dist/src/toggle/index.cjs +0 -28
- package/dist/src/toggle/index.d.cts +2 -12
- package/dist/src/toggle/index.d.ts +2 -12
- package/dist/src/toggle/index.js +1 -28
- package/dist/src/utils/test/{contractTestRunnerPlaywright-UQQI5MYS.js → contractTestRunnerPlaywright-45CFWUOD.js} +85 -13
- package/dist/src/utils/test/contracts/AccordionContract.json +55 -0
- package/dist/src/utils/test/contracts/MenuContract.json +1 -1
- package/dist/src/utils/test/index.cjs +85 -13
- package/dist/src/utils/test/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -203,19 +203,19 @@ accordion.toggleItem(2); // Toggle third panel
|
|
|
203
203
|
```
|
|
204
204
|
|
|
205
205
|
<details>
|
|
206
|
-
<summary>📌 Legacy API
|
|
206
|
+
<summary>📌 Legacy API deprecated</summary>
|
|
207
207
|
|
|
208
208
|
```javascript
|
|
209
|
-
import {
|
|
209
|
+
import { makeAccordionAccessible } from "aria-ease/accordion";
|
|
210
210
|
|
|
211
211
|
const accordionStates = [{ display: true }, { display: false }];
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
);
|
|
213
|
+
makeAccordionAccessible({
|
|
214
|
+
accordionId: "faq-div",
|
|
215
|
+
triggersClass: "dropdown-button",
|
|
216
|
+
panelsClass: "accordion-panel",
|
|
217
|
+
allowMultiple: false, // Only one panel open at a time
|
|
218
|
+
});
|
|
219
219
|
```
|
|
220
220
|
|
|
221
221
|
</details>
|
|
@@ -265,19 +265,15 @@ const indices = checkboxGroup.getCheckedIndices(); // [0, 2]
|
|
|
265
265
|
```
|
|
266
266
|
|
|
267
267
|
<details>
|
|
268
|
-
<summary>📌 Legacy API
|
|
268
|
+
<summary>📌 Legacy API deprecated</summary>
|
|
269
269
|
|
|
270
270
|
```javascript
|
|
271
|
-
import {
|
|
272
|
-
|
|
273
|
-
const checkboxStates = [{ checked: true }, { checked: false }];
|
|
271
|
+
import { makeCheckboxAccessible } from "aria-ease/checkbox";
|
|
274
272
|
|
|
275
|
-
|
|
276
|
-
"checkbox-
|
|
277
|
-
"
|
|
278
|
-
|
|
279
|
-
0,
|
|
280
|
-
);
|
|
273
|
+
makeCheckboxAccessible({
|
|
274
|
+
checkboxGroupId: "checkbox-div",
|
|
275
|
+
checkboxesClass: "course-checkbox",
|
|
276
|
+
});
|
|
281
277
|
```
|
|
282
278
|
|
|
283
279
|
</details>
|
|
@@ -326,14 +322,16 @@ const selected = radioGroup.getSelectedIndex(); // Get current selection
|
|
|
326
322
|
```
|
|
327
323
|
|
|
328
324
|
<details>
|
|
329
|
-
<summary>📌 Legacy API
|
|
325
|
+
<summary>📌 Legacy API deprecated</summary>
|
|
330
326
|
|
|
331
327
|
```javascript
|
|
332
|
-
import {
|
|
333
|
-
|
|
334
|
-
const radioStates = [{ checked: true }, { checked: false }];
|
|
328
|
+
import { makeRadioAccessible } from "aria-ease/radio";
|
|
335
329
|
|
|
336
|
-
|
|
330
|
+
makeRadioAccessible({
|
|
331
|
+
radioGroupId: "radio-div",
|
|
332
|
+
radiosClass: "radio",
|
|
333
|
+
defaultSelectedIndex: 0, // Optional: which radio is selected initially
|
|
334
|
+
});
|
|
337
335
|
```
|
|
338
336
|
|
|
339
337
|
</details>
|
|
@@ -393,7 +391,7 @@ toggle.cleanup();
|
|
|
393
391
|
```
|
|
394
392
|
|
|
395
393
|
<details>
|
|
396
|
-
<summary>📌 Legacy API
|
|
394
|
+
<summary>📌 Legacy API deprecated</summary>
|
|
397
395
|
|
|
398
396
|
```javascript
|
|
399
397
|
import { updateToggleAriaAttribute } from "aria-ease/toggle";
|
package/bin/cli.cjs
CHANGED
|
@@ -13330,10 +13330,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13330
13330
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
13331
13331
|
},
|
|
13332
13332
|
componentContract.selectors.trigger,
|
|
13333
|
-
{ timeout:
|
|
13333
|
+
{ timeout: 1e4 }
|
|
13334
13334
|
).catch(() => {
|
|
13335
13335
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
13336
13336
|
});
|
|
13337
|
+
await page.waitForTimeout(300);
|
|
13337
13338
|
}
|
|
13338
13339
|
async function resolveRelativeTarget(selector, relative) {
|
|
13339
13340
|
const items = await page.locator(selector).all();
|
|
@@ -13411,18 +13412,84 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13411
13412
|
const popupElement = page.locator(popupSelector).first();
|
|
13412
13413
|
const isPopupVisible = await popupElement.isVisible();
|
|
13413
13414
|
if (isPopupVisible) {
|
|
13414
|
-
|
|
13415
|
+
let menuClosed = false;
|
|
13416
|
+
let closeSelector = componentContract.selectors.input;
|
|
13417
|
+
if (!closeSelector && componentContract.selectors.focusable) {
|
|
13418
|
+
closeSelector = componentContract.selectors.focusable;
|
|
13419
|
+
} else if (!closeSelector) {
|
|
13420
|
+
closeSelector = componentContract.selectors.trigger;
|
|
13421
|
+
}
|
|
13415
13422
|
if (closeSelector) {
|
|
13416
13423
|
const closeElement = page.locator(closeSelector).first();
|
|
13417
13424
|
await closeElement.focus();
|
|
13418
|
-
await page.keyboard.press("Escape");
|
|
13419
13425
|
await page.waitForTimeout(200);
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
|
|
13426
|
+
await page.keyboard.press("Escape");
|
|
13427
|
+
menuClosed = await page.waitForFunction(
|
|
13428
|
+
(selector) => {
|
|
13429
|
+
const popup = document.querySelector(selector);
|
|
13430
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
13431
|
+
},
|
|
13432
|
+
popupSelector,
|
|
13433
|
+
{ timeout: 3e3 }
|
|
13434
|
+
).then(() => true).catch(() => false);
|
|
13435
|
+
}
|
|
13436
|
+
if (!menuClosed && componentContract.selectors.trigger) {
|
|
13437
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
13438
|
+
await triggerElement.click();
|
|
13439
|
+
await page.waitForTimeout(500);
|
|
13440
|
+
menuClosed = await page.waitForFunction(
|
|
13441
|
+
(selector) => {
|
|
13442
|
+
const popup = document.querySelector(selector);
|
|
13443
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
13444
|
+
},
|
|
13445
|
+
popupSelector,
|
|
13446
|
+
{ timeout: 3e3 }
|
|
13447
|
+
).then(() => true).catch(() => false);
|
|
13448
|
+
}
|
|
13449
|
+
if (!menuClosed) {
|
|
13450
|
+
await page.mouse.click(10, 10);
|
|
13451
|
+
await page.waitForTimeout(500);
|
|
13452
|
+
menuClosed = await page.waitForFunction(
|
|
13453
|
+
(selector) => {
|
|
13454
|
+
const popup = document.querySelector(selector);
|
|
13455
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
13456
|
+
},
|
|
13457
|
+
popupSelector,
|
|
13458
|
+
{ timeout: 3e3 }
|
|
13459
|
+
).then(() => true).catch(() => false);
|
|
13460
|
+
if (menuClosed) {
|
|
13461
|
+
console.log("\u{1F3AF} Strategy 3 (Click outside) worked");
|
|
13424
13462
|
}
|
|
13425
13463
|
}
|
|
13464
|
+
if (!menuClosed) {
|
|
13465
|
+
throw new Error(
|
|
13466
|
+
`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
|
|
13467
|
+
1. Escape key
|
|
13468
|
+
2. Clicking trigger
|
|
13469
|
+
3. Clicking outside
|
|
13470
|
+
This indicates a problem with the menu component's close functionality.`
|
|
13471
|
+
);
|
|
13472
|
+
}
|
|
13473
|
+
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
13474
|
+
await page.waitForFunction(
|
|
13475
|
+
(selector) => {
|
|
13476
|
+
const trigger = document.querySelector(selector);
|
|
13477
|
+
return document.activeElement === trigger;
|
|
13478
|
+
},
|
|
13479
|
+
componentContract.selectors.trigger,
|
|
13480
|
+
{ timeout: 2e3 }
|
|
13481
|
+
).catch(async () => {
|
|
13482
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
13483
|
+
await triggerElement.focus();
|
|
13484
|
+
await page.waitForTimeout(200);
|
|
13485
|
+
});
|
|
13486
|
+
}
|
|
13487
|
+
await page.waitForTimeout(500);
|
|
13488
|
+
if (componentContract.selectors.input) {
|
|
13489
|
+
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
13490
|
+
await inputElement.clear();
|
|
13491
|
+
await page.waitForTimeout(100);
|
|
13492
|
+
}
|
|
13426
13493
|
}
|
|
13427
13494
|
}
|
|
13428
13495
|
let shouldSkipTest = false;
|
|
@@ -13491,7 +13558,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13491
13558
|
continue;
|
|
13492
13559
|
}
|
|
13493
13560
|
await relativeElement.click();
|
|
13494
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
13561
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
13495
13562
|
} else {
|
|
13496
13563
|
const actionSelector = componentContract.selectors[act.target];
|
|
13497
13564
|
if (!actionSelector) {
|
|
@@ -13499,7 +13566,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13499
13566
|
continue;
|
|
13500
13567
|
}
|
|
13501
13568
|
await page.locator(actionSelector).first().click();
|
|
13502
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
13569
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
13503
13570
|
}
|
|
13504
13571
|
}
|
|
13505
13572
|
if (act.type === "keypress" && act.key) {
|
|
@@ -13522,9 +13589,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13522
13589
|
keyValue = keyValue.replace(/ /g, "");
|
|
13523
13590
|
}
|
|
13524
13591
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
13525
|
-
await page.waitForTimeout(100);
|
|
13592
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
13526
13593
|
await page.keyboard.press(keyValue);
|
|
13527
|
-
await page.waitForTimeout(100);
|
|
13594
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
13528
13595
|
} else {
|
|
13529
13596
|
const keypressSelector = componentContract.selectors[act.target];
|
|
13530
13597
|
if (!keypressSelector) {
|
|
@@ -13564,8 +13631,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13564
13631
|
await page.waitForTimeout(100);
|
|
13565
13632
|
}
|
|
13566
13633
|
}
|
|
13567
|
-
await page.waitForTimeout(100);
|
|
13634
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
13568
13635
|
}
|
|
13636
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
13569
13637
|
for (const assertion of assertions) {
|
|
13570
13638
|
let target;
|
|
13571
13639
|
if (assertion.target === "relative") {
|
|
@@ -13663,7 +13731,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13663
13731
|
await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
|
|
13664
13732
|
passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
|
|
13665
13733
|
} catch {
|
|
13666
|
-
|
|
13734
|
+
const actualFocus = await page.evaluate(() => {
|
|
13735
|
+
const focused = document.activeElement;
|
|
13736
|
+
return focused ? `${focused.tagName}#${focused.id || "no-id"}.${focused.className || "no-class"}` : "no element focused";
|
|
13737
|
+
});
|
|
13738
|
+
failures.push(`${assertion.failureMessage} (actual focus: ${actualFocus})`);
|
|
13667
13739
|
}
|
|
13668
13740
|
}
|
|
13669
13741
|
if (assertion.assertion === "toHaveRole" && assertion.expectedValue) {
|
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-TAH4VGZV.js");
|
|
208
208
|
runTest();
|
|
209
209
|
});
|
|
210
210
|
program.command("help").description("Display help information").action(() => {
|
package/bin/{contractTestRunnerPlaywright-EZLNNJV5.js → contractTestRunnerPlaywright-YPBTKJP7.js}
RENAMED
|
@@ -57,10 +57,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
57
57
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
58
58
|
},
|
|
59
59
|
componentContract.selectors.trigger,
|
|
60
|
-
{ timeout:
|
|
60
|
+
{ timeout: 1e4 }
|
|
61
61
|
).catch(() => {
|
|
62
62
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
63
63
|
});
|
|
64
|
+
await page.waitForTimeout(300);
|
|
64
65
|
}
|
|
65
66
|
async function resolveRelativeTarget(selector, relative) {
|
|
66
67
|
const items = await page.locator(selector).all();
|
|
@@ -138,18 +139,84 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
138
139
|
const popupElement = page.locator(popupSelector).first();
|
|
139
140
|
const isPopupVisible = await popupElement.isVisible();
|
|
140
141
|
if (isPopupVisible) {
|
|
141
|
-
|
|
142
|
+
let menuClosed = false;
|
|
143
|
+
let closeSelector = componentContract.selectors.input;
|
|
144
|
+
if (!closeSelector && componentContract.selectors.focusable) {
|
|
145
|
+
closeSelector = componentContract.selectors.focusable;
|
|
146
|
+
} else if (!closeSelector) {
|
|
147
|
+
closeSelector = componentContract.selectors.trigger;
|
|
148
|
+
}
|
|
142
149
|
if (closeSelector) {
|
|
143
150
|
const closeElement = page.locator(closeSelector).first();
|
|
144
151
|
await closeElement.focus();
|
|
145
|
-
await page.keyboard.press("Escape");
|
|
146
152
|
await page.waitForTimeout(200);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
await page.keyboard.press("Escape");
|
|
154
|
+
menuClosed = await page.waitForFunction(
|
|
155
|
+
(selector) => {
|
|
156
|
+
const popup = document.querySelector(selector);
|
|
157
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
158
|
+
},
|
|
159
|
+
popupSelector,
|
|
160
|
+
{ timeout: 3e3 }
|
|
161
|
+
).then(() => true).catch(() => false);
|
|
162
|
+
}
|
|
163
|
+
if (!menuClosed && componentContract.selectors.trigger) {
|
|
164
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
165
|
+
await triggerElement.click();
|
|
166
|
+
await page.waitForTimeout(500);
|
|
167
|
+
menuClosed = await page.waitForFunction(
|
|
168
|
+
(selector) => {
|
|
169
|
+
const popup = document.querySelector(selector);
|
|
170
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
171
|
+
},
|
|
172
|
+
popupSelector,
|
|
173
|
+
{ timeout: 3e3 }
|
|
174
|
+
).then(() => true).catch(() => false);
|
|
175
|
+
}
|
|
176
|
+
if (!menuClosed) {
|
|
177
|
+
await page.mouse.click(10, 10);
|
|
178
|
+
await page.waitForTimeout(500);
|
|
179
|
+
menuClosed = await page.waitForFunction(
|
|
180
|
+
(selector) => {
|
|
181
|
+
const popup = document.querySelector(selector);
|
|
182
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
183
|
+
},
|
|
184
|
+
popupSelector,
|
|
185
|
+
{ timeout: 3e3 }
|
|
186
|
+
).then(() => true).catch(() => false);
|
|
187
|
+
if (menuClosed) {
|
|
188
|
+
console.log("\u{1F3AF} Strategy 3 (Click outside) worked");
|
|
151
189
|
}
|
|
152
190
|
}
|
|
191
|
+
if (!menuClosed) {
|
|
192
|
+
throw new Error(
|
|
193
|
+
`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
|
|
194
|
+
1. Escape key
|
|
195
|
+
2. Clicking trigger
|
|
196
|
+
3. Clicking outside
|
|
197
|
+
This indicates a problem with the menu component's close functionality.`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
201
|
+
await page.waitForFunction(
|
|
202
|
+
(selector) => {
|
|
203
|
+
const trigger = document.querySelector(selector);
|
|
204
|
+
return document.activeElement === trigger;
|
|
205
|
+
},
|
|
206
|
+
componentContract.selectors.trigger,
|
|
207
|
+
{ timeout: 2e3 }
|
|
208
|
+
).catch(async () => {
|
|
209
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
210
|
+
await triggerElement.focus();
|
|
211
|
+
await page.waitForTimeout(200);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
await page.waitForTimeout(500);
|
|
215
|
+
if (componentContract.selectors.input) {
|
|
216
|
+
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
217
|
+
await inputElement.clear();
|
|
218
|
+
await page.waitForTimeout(100);
|
|
219
|
+
}
|
|
153
220
|
}
|
|
154
221
|
}
|
|
155
222
|
let shouldSkipTest = false;
|
|
@@ -218,7 +285,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
218
285
|
continue;
|
|
219
286
|
}
|
|
220
287
|
await relativeElement.click();
|
|
221
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
288
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
222
289
|
} else {
|
|
223
290
|
const actionSelector = componentContract.selectors[act.target];
|
|
224
291
|
if (!actionSelector) {
|
|
@@ -226,7 +293,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
226
293
|
continue;
|
|
227
294
|
}
|
|
228
295
|
await page.locator(actionSelector).first().click();
|
|
229
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
296
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
230
297
|
}
|
|
231
298
|
}
|
|
232
299
|
if (act.type === "keypress" && act.key) {
|
|
@@ -249,9 +316,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
249
316
|
keyValue = keyValue.replace(/ /g, "");
|
|
250
317
|
}
|
|
251
318
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
252
|
-
await page.waitForTimeout(100);
|
|
319
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
253
320
|
await page.keyboard.press(keyValue);
|
|
254
|
-
await page.waitForTimeout(100);
|
|
321
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
255
322
|
} else {
|
|
256
323
|
const keypressSelector = componentContract.selectors[act.target];
|
|
257
324
|
if (!keypressSelector) {
|
|
@@ -291,8 +358,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
291
358
|
await page.waitForTimeout(100);
|
|
292
359
|
}
|
|
293
360
|
}
|
|
294
|
-
await page.waitForTimeout(100);
|
|
361
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
295
362
|
}
|
|
363
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
296
364
|
for (const assertion of assertions) {
|
|
297
365
|
let target;
|
|
298
366
|
if (assertion.target === "relative") {
|
|
@@ -390,7 +458,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
390
458
|
await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
|
|
391
459
|
passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
|
|
392
460
|
} catch {
|
|
393
|
-
|
|
461
|
+
const actualFocus = await page.evaluate(() => {
|
|
462
|
+
const focused = document.activeElement;
|
|
463
|
+
return focused ? `${focused.tagName}#${focused.id || "no-id"}.${focused.className || "no-class"}` : "no element focused";
|
|
464
|
+
});
|
|
465
|
+
failures.push(`${assertion.failureMessage} (actual focus: ${actualFocus})`);
|
|
394
466
|
}
|
|
395
467
|
}
|
|
396
468
|
if (assertion.assertion === "toHaveRole" && assertion.expectedValue) {
|
|
@@ -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-YPBTKJP7.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-UQQI5MYS.js → contractTestRunnerPlaywright-45CFWUOD.js}
RENAMED
|
@@ -55,10 +55,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
55
55
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
56
56
|
},
|
|
57
57
|
componentContract.selectors.trigger,
|
|
58
|
-
{ timeout:
|
|
58
|
+
{ timeout: 1e4 }
|
|
59
59
|
).catch(() => {
|
|
60
60
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
61
61
|
});
|
|
62
|
+
await page.waitForTimeout(300);
|
|
62
63
|
}
|
|
63
64
|
async function resolveRelativeTarget(selector, relative) {
|
|
64
65
|
const items = await page.locator(selector).all();
|
|
@@ -136,18 +137,84 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
136
137
|
const popupElement = page.locator(popupSelector).first();
|
|
137
138
|
const isPopupVisible = await popupElement.isVisible();
|
|
138
139
|
if (isPopupVisible) {
|
|
139
|
-
|
|
140
|
+
let menuClosed = false;
|
|
141
|
+
let closeSelector = componentContract.selectors.input;
|
|
142
|
+
if (!closeSelector && componentContract.selectors.focusable) {
|
|
143
|
+
closeSelector = componentContract.selectors.focusable;
|
|
144
|
+
} else if (!closeSelector) {
|
|
145
|
+
closeSelector = componentContract.selectors.trigger;
|
|
146
|
+
}
|
|
140
147
|
if (closeSelector) {
|
|
141
148
|
const closeElement = page.locator(closeSelector).first();
|
|
142
149
|
await closeElement.focus();
|
|
143
|
-
await page.keyboard.press("Escape");
|
|
144
150
|
await page.waitForTimeout(200);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
await page.keyboard.press("Escape");
|
|
152
|
+
menuClosed = await page.waitForFunction(
|
|
153
|
+
(selector) => {
|
|
154
|
+
const popup = document.querySelector(selector);
|
|
155
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
156
|
+
},
|
|
157
|
+
popupSelector,
|
|
158
|
+
{ timeout: 3e3 }
|
|
159
|
+
).then(() => true).catch(() => false);
|
|
160
|
+
}
|
|
161
|
+
if (!menuClosed && componentContract.selectors.trigger) {
|
|
162
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
163
|
+
await triggerElement.click();
|
|
164
|
+
await page.waitForTimeout(500);
|
|
165
|
+
menuClosed = await page.waitForFunction(
|
|
166
|
+
(selector) => {
|
|
167
|
+
const popup = document.querySelector(selector);
|
|
168
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
169
|
+
},
|
|
170
|
+
popupSelector,
|
|
171
|
+
{ timeout: 3e3 }
|
|
172
|
+
).then(() => true).catch(() => false);
|
|
173
|
+
}
|
|
174
|
+
if (!menuClosed) {
|
|
175
|
+
await page.mouse.click(10, 10);
|
|
176
|
+
await page.waitForTimeout(500);
|
|
177
|
+
menuClosed = await page.waitForFunction(
|
|
178
|
+
(selector) => {
|
|
179
|
+
const popup = document.querySelector(selector);
|
|
180
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
181
|
+
},
|
|
182
|
+
popupSelector,
|
|
183
|
+
{ timeout: 3e3 }
|
|
184
|
+
).then(() => true).catch(() => false);
|
|
185
|
+
if (menuClosed) {
|
|
186
|
+
console.log("\u{1F3AF} Strategy 3 (Click outside) worked");
|
|
149
187
|
}
|
|
150
188
|
}
|
|
189
|
+
if (!menuClosed) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
|
|
192
|
+
1. Escape key
|
|
193
|
+
2. Clicking trigger
|
|
194
|
+
3. Clicking outside
|
|
195
|
+
This indicates a problem with the menu component's close functionality.`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
199
|
+
await page.waitForFunction(
|
|
200
|
+
(selector) => {
|
|
201
|
+
const trigger = document.querySelector(selector);
|
|
202
|
+
return document.activeElement === trigger;
|
|
203
|
+
},
|
|
204
|
+
componentContract.selectors.trigger,
|
|
205
|
+
{ timeout: 2e3 }
|
|
206
|
+
).catch(async () => {
|
|
207
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
208
|
+
await triggerElement.focus();
|
|
209
|
+
await page.waitForTimeout(200);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
await page.waitForTimeout(500);
|
|
213
|
+
if (componentContract.selectors.input) {
|
|
214
|
+
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
215
|
+
await inputElement.clear();
|
|
216
|
+
await page.waitForTimeout(100);
|
|
217
|
+
}
|
|
151
218
|
}
|
|
152
219
|
}
|
|
153
220
|
let shouldSkipTest = false;
|
|
@@ -216,7 +283,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
216
283
|
continue;
|
|
217
284
|
}
|
|
218
285
|
await relativeElement.click();
|
|
219
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
286
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
220
287
|
} else {
|
|
221
288
|
const actionSelector = componentContract.selectors[act.target];
|
|
222
289
|
if (!actionSelector) {
|
|
@@ -224,7 +291,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
224
291
|
continue;
|
|
225
292
|
}
|
|
226
293
|
await page.locator(actionSelector).first().click();
|
|
227
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
294
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
228
295
|
}
|
|
229
296
|
}
|
|
230
297
|
if (act.type === "keypress" && act.key) {
|
|
@@ -247,9 +314,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
247
314
|
keyValue = keyValue.replace(/ /g, "");
|
|
248
315
|
}
|
|
249
316
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
250
|
-
await page.waitForTimeout(100);
|
|
317
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
251
318
|
await page.keyboard.press(keyValue);
|
|
252
|
-
await page.waitForTimeout(100);
|
|
319
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
253
320
|
} else {
|
|
254
321
|
const keypressSelector = componentContract.selectors[act.target];
|
|
255
322
|
if (!keypressSelector) {
|
|
@@ -289,8 +356,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
289
356
|
await page.waitForTimeout(100);
|
|
290
357
|
}
|
|
291
358
|
}
|
|
292
|
-
await page.waitForTimeout(100);
|
|
359
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
293
360
|
}
|
|
361
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
294
362
|
for (const assertion of assertions) {
|
|
295
363
|
let target;
|
|
296
364
|
if (assertion.target === "relative") {
|
|
@@ -388,7 +456,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
388
456
|
await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
|
|
389
457
|
passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
|
|
390
458
|
} catch {
|
|
391
|
-
|
|
459
|
+
const actualFocus = await page.evaluate(() => {
|
|
460
|
+
const focused = document.activeElement;
|
|
461
|
+
return focused ? `${focused.tagName}#${focused.id || "no-id"}.${focused.className || "no-class"}` : "no element focused";
|
|
462
|
+
});
|
|
463
|
+
failures.push(`${assertion.failureMessage} (actual focus: ${actualFocus})`);
|
|
392
464
|
}
|
|
393
465
|
}
|
|
394
466
|
if (assertion.assertion === "toHaveRole" && assertion.expectedValue) {
|