aria-ease 3.0.2 → 3.0.3
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 +6 -6
- package/bin/cli.cjs +58 -22
- package/bin/cli.js +1 -1
- package/bin/{contractTestRunnerPlaywright-TLQZGKW7.js → contractTestRunnerPlaywright-3VJUZSYK.js} +11 -10
- package/bin/{test-Q7W3WQEA.js → test-D374H2ZS.js} +47 -12
- package/dist/{contractTestRunnerPlaywright-7U2O33SR.js → contractTestRunnerPlaywright-4UOHWGWD.js} +11 -10
- package/dist/index.cjs +58 -56
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +47 -46
- package/dist/src/menu/index.cjs +0 -34
- package/dist/src/menu/index.js +0 -34
- package/dist/src/utils/test/{contractTestRunnerPlaywright-7U2O33SR.js → contractTestRunnerPlaywright-4UOHWGWD.js} +11 -10
- package/dist/src/utils/test/contracts/MenuContract.json +1 -0
- package/dist/src/utils/test/index.cjs +58 -22
- package/dist/src/utils/test/index.d.cts +5 -4
- package/dist/src/utils/test/index.d.ts +5 -4
- package/dist/src/utils/test/index.js +47 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -172,7 +172,7 @@ updateAccordionTriggerAriaAttributes(
|
|
|
172
172
|
"accordion-container", // Container ID
|
|
173
173
|
"accordion-trigger", // Shared class for triggers
|
|
174
174
|
accordionStates, // State array
|
|
175
|
-
0 // Index of trigger that changed
|
|
175
|
+
0, // Index of trigger that changed
|
|
176
176
|
);
|
|
177
177
|
```
|
|
178
178
|
|
|
@@ -223,7 +223,7 @@ function handleCheckboxClick(index) {
|
|
|
223
223
|
"checkbox-group",
|
|
224
224
|
"custom-checkbox",
|
|
225
225
|
checkboxStates,
|
|
226
|
-
index
|
|
226
|
+
index,
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
```
|
|
@@ -314,14 +314,14 @@ Aria-Ease includes a built-in testing framework for automated accessibility vali
|
|
|
314
314
|
import { testUiComponent } from "aria-ease/test";
|
|
315
315
|
|
|
316
316
|
// In your test file (Vitest, Jest, etc.)
|
|
317
|
-
test("
|
|
318
|
-
const { container } = render(<
|
|
317
|
+
test("combobox is accessible", async () => {
|
|
318
|
+
const { container } = render(<Combobox />);
|
|
319
319
|
|
|
320
320
|
// Runs axe-core + contract tests
|
|
321
321
|
const result = await testUiComponent(
|
|
322
|
-
"
|
|
322
|
+
"combobox",
|
|
323
323
|
container,
|
|
324
|
-
"http://localhost:3000" // Optional: full E2E with Playwright
|
|
324
|
+
"http://localhost:3000", // Optional: full E2E with Playwright
|
|
325
325
|
);
|
|
326
326
|
|
|
327
327
|
expect(result.violations).toHaveLength(0);
|
package/bin/cli.cjs
CHANGED
|
@@ -13261,7 +13261,7 @@ async function runContractTests(componentName, component) {
|
|
|
13261
13261
|
const staticFailed = 0;
|
|
13262
13262
|
reporter.reportStatic(staticPassed, staticFailed);
|
|
13263
13263
|
reporter.summary(failures);
|
|
13264
|
-
return { passes, failures };
|
|
13264
|
+
return { passes, failures, skipped };
|
|
13265
13265
|
}
|
|
13266
13266
|
var import_promises, import_meta;
|
|
13267
13267
|
var init_contractTestRunner = __esm({
|
|
@@ -13308,6 +13308,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13308
13308
|
reporter.start(componentName, totalTests);
|
|
13309
13309
|
const failures = [];
|
|
13310
13310
|
const passes = [];
|
|
13311
|
+
const skipped = [];
|
|
13311
13312
|
let browser = null;
|
|
13312
13313
|
try {
|
|
13313
13314
|
browser = await import_playwright3.chromium.launch({ headless: true });
|
|
@@ -13315,13 +13316,13 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13315
13316
|
const page = await context.newPage();
|
|
13316
13317
|
await page.goto(url, {
|
|
13317
13318
|
waitUntil: "domcontentloaded",
|
|
13318
|
-
timeout:
|
|
13319
|
+
timeout: 9e4
|
|
13319
13320
|
});
|
|
13320
13321
|
const mainSelector = componentContract.selectors.trigger || componentContract.selectors.input || componentContract.selectors.container;
|
|
13321
13322
|
if (!mainSelector) {
|
|
13322
13323
|
throw new Error(`No main selector (trigger, input, or container) found in contract for ${componentName}`);
|
|
13323
13324
|
}
|
|
13324
|
-
await page.waitForSelector(mainSelector, { timeout:
|
|
13325
|
+
await page.waitForSelector(mainSelector, { timeout: 9e4 });
|
|
13325
13326
|
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
13326
13327
|
await page.waitForFunction(
|
|
13327
13328
|
(selector) => {
|
|
@@ -13329,7 +13330,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13329
13330
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
13330
13331
|
},
|
|
13331
13332
|
componentContract.selectors.trigger,
|
|
13332
|
-
{ timeout:
|
|
13333
|
+
{ timeout: 6e3 }
|
|
13333
13334
|
).catch(() => {
|
|
13334
13335
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
13335
13336
|
});
|
|
@@ -13419,7 +13420,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13419
13420
|
if (componentContract.selectors.input) {
|
|
13420
13421
|
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
13421
13422
|
await inputElement.clear();
|
|
13422
|
-
await page.waitForTimeout(
|
|
13423
|
+
await page.waitForTimeout(100);
|
|
13423
13424
|
}
|
|
13424
13425
|
}
|
|
13425
13426
|
}
|
|
@@ -13432,7 +13433,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13432
13433
|
continue;
|
|
13433
13434
|
}
|
|
13434
13435
|
await page.locator(focusSelector).first().focus();
|
|
13435
|
-
await page.waitForTimeout(
|
|
13436
|
+
await page.waitForTimeout(100);
|
|
13436
13437
|
}
|
|
13437
13438
|
if (act.type === "type" && act.value) {
|
|
13438
13439
|
const typeSelector = componentContract.selectors[act.target];
|
|
@@ -13441,7 +13442,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13441
13442
|
continue;
|
|
13442
13443
|
}
|
|
13443
13444
|
await page.locator(typeSelector).first().fill(act.value);
|
|
13444
|
-
await page.waitForTimeout(
|
|
13445
|
+
await page.waitForTimeout(100);
|
|
13445
13446
|
}
|
|
13446
13447
|
if (act.type === "click") {
|
|
13447
13448
|
if (act.target === "document") {
|
|
@@ -13491,7 +13492,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13491
13492
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
13492
13493
|
await page.waitForTimeout(100);
|
|
13493
13494
|
await page.keyboard.press(keyValue);
|
|
13494
|
-
await page.waitForTimeout(
|
|
13495
|
+
await page.waitForTimeout(100);
|
|
13495
13496
|
} else {
|
|
13496
13497
|
const keypressSelector = componentContract.selectors[act.target];
|
|
13497
13498
|
if (!keypressSelector) {
|
|
@@ -13520,7 +13521,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13520
13521
|
continue;
|
|
13521
13522
|
}
|
|
13522
13523
|
await relativeElement.hover();
|
|
13523
|
-
await page.waitForTimeout(
|
|
13524
|
+
await page.waitForTimeout(100);
|
|
13524
13525
|
} else {
|
|
13525
13526
|
const hoverSelector = componentContract.selectors[act.target];
|
|
13526
13527
|
if (!hoverSelector) {
|
|
@@ -13528,7 +13529,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13528
13529
|
continue;
|
|
13529
13530
|
}
|
|
13530
13531
|
await page.locator(hoverSelector).first().hover();
|
|
13531
|
-
await page.waitForTimeout(
|
|
13532
|
+
await page.waitForTimeout(100);
|
|
13532
13533
|
}
|
|
13533
13534
|
}
|
|
13534
13535
|
await page.waitForTimeout(100);
|
|
@@ -13670,7 +13671,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
13670
13671
|
} finally {
|
|
13671
13672
|
if (browser) await browser.close();
|
|
13672
13673
|
}
|
|
13673
|
-
return { passes, failures };
|
|
13674
|
+
return { passes, failures, skipped };
|
|
13674
13675
|
}
|
|
13675
13676
|
var import_playwright3, import_fs, import_meta2;
|
|
13676
13677
|
var init_contractTestRunnerPlaywright = __esm({
|
|
@@ -13687,15 +13688,49 @@ var init_contractTestRunnerPlaywright = __esm({
|
|
|
13687
13688
|
|
|
13688
13689
|
// src/utils/test/src/test.ts
|
|
13689
13690
|
async function testUiComponent(componentName, component, url) {
|
|
13690
|
-
|
|
13691
|
+
if (!componentName || typeof componentName !== "string") {
|
|
13692
|
+
throw new Error("\u274C testUiComponent requires a valid componentName (string)");
|
|
13693
|
+
}
|
|
13694
|
+
if (!component || !(component instanceof HTMLElement)) {
|
|
13695
|
+
throw new Error("\u274C testUiComponent requires a valid component (HTMLElement)");
|
|
13696
|
+
}
|
|
13697
|
+
if (url && typeof url !== "string") {
|
|
13698
|
+
throw new Error("\u274C testUiComponent url parameter must be a string");
|
|
13699
|
+
}
|
|
13700
|
+
let results;
|
|
13701
|
+
try {
|
|
13702
|
+
results = await (0, import_jest_axe.axe)(component);
|
|
13703
|
+
} catch (error) {
|
|
13704
|
+
throw new Error(
|
|
13705
|
+
`\u274C Axe accessibility scan failed
|
|
13706
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
13707
|
+
);
|
|
13708
|
+
}
|
|
13691
13709
|
let contract;
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13710
|
+
try {
|
|
13711
|
+
if (url) {
|
|
13712
|
+
console.log(`\u{1F3AD} Running Playwright E2E tests on ${url}`);
|
|
13713
|
+
try {
|
|
13714
|
+
new URL(url);
|
|
13715
|
+
} catch {
|
|
13716
|
+
throw new Error(
|
|
13717
|
+
`\u274C Invalid URL format: "${url}"
|
|
13718
|
+
URL must include protocol (e.g., "http://localhost:5173/test")`
|
|
13719
|
+
);
|
|
13720
|
+
}
|
|
13721
|
+
const { runContractTestsPlaywright: runContractTestsPlaywright2 } = await Promise.resolve().then(() => (init_contractTestRunnerPlaywright(), contractTestRunnerPlaywright_exports));
|
|
13722
|
+
contract = await runContractTestsPlaywright2(componentName, url);
|
|
13723
|
+
} else {
|
|
13724
|
+
console.log(`\u{1F9EA} Running jsdom tests (limited event handling)`);
|
|
13725
|
+
console.log(`Some tests may be skipped or yield false positives/negatives.
|
|
13726
|
+
For full coverage, run with a URL to enable Playwright E2E tests.`);
|
|
13727
|
+
contract = await runContractTests(componentName, component);
|
|
13728
|
+
}
|
|
13729
|
+
} catch (error) {
|
|
13730
|
+
if (error instanceof Error) {
|
|
13731
|
+
throw error;
|
|
13732
|
+
}
|
|
13733
|
+
throw new Error(`\u274C Contract test execution failed: ${String(error)}`);
|
|
13699
13734
|
}
|
|
13700
13735
|
const result = {
|
|
13701
13736
|
violations: results.violations,
|
|
@@ -13706,10 +13741,11 @@ async function testUiComponent(componentName, component, url) {
|
|
|
13706
13741
|
const mode = url ? "Playwright" : "jsdom";
|
|
13707
13742
|
throw new Error(
|
|
13708
13743
|
`
|
|
13709
|
-
\u274C ${contract.failures.length}
|
|
13710
|
-
\u2705 ${contract.passes.length}
|
|
13744
|
+
\u274C ${contract.failures.length} accessibility contract test${contract.failures.length > 1 ? "s" : ""} failed (${mode} mode)
|
|
13745
|
+
\u2705 ${contract.passes.length} test${contract.passes.length > 1 ? "s" : ""} passed
|
|
13711
13746
|
|
|
13712
|
-
\u{1F4CB} Review the detailed test report above for specific failures
|
|
13747
|
+
\u{1F4CB} Review the detailed test report above for specific failures.
|
|
13748
|
+
\u{1F4A1} Contract tests validate ARIA attributes and keyboard interactions per W3C APG guidelines.`
|
|
13713
13749
|
);
|
|
13714
13750
|
}
|
|
13715
13751
|
if (results.violations.length > 0) {
|
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-D374H2ZS.js");
|
|
208
208
|
runTest();
|
|
209
209
|
});
|
|
210
210
|
program.command("help").description("Display help information").action(() => {
|
package/bin/{contractTestRunnerPlaywright-TLQZGKW7.js → contractTestRunnerPlaywright-3VJUZSYK.js}
RENAMED
|
@@ -35,6 +35,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
35
35
|
reporter.start(componentName, totalTests);
|
|
36
36
|
const failures = [];
|
|
37
37
|
const passes = [];
|
|
38
|
+
const skipped = [];
|
|
38
39
|
let browser = null;
|
|
39
40
|
try {
|
|
40
41
|
browser = await chromium.launch({ headless: true });
|
|
@@ -42,13 +43,13 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
42
43
|
const page = await context.newPage();
|
|
43
44
|
await page.goto(url, {
|
|
44
45
|
waitUntil: "domcontentloaded",
|
|
45
|
-
timeout:
|
|
46
|
+
timeout: 9e4
|
|
46
47
|
});
|
|
47
48
|
const mainSelector = componentContract.selectors.trigger || componentContract.selectors.input || componentContract.selectors.container;
|
|
48
49
|
if (!mainSelector) {
|
|
49
50
|
throw new Error(`No main selector (trigger, input, or container) found in contract for ${componentName}`);
|
|
50
51
|
}
|
|
51
|
-
await page.waitForSelector(mainSelector, { timeout:
|
|
52
|
+
await page.waitForSelector(mainSelector, { timeout: 9e4 });
|
|
52
53
|
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
53
54
|
await page.waitForFunction(
|
|
54
55
|
(selector) => {
|
|
@@ -56,7 +57,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
56
57
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
57
58
|
},
|
|
58
59
|
componentContract.selectors.trigger,
|
|
59
|
-
{ timeout:
|
|
60
|
+
{ timeout: 6e3 }
|
|
60
61
|
).catch(() => {
|
|
61
62
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
62
63
|
});
|
|
@@ -146,7 +147,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
146
147
|
if (componentContract.selectors.input) {
|
|
147
148
|
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
148
149
|
await inputElement.clear();
|
|
149
|
-
await page.waitForTimeout(
|
|
150
|
+
await page.waitForTimeout(100);
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
}
|
|
@@ -159,7 +160,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
159
160
|
continue;
|
|
160
161
|
}
|
|
161
162
|
await page.locator(focusSelector).first().focus();
|
|
162
|
-
await page.waitForTimeout(
|
|
163
|
+
await page.waitForTimeout(100);
|
|
163
164
|
}
|
|
164
165
|
if (act.type === "type" && act.value) {
|
|
165
166
|
const typeSelector = componentContract.selectors[act.target];
|
|
@@ -168,7 +169,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
168
169
|
continue;
|
|
169
170
|
}
|
|
170
171
|
await page.locator(typeSelector).first().fill(act.value);
|
|
171
|
-
await page.waitForTimeout(
|
|
172
|
+
await page.waitForTimeout(100);
|
|
172
173
|
}
|
|
173
174
|
if (act.type === "click") {
|
|
174
175
|
if (act.target === "document") {
|
|
@@ -218,7 +219,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
218
219
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
219
220
|
await page.waitForTimeout(100);
|
|
220
221
|
await page.keyboard.press(keyValue);
|
|
221
|
-
await page.waitForTimeout(
|
|
222
|
+
await page.waitForTimeout(100);
|
|
222
223
|
} else {
|
|
223
224
|
const keypressSelector = componentContract.selectors[act.target];
|
|
224
225
|
if (!keypressSelector) {
|
|
@@ -247,7 +248,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
247
248
|
continue;
|
|
248
249
|
}
|
|
249
250
|
await relativeElement.hover();
|
|
250
|
-
await page.waitForTimeout(
|
|
251
|
+
await page.waitForTimeout(100);
|
|
251
252
|
} else {
|
|
252
253
|
const hoverSelector = componentContract.selectors[act.target];
|
|
253
254
|
if (!hoverSelector) {
|
|
@@ -255,7 +256,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
255
256
|
continue;
|
|
256
257
|
}
|
|
257
258
|
await page.locator(hoverSelector).first().hover();
|
|
258
|
-
await page.waitForTimeout(
|
|
259
|
+
await page.waitForTimeout(100);
|
|
259
260
|
}
|
|
260
261
|
}
|
|
261
262
|
await page.waitForTimeout(100);
|
|
@@ -397,7 +398,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
397
398
|
} finally {
|
|
398
399
|
if (browser) await browser.close();
|
|
399
400
|
}
|
|
400
|
-
return { passes, failures };
|
|
401
|
+
return { passes, failures, skipped };
|
|
401
402
|
}
|
|
402
403
|
export {
|
|
403
404
|
runContractTestsPlaywright
|
|
@@ -12741,20 +12741,54 @@ async function runContractTests(componentName, component) {
|
|
|
12741
12741
|
const staticFailed = 0;
|
|
12742
12742
|
reporter.reportStatic(staticPassed, staticFailed);
|
|
12743
12743
|
reporter.summary(failures);
|
|
12744
|
-
return { passes, failures };
|
|
12744
|
+
return { passes, failures, skipped };
|
|
12745
12745
|
}
|
|
12746
12746
|
|
|
12747
12747
|
// src/utils/test/src/test.ts
|
|
12748
12748
|
async function testUiComponent(componentName, component, url) {
|
|
12749
|
-
|
|
12749
|
+
if (!componentName || typeof componentName !== "string") {
|
|
12750
|
+
throw new Error("\u274C testUiComponent requires a valid componentName (string)");
|
|
12751
|
+
}
|
|
12752
|
+
if (!component || !(component instanceof HTMLElement)) {
|
|
12753
|
+
throw new Error("\u274C testUiComponent requires a valid component (HTMLElement)");
|
|
12754
|
+
}
|
|
12755
|
+
if (url && typeof url !== "string") {
|
|
12756
|
+
throw new Error("\u274C testUiComponent url parameter must be a string");
|
|
12757
|
+
}
|
|
12758
|
+
let results;
|
|
12759
|
+
try {
|
|
12760
|
+
results = await axe(component);
|
|
12761
|
+
} catch (error) {
|
|
12762
|
+
throw new Error(
|
|
12763
|
+
`\u274C Axe accessibility scan failed
|
|
12764
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
12765
|
+
);
|
|
12766
|
+
}
|
|
12750
12767
|
let contract;
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12768
|
+
try {
|
|
12769
|
+
if (url) {
|
|
12770
|
+
console.log(`\u{1F3AD} Running Playwright E2E tests on ${url}`);
|
|
12771
|
+
try {
|
|
12772
|
+
new URL(url);
|
|
12773
|
+
} catch {
|
|
12774
|
+
throw new Error(
|
|
12775
|
+
`\u274C Invalid URL format: "${url}"
|
|
12776
|
+
URL must include protocol (e.g., "http://localhost:5173/test")`
|
|
12777
|
+
);
|
|
12778
|
+
}
|
|
12779
|
+
const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-3VJUZSYK.js");
|
|
12780
|
+
contract = await runContractTestsPlaywright(componentName, url);
|
|
12781
|
+
} else {
|
|
12782
|
+
console.log(`\u{1F9EA} Running jsdom tests (limited event handling)`);
|
|
12783
|
+
console.log(`Some tests may be skipped or yield false positives/negatives.
|
|
12784
|
+
For full coverage, run with a URL to enable Playwright E2E tests.`);
|
|
12785
|
+
contract = await runContractTests(componentName, component);
|
|
12786
|
+
}
|
|
12787
|
+
} catch (error) {
|
|
12788
|
+
if (error instanceof Error) {
|
|
12789
|
+
throw error;
|
|
12790
|
+
}
|
|
12791
|
+
throw new Error(`\u274C Contract test execution failed: ${String(error)}`);
|
|
12758
12792
|
}
|
|
12759
12793
|
const result = {
|
|
12760
12794
|
violations: results.violations,
|
|
@@ -12765,10 +12799,11 @@ async function testUiComponent(componentName, component, url) {
|
|
|
12765
12799
|
const mode = url ? "Playwright" : "jsdom";
|
|
12766
12800
|
throw new Error(
|
|
12767
12801
|
`
|
|
12768
|
-
\u274C ${contract.failures.length}
|
|
12769
|
-
\u2705 ${contract.passes.length}
|
|
12802
|
+
\u274C ${contract.failures.length} accessibility contract test${contract.failures.length > 1 ? "s" : ""} failed (${mode} mode)
|
|
12803
|
+
\u2705 ${contract.passes.length} test${contract.passes.length > 1 ? "s" : ""} passed
|
|
12770
12804
|
|
|
12771
|
-
\u{1F4CB} Review the detailed test report above for specific failures
|
|
12805
|
+
\u{1F4CB} Review the detailed test report above for specific failures.
|
|
12806
|
+
\u{1F4A1} Contract tests validate ARIA attributes and keyboard interactions per W3C APG guidelines.`
|
|
12772
12807
|
);
|
|
12773
12808
|
}
|
|
12774
12809
|
if (results.violations.length > 0) {
|
package/dist/{contractTestRunnerPlaywright-7U2O33SR.js → contractTestRunnerPlaywright-4UOHWGWD.js}
RENAMED
|
@@ -33,6 +33,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
33
33
|
reporter.start(componentName, totalTests);
|
|
34
34
|
const failures = [];
|
|
35
35
|
const passes = [];
|
|
36
|
+
const skipped = [];
|
|
36
37
|
let browser = null;
|
|
37
38
|
try {
|
|
38
39
|
browser = await chromium.launch({ headless: true });
|
|
@@ -40,13 +41,13 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
40
41
|
const page = await context.newPage();
|
|
41
42
|
await page.goto(url, {
|
|
42
43
|
waitUntil: "domcontentloaded",
|
|
43
|
-
timeout:
|
|
44
|
+
timeout: 9e4
|
|
44
45
|
});
|
|
45
46
|
const mainSelector = componentContract.selectors.trigger || componentContract.selectors.input || componentContract.selectors.container;
|
|
46
47
|
if (!mainSelector) {
|
|
47
48
|
throw new Error(`No main selector (trigger, input, or container) found in contract for ${componentName}`);
|
|
48
49
|
}
|
|
49
|
-
await page.waitForSelector(mainSelector, { timeout:
|
|
50
|
+
await page.waitForSelector(mainSelector, { timeout: 9e4 });
|
|
50
51
|
if (componentName === "menu" && componentContract.selectors.trigger) {
|
|
51
52
|
await page.waitForFunction(
|
|
52
53
|
(selector) => {
|
|
@@ -54,7 +55,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
54
55
|
return trigger && trigger.getAttribute("data-menu-initialized") === "true";
|
|
55
56
|
},
|
|
56
57
|
componentContract.selectors.trigger,
|
|
57
|
-
{ timeout:
|
|
58
|
+
{ timeout: 6e3 }
|
|
58
59
|
).catch(() => {
|
|
59
60
|
console.warn("Menu initialization signal not detected, continuing with tests...");
|
|
60
61
|
});
|
|
@@ -144,7 +145,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
144
145
|
if (componentContract.selectors.input) {
|
|
145
146
|
const inputElement = page.locator(componentContract.selectors.input).first();
|
|
146
147
|
await inputElement.clear();
|
|
147
|
-
await page.waitForTimeout(
|
|
148
|
+
await page.waitForTimeout(100);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
}
|
|
@@ -157,7 +158,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
157
158
|
continue;
|
|
158
159
|
}
|
|
159
160
|
await page.locator(focusSelector).first().focus();
|
|
160
|
-
await page.waitForTimeout(
|
|
161
|
+
await page.waitForTimeout(100);
|
|
161
162
|
}
|
|
162
163
|
if (act.type === "type" && act.value) {
|
|
163
164
|
const typeSelector = componentContract.selectors[act.target];
|
|
@@ -166,7 +167,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
166
167
|
continue;
|
|
167
168
|
}
|
|
168
169
|
await page.locator(typeSelector).first().fill(act.value);
|
|
169
|
-
await page.waitForTimeout(
|
|
170
|
+
await page.waitForTimeout(100);
|
|
170
171
|
}
|
|
171
172
|
if (act.type === "click") {
|
|
172
173
|
if (act.target === "document") {
|
|
@@ -216,7 +217,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
216
217
|
if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
|
|
217
218
|
await page.waitForTimeout(100);
|
|
218
219
|
await page.keyboard.press(keyValue);
|
|
219
|
-
await page.waitForTimeout(
|
|
220
|
+
await page.waitForTimeout(100);
|
|
220
221
|
} else {
|
|
221
222
|
const keypressSelector = componentContract.selectors[act.target];
|
|
222
223
|
if (!keypressSelector) {
|
|
@@ -245,7 +246,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
245
246
|
continue;
|
|
246
247
|
}
|
|
247
248
|
await relativeElement.hover();
|
|
248
|
-
await page.waitForTimeout(
|
|
249
|
+
await page.waitForTimeout(100);
|
|
249
250
|
} else {
|
|
250
251
|
const hoverSelector = componentContract.selectors[act.target];
|
|
251
252
|
if (!hoverSelector) {
|
|
@@ -253,7 +254,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
253
254
|
continue;
|
|
254
255
|
}
|
|
255
256
|
await page.locator(hoverSelector).first().hover();
|
|
256
|
-
await page.waitForTimeout(
|
|
257
|
+
await page.waitForTimeout(100);
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
260
|
await page.waitForTimeout(100);
|
|
@@ -395,7 +396,7 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
395
396
|
} finally {
|
|
396
397
|
if (browser) await browser.close();
|
|
397
398
|
}
|
|
398
|
-
return { passes, failures };
|
|
399
|
+
return { passes, failures, skipped };
|
|
399
400
|
}
|
|
400
401
|
export {
|
|
401
402
|
runContractTestsPlaywright
|