aria-ease 5.0.0 → 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/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 +85 -13
- package/dist/index.js +1 -1
- package/dist/src/utils/test/{contractTestRunnerPlaywright-UQQI5MYS.js → contractTestRunnerPlaywright-45CFWUOD.js} +85 -13
- package/dist/src/utils/test/index.cjs +85 -13
- package/dist/src/utils/test/index.js +1 -1
- package/package.json +1 -1
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) {
|
package/dist/index.cjs
CHANGED
|
@@ -9455,10 +9455,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9455
9455
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
9456
9456
|
},
|
|
9457
9457
|
componentContract.selectors.trigger,
|
|
9458
|
-
{ timeout:
|
|
9458
|
+
{ timeout: 1e4 }
|
|
9459
9459
|
).catch(() => {
|
|
9460
9460
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
9461
9461
|
});
|
|
9462
|
+
await page.waitForTimeout(300);
|
|
9462
9463
|
}
|
|
9463
9464
|
async function resolveRelativeTarget(selector, relative) {
|
|
9464
9465
|
const items = await page.locator(selector).all();
|
|
@@ -9536,18 +9537,84 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9536
9537
|
const popupElement = page.locator(popupSelector).first();
|
|
9537
9538
|
const isPopupVisible = await popupElement.isVisible();
|
|
9538
9539
|
if (isPopupVisible) {
|
|
9539
|
-
|
|
9540
|
+
let menuClosed = false;
|
|
9541
|
+
let closeSelector = componentContract.selectors.input;
|
|
9542
|
+
if (!closeSelector && componentContract.selectors.focusable) {
|
|
9543
|
+
closeSelector = componentContract.selectors.focusable;
|
|
9544
|
+
} else if (!closeSelector) {
|
|
9545
|
+
closeSelector = componentContract.selectors.trigger;
|
|
9546
|
+
}
|
|
9540
9547
|
if (closeSelector) {
|
|
9541
9548
|
const closeElement = page.locator(closeSelector).first();
|
|
9542
9549
|
await closeElement.focus();
|
|
9543
|
-
await page.keyboard.press("Escape");
|
|
9544
9550
|
await page.waitForTimeout(200);
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9551
|
+
await page.keyboard.press("Escape");
|
|
9552
|
+
menuClosed = await page.waitForFunction(
|
|
9553
|
+
(selector) => {
|
|
9554
|
+
const popup = document.querySelector(selector);
|
|
9555
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
9556
|
+
},
|
|
9557
|
+
popupSelector,
|
|
9558
|
+
{ timeout: 3e3 }
|
|
9559
|
+
).then(() => true).catch(() => false);
|
|
9560
|
+
}
|
|
9561
|
+
if (!menuClosed && componentContract.selectors.trigger) {
|
|
9562
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
9563
|
+
await triggerElement.click();
|
|
9564
|
+
await page.waitForTimeout(500);
|
|
9565
|
+
menuClosed = await page.waitForFunction(
|
|
9566
|
+
(selector) => {
|
|
9567
|
+
const popup = document.querySelector(selector);
|
|
9568
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
9569
|
+
},
|
|
9570
|
+
popupSelector,
|
|
9571
|
+
{ timeout: 3e3 }
|
|
9572
|
+
).then(() => true).catch(() => false);
|
|
9573
|
+
}
|
|
9574
|
+
if (!menuClosed) {
|
|
9575
|
+
await page.mouse.click(10, 10);
|
|
9576
|
+
await page.waitForTimeout(500);
|
|
9577
|
+
menuClosed = await page.waitForFunction(
|
|
9578
|
+
(selector) => {
|
|
9579
|
+
const popup = document.querySelector(selector);
|
|
9580
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
9581
|
+
},
|
|
9582
|
+
popupSelector,
|
|
9583
|
+
{ timeout: 3e3 }
|
|
9584
|
+
).then(() => true).catch(() => false);
|
|
9585
|
+
if (menuClosed) {
|
|
9586
|
+
console.log("\u{1F3AF} Strategy 3 (Click outside) worked");
|
|
9549
9587
|
}
|
|
9550
9588
|
}
|
|
9589
|
+
if (!menuClosed) {
|
|
9590
|
+
throw new Error(
|
|
9591
|
+
`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
|
|
9592
|
+
1. Escape key
|
|
9593
|
+
2. Clicking trigger
|
|
9594
|
+
3. Clicking outside
|
|
9595
|
+
This indicates a problem with the menu component's close functionality.`
|
|
9596
|
+
);
|
|
9597
|
+
}
|
|
9598
|
+
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
9599
|
+
await page.waitForFunction(
|
|
9600
|
+
(selector) => {
|
|
9601
|
+
const trigger = document.querySelector(selector);
|
|
9602
|
+
return document.activeElement === trigger;
|
|
9603
|
+
},
|
|
9604
|
+
componentContract.selectors.trigger,
|
|
9605
|
+
{ timeout: 2e3 }
|
|
9606
|
+
).catch(async () => {
|
|
9607
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
9608
|
+
await triggerElement.focus();
|
|
9609
|
+
await page.waitForTimeout(200);
|
|
9610
|
+
});
|
|
9611
|
+
}
|
|
9612
|
+
await page.waitForTimeout(500);
|
|
9613
|
+
if (componentContract.selectors.input) {
|
|
9614
|
+
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
9615
|
+
await inputElement.clear();
|
|
9616
|
+
await page.waitForTimeout(100);
|
|
9617
|
+
}
|
|
9551
9618
|
}
|
|
9552
9619
|
}
|
|
9553
9620
|
let shouldSkipTest = false;
|
|
@@ -9616,7 +9683,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9616
9683
|
continue;
|
|
9617
9684
|
}
|
|
9618
9685
|
await relativeElement.click();
|
|
9619
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
9686
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
9620
9687
|
} else {
|
|
9621
9688
|
const actionSelector = componentContract.selectors[act.target];
|
|
9622
9689
|
if (!actionSelector) {
|
|
@@ -9624,7 +9691,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9624
9691
|
continue;
|
|
9625
9692
|
}
|
|
9626
9693
|
await page.locator(actionSelector).first().click();
|
|
9627
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
9694
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
9628
9695
|
}
|
|
9629
9696
|
}
|
|
9630
9697
|
if (act.type === "keypress" && act.key) {
|
|
@@ -9647,9 +9714,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9647
9714
|
keyValue = keyValue.replace(/ /g, "");
|
|
9648
9715
|
}
|
|
9649
9716
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
9650
|
-
await page.waitForTimeout(100);
|
|
9717
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
9651
9718
|
await page.keyboard.press(keyValue);
|
|
9652
|
-
await page.waitForTimeout(100);
|
|
9719
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
9653
9720
|
} else {
|
|
9654
9721
|
const keypressSelector = componentContract.selectors[act.target];
|
|
9655
9722
|
if (!keypressSelector) {
|
|
@@ -9689,8 +9756,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9689
9756
|
await page.waitForTimeout(100);
|
|
9690
9757
|
}
|
|
9691
9758
|
}
|
|
9692
|
-
await page.waitForTimeout(100);
|
|
9759
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
9693
9760
|
}
|
|
9761
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
9694
9762
|
for (const assertion of assertions) {
|
|
9695
9763
|
let target;
|
|
9696
9764
|
if (assertion.target === "relative") {
|
|
@@ -9788,7 +9856,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9788
9856
|
await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
|
|
9789
9857
|
passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
|
|
9790
9858
|
} catch {
|
|
9791
|
-
|
|
9859
|
+
const actualFocus = await page.evaluate(() => {
|
|
9860
|
+
const focused = document.activeElement;
|
|
9861
|
+
return focused ? `${focused.tagName}#${focused.id || "no-id"}.${focused.className || "no-class"}` : "no element focused";
|
|
9862
|
+
});
|
|
9863
|
+
failures.push(`${assertion.failureMessage} (actual focus: ${actualFocus})`);
|
|
9792
9864
|
}
|
|
9793
9865
|
}
|
|
9794
9866
|
if (assertion.assertion === "toHaveRole" && assertion.expectedValue) {
|
package/dist/index.js
CHANGED
|
@@ -13939,7 +13939,7 @@ Error: ${error instanceof Error ? error.message : String(error)}`
|
|
|
13939
13939
|
URL must include protocol (e.g., "http://localhost:5173/test")`
|
|
13940
13940
|
);
|
|
13941
13941
|
}
|
|
13942
|
-
const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-
|
|
13942
|
+
const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-45CFWUOD.js");
|
|
13943
13943
|
contract = await runContractTestsPlaywright(componentName, url);
|
|
13944
13944
|
} else {
|
|
13945
13945
|
console.log(`\u{1F9EA} Running jsdom tests (limited event handling)`);
|
|
@@ -46,10 +46,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
46
46
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
47
47
|
},
|
|
48
48
|
componentContract.selectors.trigger,
|
|
49
|
-
{ timeout:
|
|
49
|
+
{ timeout: 1e4 }
|
|
50
50
|
).catch(() => {
|
|
51
51
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
52
52
|
});
|
|
53
|
+
await page.waitForTimeout(300);
|
|
53
54
|
}
|
|
54
55
|
async function resolveRelativeTarget(selector, relative) {
|
|
55
56
|
const items = await page.locator(selector).all();
|
|
@@ -127,18 +128,84 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
127
128
|
const popupElement = page.locator(popupSelector).first();
|
|
128
129
|
const isPopupVisible = await popupElement.isVisible();
|
|
129
130
|
if (isPopupVisible) {
|
|
130
|
-
|
|
131
|
+
let menuClosed = false;
|
|
132
|
+
let closeSelector = componentContract.selectors.input;
|
|
133
|
+
if (!closeSelector && componentContract.selectors.focusable) {
|
|
134
|
+
closeSelector = componentContract.selectors.focusable;
|
|
135
|
+
} else if (!closeSelector) {
|
|
136
|
+
closeSelector = componentContract.selectors.trigger;
|
|
137
|
+
}
|
|
131
138
|
if (closeSelector) {
|
|
132
139
|
const closeElement = page.locator(closeSelector).first();
|
|
133
140
|
await closeElement.focus();
|
|
134
|
-
await page.keyboard.press("Escape");
|
|
135
141
|
await page.waitForTimeout(200);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
await page.keyboard.press("Escape");
|
|
143
|
+
menuClosed = await page.waitForFunction(
|
|
144
|
+
(selector) => {
|
|
145
|
+
const popup = document.querySelector(selector);
|
|
146
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
147
|
+
},
|
|
148
|
+
popupSelector,
|
|
149
|
+
{ timeout: 3e3 }
|
|
150
|
+
).then(() => true).catch(() => false);
|
|
151
|
+
}
|
|
152
|
+
if (!menuClosed && componentContract.selectors.trigger) {
|
|
153
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
154
|
+
await triggerElement.click();
|
|
155
|
+
await page.waitForTimeout(500);
|
|
156
|
+
menuClosed = await page.waitForFunction(
|
|
157
|
+
(selector) => {
|
|
158
|
+
const popup = document.querySelector(selector);
|
|
159
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
160
|
+
},
|
|
161
|
+
popupSelector,
|
|
162
|
+
{ timeout: 3e3 }
|
|
163
|
+
).then(() => true).catch(() => false);
|
|
164
|
+
}
|
|
165
|
+
if (!menuClosed) {
|
|
166
|
+
await page.mouse.click(10, 10);
|
|
167
|
+
await page.waitForTimeout(500);
|
|
168
|
+
menuClosed = await page.waitForFunction(
|
|
169
|
+
(selector) => {
|
|
170
|
+
const popup = document.querySelector(selector);
|
|
171
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
172
|
+
},
|
|
173
|
+
popupSelector,
|
|
174
|
+
{ timeout: 3e3 }
|
|
175
|
+
).then(() => true).catch(() => false);
|
|
176
|
+
if (menuClosed) {
|
|
177
|
+
console.log("\u{1F3AF} Strategy 3 (Click outside) worked");
|
|
140
178
|
}
|
|
141
179
|
}
|
|
180
|
+
if (!menuClosed) {
|
|
181
|
+
throw new Error(
|
|
182
|
+
`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
|
|
183
|
+
1. Escape key
|
|
184
|
+
2. Clicking trigger
|
|
185
|
+
3. Clicking outside
|
|
186
|
+
This indicates a problem with the menu component's close functionality.`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
190
|
+
await page.waitForFunction(
|
|
191
|
+
(selector) => {
|
|
192
|
+
const trigger = document.querySelector(selector);
|
|
193
|
+
return document.activeElement === trigger;
|
|
194
|
+
},
|
|
195
|
+
componentContract.selectors.trigger,
|
|
196
|
+
{ timeout: 2e3 }
|
|
197
|
+
).catch(async () => {
|
|
198
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
199
|
+
await triggerElement.focus();
|
|
200
|
+
await page.waitForTimeout(200);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
await page.waitForTimeout(500);
|
|
204
|
+
if (componentContract.selectors.input) {
|
|
205
|
+
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
206
|
+
await inputElement.clear();
|
|
207
|
+
await page.waitForTimeout(100);
|
|
208
|
+
}
|
|
142
209
|
}
|
|
143
210
|
}
|
|
144
211
|
let shouldSkipTest = false;
|
|
@@ -207,7 +274,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
207
274
|
continue;
|
|
208
275
|
}
|
|
209
276
|
await relativeElement.click();
|
|
210
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
277
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
211
278
|
} else {
|
|
212
279
|
const actionSelector = componentContract.selectors[act.target];
|
|
213
280
|
if (!actionSelector) {
|
|
@@ -215,7 +282,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
215
282
|
continue;
|
|
216
283
|
}
|
|
217
284
|
await page.locator(actionSelector).first().click();
|
|
218
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
285
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
219
286
|
}
|
|
220
287
|
}
|
|
221
288
|
if (act.type === "keypress" && act.key) {
|
|
@@ -238,9 +305,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
238
305
|
keyValue = keyValue.replace(/ /g, "");
|
|
239
306
|
}
|
|
240
307
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
241
|
-
await page.waitForTimeout(100);
|
|
308
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
242
309
|
await page.keyboard.press(keyValue);
|
|
243
|
-
await page.waitForTimeout(100);
|
|
310
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
244
311
|
} else {
|
|
245
312
|
const keypressSelector = componentContract.selectors[act.target];
|
|
246
313
|
if (!keypressSelector) {
|
|
@@ -280,8 +347,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
280
347
|
await page.waitForTimeout(100);
|
|
281
348
|
}
|
|
282
349
|
}
|
|
283
|
-
await page.waitForTimeout(100);
|
|
350
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
284
351
|
}
|
|
352
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
285
353
|
for (const assertion of assertions) {
|
|
286
354
|
let target;
|
|
287
355
|
if (assertion.target === "relative") {
|
|
@@ -379,7 +447,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
379
447
|
await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
|
|
380
448
|
passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
|
|
381
449
|
} catch {
|
|
382
|
-
|
|
450
|
+
const actualFocus = await page.evaluate(() => {
|
|
451
|
+
const focused = document.activeElement;
|
|
452
|
+
return focused ? `${focused.tagName}#${focused.id || "no-id"}.${focused.className || "no-class"}` : "no element focused";
|
|
453
|
+
});
|
|
454
|
+
failures.push(`${assertion.failureMessage} (actual focus: ${actualFocus})`);
|
|
383
455
|
}
|
|
384
456
|
}
|
|
385
457
|
if (assertion.assertion === "toHaveRole" && assertion.expectedValue) {
|
|
@@ -9310,10 +9310,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9310
9310
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
9311
9311
|
},
|
|
9312
9312
|
componentContract.selectors.trigger,
|
|
9313
|
-
{ timeout:
|
|
9313
|
+
{ timeout: 1e4 }
|
|
9314
9314
|
).catch(() => {
|
|
9315
9315
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
9316
9316
|
});
|
|
9317
|
+
await page.waitForTimeout(300);
|
|
9317
9318
|
}
|
|
9318
9319
|
async function resolveRelativeTarget(selector, relative) {
|
|
9319
9320
|
const items = await page.locator(selector).all();
|
|
@@ -9391,18 +9392,84 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9391
9392
|
const popupElement = page.locator(popupSelector).first();
|
|
9392
9393
|
const isPopupVisible = await popupElement.isVisible();
|
|
9393
9394
|
if (isPopupVisible) {
|
|
9394
|
-
|
|
9395
|
+
let menuClosed = false;
|
|
9396
|
+
let closeSelector = componentContract.selectors.input;
|
|
9397
|
+
if (!closeSelector && componentContract.selectors.focusable) {
|
|
9398
|
+
closeSelector = componentContract.selectors.focusable;
|
|
9399
|
+
} else if (!closeSelector) {
|
|
9400
|
+
closeSelector = componentContract.selectors.trigger;
|
|
9401
|
+
}
|
|
9395
9402
|
if (closeSelector) {
|
|
9396
9403
|
const closeElement = page.locator(closeSelector).first();
|
|
9397
9404
|
await closeElement.focus();
|
|
9398
|
-
await page.keyboard.press("Escape");
|
|
9399
9405
|
await page.waitForTimeout(200);
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9406
|
+
await page.keyboard.press("Escape");
|
|
9407
|
+
menuClosed = await page.waitForFunction(
|
|
9408
|
+
(selector) => {
|
|
9409
|
+
const popup = document.querySelector(selector);
|
|
9410
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
9411
|
+
},
|
|
9412
|
+
popupSelector,
|
|
9413
|
+
{ timeout: 3e3 }
|
|
9414
|
+
).then(() => true).catch(() => false);
|
|
9415
|
+
}
|
|
9416
|
+
if (!menuClosed && componentContract.selectors.trigger) {
|
|
9417
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
9418
|
+
await triggerElement.click();
|
|
9419
|
+
await page.waitForTimeout(500);
|
|
9420
|
+
menuClosed = await page.waitForFunction(
|
|
9421
|
+
(selector) => {
|
|
9422
|
+
const popup = document.querySelector(selector);
|
|
9423
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
9424
|
+
},
|
|
9425
|
+
popupSelector,
|
|
9426
|
+
{ timeout: 3e3 }
|
|
9427
|
+
).then(() => true).catch(() => false);
|
|
9428
|
+
}
|
|
9429
|
+
if (!menuClosed) {
|
|
9430
|
+
await page.mouse.click(10, 10);
|
|
9431
|
+
await page.waitForTimeout(500);
|
|
9432
|
+
menuClosed = await page.waitForFunction(
|
|
9433
|
+
(selector) => {
|
|
9434
|
+
const popup = document.querySelector(selector);
|
|
9435
|
+
return popup && getComputedStyle(popup).display === "none";
|
|
9436
|
+
},
|
|
9437
|
+
popupSelector,
|
|
9438
|
+
{ timeout: 3e3 }
|
|
9439
|
+
).then(() => true).catch(() => false);
|
|
9440
|
+
if (menuClosed) {
|
|
9441
|
+
console.log("\u{1F3AF} Strategy 3 (Click outside) worked");
|
|
9404
9442
|
}
|
|
9405
9443
|
}
|
|
9444
|
+
if (!menuClosed) {
|
|
9445
|
+
throw new Error(
|
|
9446
|
+
`\u274C FATAL: Cannot close menu between tests. Menu remains visible after trying:
|
|
9447
|
+
1. Escape key
|
|
9448
|
+
2. Clicking trigger
|
|
9449
|
+
3. Clicking outside
|
|
9450
|
+
This indicates a problem with the menu component's close functionality.`
|
|
9451
|
+
);
|
|
9452
|
+
}
|
|
9453
|
+
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
9454
|
+
await page.waitForFunction(
|
|
9455
|
+
(selector) => {
|
|
9456
|
+
const trigger = document.querySelector(selector);
|
|
9457
|
+
return document.activeElement === trigger;
|
|
9458
|
+
},
|
|
9459
|
+
componentContract.selectors.trigger,
|
|
9460
|
+
{ timeout: 2e3 }
|
|
9461
|
+
).catch(async () => {
|
|
9462
|
+
const triggerElement = page.locator(componentContract.selectors.trigger).first();
|
|
9463
|
+
await triggerElement.focus();
|
|
9464
|
+
await page.waitForTimeout(200);
|
|
9465
|
+
});
|
|
9466
|
+
}
|
|
9467
|
+
await page.waitForTimeout(500);
|
|
9468
|
+
if (componentContract.selectors.input) {
|
|
9469
|
+
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
9470
|
+
await inputElement.clear();
|
|
9471
|
+
await page.waitForTimeout(100);
|
|
9472
|
+
}
|
|
9406
9473
|
}
|
|
9407
9474
|
}
|
|
9408
9475
|
let shouldSkipTest = false;
|
|
@@ -9471,7 +9538,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9471
9538
|
continue;
|
|
9472
9539
|
}
|
|
9473
9540
|
await relativeElement.click();
|
|
9474
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
9541
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
9475
9542
|
} else {
|
|
9476
9543
|
const actionSelector = componentContract.selectors[act.target];
|
|
9477
9544
|
if (!actionSelector) {
|
|
@@ -9479,7 +9546,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9479
9546
|
continue;
|
|
9480
9547
|
}
|
|
9481
9548
|
await page.locator(actionSelector).first().click();
|
|
9482
|
-
await page.waitForTimeout(componentName === "menu" ?
|
|
9549
|
+
await page.waitForTimeout(componentName === "menu" ? 800 : 200);
|
|
9483
9550
|
}
|
|
9484
9551
|
}
|
|
9485
9552
|
if (act.type === "keypress" && act.key) {
|
|
@@ -9502,9 +9569,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9502
9569
|
keyValue = keyValue.replace(/ /g, "");
|
|
9503
9570
|
}
|
|
9504
9571
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
9505
|
-
await page.waitForTimeout(100);
|
|
9572
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
9506
9573
|
await page.keyboard.press(keyValue);
|
|
9507
|
-
await page.waitForTimeout(100);
|
|
9574
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
9508
9575
|
} else {
|
|
9509
9576
|
const keypressSelector = componentContract.selectors[act.target];
|
|
9510
9577
|
if (!keypressSelector) {
|
|
@@ -9544,8 +9611,9 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9544
9611
|
await page.waitForTimeout(100);
|
|
9545
9612
|
}
|
|
9546
9613
|
}
|
|
9547
|
-
await page.waitForTimeout(100);
|
|
9614
|
+
await page.waitForTimeout(componentName === "menu" ? 200 : 100);
|
|
9548
9615
|
}
|
|
9616
|
+
await page.waitForTimeout(componentName === "menu" ? 300 : 100);
|
|
9549
9617
|
for (const assertion of assertions) {
|
|
9550
9618
|
let target;
|
|
9551
9619
|
if (assertion.target === "relative") {
|
|
@@ -9643,7 +9711,11 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9643
9711
|
await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
|
|
9644
9712
|
passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
|
|
9645
9713
|
} catch {
|
|
9646
|
-
|
|
9714
|
+
const actualFocus = await page.evaluate(() => {
|
|
9715
|
+
const focused = document.activeElement;
|
|
9716
|
+
return focused ? `${focused.tagName}#${focused.id || "no-id"}.${focused.className || "no-class"}` : "no element focused";
|
|
9717
|
+
});
|
|
9718
|
+
failures.push(`${assertion.failureMessage} (actual focus: ${actualFocus})`);
|
|
9647
9719
|
}
|
|
9648
9720
|
}
|
|
9649
9721
|
if (assertion.assertion === "toHaveRole" && assertion.expectedValue) {
|
|
@@ -12580,7 +12580,7 @@ Error: ${error instanceof Error ? error.message : String(error)}`
|
|
|
12580
12580
|
URL must include protocol (e.g., "http://localhost:5173/test")`
|
|
12581
12581
|
);
|
|
12582
12582
|
}
|
|
12583
|
-
const { runContractTestsPlaywright } = await import('./contractTestRunnerPlaywright-
|
|
12583
|
+
const { runContractTestsPlaywright } = await import('./contractTestRunnerPlaywright-45CFWUOD.js');
|
|
12584
12584
|
contract = await runContractTestsPlaywright(componentName, url);
|
|
12585
12585
|
} else {
|
|
12586
12586
|
console.log(`\u{1F9EA} Running jsdom tests (limited event handling)`);
|