aria-ease 6.12.1 → 6.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{MenuComponentStrategy-JAMTCSNF.js → MenuComponentStrategy-VYCC2XOM.js} +5 -5
- package/dist/{buildContracts-FT6KWUJN.js → buildContracts-VIV6GM56.js} +0 -28
- package/dist/cli.cjs +154 -78
- package/dist/cli.js +2 -2
- package/dist/{contractTestRunnerPlaywright-H24LQ45R.js → contractTestRunnerPlaywright-B2HLZKKK.js} +150 -46
- package/dist/{contractTestRunnerPlaywright-NL3JNJYH.js → contractTestRunnerPlaywright-RWK52C7S.js} +150 -46
- package/dist/index.cjs +564 -85
- package/dist/index.d.cts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +411 -36
- package/dist/src/combobox/index.cjs +3 -0
- package/dist/src/combobox/index.js +3 -0
- package/dist/src/utils/test/{MenuComponentStrategy-VKZQYLBE.js → MenuComponentStrategy-6XWU5KLW.js} +5 -5
- package/dist/src/utils/test/{contractTestRunnerPlaywright-5FT6K2WN.js → contractTestRunnerPlaywright-5FIGA5G4.js} +150 -46
- package/dist/src/utils/test/dsl/index.cjs +407 -35
- package/dist/src/utils/test/dsl/index.d.cts +24 -1
- package/dist/src/utils/test/dsl/index.d.ts +24 -1
- package/dist/src/utils/test/dsl/index.js +407 -35
- package/dist/src/utils/test/index.cjs +154 -50
- package/dist/src/utils/test/index.js +1 -1
- package/dist/{test-FYSJXQWO.js → test-WDBS5JWO.js} +1 -1
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ var MenuComponentStrategy = class {
|
|
|
22
22
|
if (!closeSelector && this.selectors.focusable) {
|
|
23
23
|
closeSelector = this.selectors.focusable;
|
|
24
24
|
} else if (!closeSelector) {
|
|
25
|
-
closeSelector = this.selectors.
|
|
25
|
+
closeSelector = this.selectors.main;
|
|
26
26
|
}
|
|
27
27
|
if (closeSelector) {
|
|
28
28
|
const closeElement = page.locator(closeSelector).first();
|
|
@@ -30,8 +30,8 @@ var MenuComponentStrategy = class {
|
|
|
30
30
|
await page.keyboard.press("Escape");
|
|
31
31
|
menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
|
|
32
32
|
}
|
|
33
|
-
if (!menuClosed && this.selectors.
|
|
34
|
-
const triggerElement = page.locator(this.selectors.
|
|
33
|
+
if (!menuClosed && this.selectors.main) {
|
|
34
|
+
const triggerElement = page.locator(this.selectors.main).first();
|
|
35
35
|
await triggerElement.click({ timeout: this.actionTimeoutMs });
|
|
36
36
|
menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
|
|
37
37
|
}
|
|
@@ -51,8 +51,8 @@ This indicates a problem with the menu component's close functionality.`
|
|
|
51
51
|
if (this.selectors.input) {
|
|
52
52
|
await page.locator(this.selectors.input).first().clear();
|
|
53
53
|
}
|
|
54
|
-
if (this.selectors.
|
|
55
|
-
const triggerElement = page.locator(this.selectors.
|
|
54
|
+
if (this.selectors.main) {
|
|
55
|
+
const triggerElement = page.locator(this.selectors.main).first();
|
|
56
56
|
await triggerElement.focus();
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -214,25 +214,6 @@ function validateContractSchema(contract) {
|
|
|
214
214
|
});
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
|
-
if (c.states !== void 0) {
|
|
218
|
-
if (!Array.isArray(c.states)) {
|
|
219
|
-
errors.push({ path: "$.states", message: "states must be an array" });
|
|
220
|
-
} else {
|
|
221
|
-
c.states.forEach((state, idx) => {
|
|
222
|
-
if (typeof state !== "object" || state === null) {
|
|
223
|
-
errors.push({ path: `$.states[${idx}]`, message: "state must be an object" });
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
const s = state;
|
|
227
|
-
if (typeof s.name !== "string") {
|
|
228
|
-
errors.push({ path: `$.states[${idx}].name`, message: "name is required and must be a string" });
|
|
229
|
-
}
|
|
230
|
-
if (!Array.isArray(s.requires)) {
|
|
231
|
-
errors.push({ path: `$.states[${idx}].requires`, message: "requires is required and must be an array" });
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
217
|
return {
|
|
237
218
|
valid: errors.length === 0,
|
|
238
219
|
errors
|
|
@@ -308,17 +289,8 @@ function validateTargetReferences(contract, selectorKeys) {
|
|
|
308
289
|
});
|
|
309
290
|
}
|
|
310
291
|
const dynamicItems = c.dynamic;
|
|
311
|
-
const states = c.states;
|
|
312
|
-
const stateNames = new Set((states || []).map((s) => String(s.name)));
|
|
313
292
|
if (Array.isArray(dynamicItems)) {
|
|
314
293
|
dynamicItems.forEach((item, itemIdx) => {
|
|
315
|
-
const given = item.given;
|
|
316
|
-
if (given && !stateNames.has(given)) {
|
|
317
|
-
errors.push({
|
|
318
|
-
path: `$.dynamic[${itemIdx}].given`,
|
|
319
|
-
message: `State '${given}' not found in states`
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
294
|
const actions = item.action;
|
|
323
295
|
if (Array.isArray(actions)) {
|
|
324
296
|
actions.forEach((action, actIdx) => {
|
package/dist/cli.cjs
CHANGED
|
@@ -1155,7 +1155,7 @@ var init_MenuComponentStrategy = __esm({
|
|
|
1155
1155
|
if (!closeSelector && this.selectors.focusable) {
|
|
1156
1156
|
closeSelector = this.selectors.focusable;
|
|
1157
1157
|
} else if (!closeSelector) {
|
|
1158
|
-
closeSelector = this.selectors.
|
|
1158
|
+
closeSelector = this.selectors.main;
|
|
1159
1159
|
}
|
|
1160
1160
|
if (closeSelector) {
|
|
1161
1161
|
const closeElement = page.locator(closeSelector).first();
|
|
@@ -1163,8 +1163,8 @@ var init_MenuComponentStrategy = __esm({
|
|
|
1163
1163
|
await page.keyboard.press("Escape");
|
|
1164
1164
|
menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
|
|
1165
1165
|
}
|
|
1166
|
-
if (!menuClosed && this.selectors.
|
|
1167
|
-
const triggerElement = page.locator(this.selectors.
|
|
1166
|
+
if (!menuClosed && this.selectors.main) {
|
|
1167
|
+
const triggerElement = page.locator(this.selectors.main).first();
|
|
1168
1168
|
await triggerElement.click({ timeout: this.actionTimeoutMs });
|
|
1169
1169
|
menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: this.assertionTimeoutMs }).then(() => true).catch(() => false);
|
|
1170
1170
|
}
|
|
@@ -1184,8 +1184,8 @@ This indicates a problem with the menu component's close functionality.`
|
|
|
1184
1184
|
if (this.selectors.input) {
|
|
1185
1185
|
await page.locator(this.selectors.input).first().clear();
|
|
1186
1186
|
}
|
|
1187
|
-
if (this.selectors.
|
|
1188
|
-
const triggerElement = page.locator(this.selectors.
|
|
1187
|
+
if (this.selectors.main) {
|
|
1188
|
+
const triggerElement = page.locator(this.selectors.main).first();
|
|
1189
1189
|
await triggerElement.focus();
|
|
1190
1190
|
}
|
|
1191
1191
|
}
|
|
@@ -1977,13 +1977,21 @@ var init_AssertionRunner = __esm({
|
|
|
1977
1977
|
/**
|
|
1978
1978
|
* Validate focus assertion
|
|
1979
1979
|
*/
|
|
1980
|
-
async validateFocus(target, targetName, failureMessage, testDescription) {
|
|
1980
|
+
async validateFocus(target, targetName, expectedFocus, failureMessage, testDescription) {
|
|
1981
1981
|
try {
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1982
|
+
if (expectedFocus) {
|
|
1983
|
+
await (0, test_exports.expect)(target).toBeFocused({ timeout: this.timeoutMs });
|
|
1984
|
+
return {
|
|
1985
|
+
success: true,
|
|
1986
|
+
passMessage: `${targetName} has focus as expected. Test: "${testDescription}".`
|
|
1987
|
+
};
|
|
1988
|
+
} else {
|
|
1989
|
+
await (0, test_exports.expect)(target).not.toBeFocused({ timeout: this.timeoutMs });
|
|
1990
|
+
return {
|
|
1991
|
+
success: true,
|
|
1992
|
+
passMessage: `${targetName} does not have focus as expected. Test: "${testDescription}".`
|
|
1993
|
+
};
|
|
1994
|
+
}
|
|
1987
1995
|
} catch {
|
|
1988
1996
|
const actualFocus = await this.page.evaluate(() => {
|
|
1989
1997
|
const focused = document.activeElement;
|
|
@@ -2069,7 +2077,9 @@ var init_AssertionRunner = __esm({
|
|
|
2069
2077
|
}
|
|
2070
2078
|
return { success: false, failMessage: "Missing expectedValue for toHaveValue assertion" };
|
|
2071
2079
|
case "toHaveFocus":
|
|
2072
|
-
return this.validateFocus(target, assertion.target, assertion.failureMessage || "", testDescription);
|
|
2080
|
+
return this.validateFocus(target, assertion.target, true, assertion.failureMessage || "", testDescription);
|
|
2081
|
+
case "notToHaveFocus":
|
|
2082
|
+
return this.validateFocus(target, assertion.target, false, assertion.failureMessage || "", testDescription);
|
|
2073
2083
|
case "toHaveRole":
|
|
2074
2084
|
if (assertion.expectedValue !== void 0) {
|
|
2075
2085
|
return this.validateRole(target, assertion.target, assertion.expectedValue, assertion.failureMessage || "", testDescription);
|
|
@@ -2092,12 +2102,7 @@ async function runContractTestsPlaywright(componentName, url, strictness, config
|
|
|
2092
2102
|
const componentConfig = config?.test?.components?.find((c) => c.name === componentName);
|
|
2093
2103
|
const isCustomContract = !!componentConfig?.contractPath;
|
|
2094
2104
|
const reporter = new ContractReporter(true, isCustomContract);
|
|
2095
|
-
const defaultTimeouts = {
|
|
2096
|
-
actionTimeoutMs: 400,
|
|
2097
|
-
assertionTimeoutMs: 400,
|
|
2098
|
-
navigationTimeoutMs: 3e4,
|
|
2099
|
-
componentReadyTimeoutMs: 5e3
|
|
2100
|
-
};
|
|
2105
|
+
const defaultTimeouts = { actionTimeoutMs: 400, assertionTimeoutMs: 400, navigationTimeoutMs: 3e4, componentReadyTimeoutMs: 5e3 };
|
|
2101
2106
|
const globalDisableTimeouts = config?.test?.disableTimeouts === true;
|
|
2102
2107
|
const componentDisableTimeouts = componentConfig?.disableTimeouts === true;
|
|
2103
2108
|
const disableTimeouts = componentDisableTimeouts || globalDisableTimeouts;
|
|
@@ -2109,11 +2114,7 @@ async function runContractTestsPlaywright(componentName, url, strictness, config
|
|
|
2109
2114
|
}
|
|
2110
2115
|
return value;
|
|
2111
2116
|
};
|
|
2112
|
-
const actionTimeoutMs = resolveTimeout(
|
|
2113
|
-
componentConfig?.actionTimeoutMs,
|
|
2114
|
-
config?.test?.actionTimeoutMs,
|
|
2115
|
-
defaultTimeouts.actionTimeoutMs
|
|
2116
|
-
);
|
|
2117
|
+
const actionTimeoutMs = resolveTimeout(componentConfig?.actionTimeoutMs, config?.test?.actionTimeoutMs, defaultTimeouts.actionTimeoutMs);
|
|
2117
2118
|
const assertionTimeoutMs = resolveTimeout(
|
|
2118
2119
|
componentConfig?.assertionTimeoutMs,
|
|
2119
2120
|
config?.test?.assertionTimeoutMs,
|
|
@@ -2213,8 +2214,8 @@ This usually means:
|
|
|
2213
2214
|
);
|
|
2214
2215
|
}
|
|
2215
2216
|
reporter.start(componentName, totalTests, apgUrl);
|
|
2216
|
-
if (componentName === "menu" && componentContract.selectors.
|
|
2217
|
-
await page.locator(componentContract.selectors.
|
|
2217
|
+
if (componentName === "menu" && componentContract.selectors.main) {
|
|
2218
|
+
await page.locator(componentContract.selectors.main).first().waitFor({ state: "visible", timeout: componentReadyTimeoutMs }).catch(() => {
|
|
2218
2219
|
});
|
|
2219
2220
|
}
|
|
2220
2221
|
const hasSubmenuCapability = componentName === "menu" && !!componentContract.selectors.submenuTrigger ? await page.locator(componentContract.selectors.submenuTrigger).count() > 0 : false;
|
|
@@ -2223,7 +2224,42 @@ This usually means:
|
|
|
2223
2224
|
let staticFailed = 0;
|
|
2224
2225
|
let staticWarnings = 0;
|
|
2225
2226
|
for (const rel of componentContract.relationships || []) {
|
|
2227
|
+
if (strategy && typeof strategy.resetState === "function") {
|
|
2228
|
+
try {
|
|
2229
|
+
await strategy.resetState(page);
|
|
2230
|
+
} catch (err) {
|
|
2231
|
+
warnings.push(`Warning: resetState failed before relationship test: ${err instanceof Error ? err.message : String(err)}`);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2226
2234
|
const relationshipLevel = normalizeLevel(rel.level);
|
|
2235
|
+
if (Array.isArray(rel.setup) && rel.setup.length > 0) {
|
|
2236
|
+
let isAllowedType2 = function(t) {
|
|
2237
|
+
return allowedTypes.includes(t);
|
|
2238
|
+
};
|
|
2239
|
+
var isAllowedType = isAllowedType2;
|
|
2240
|
+
const actionExecutor = new ActionExecutor(page, componentContract.selectors, actionTimeoutMs);
|
|
2241
|
+
const relDescription = rel.type === "aria-reference" ? `${rel.from}.${rel.attribute} references ${rel.to}` : `${rel.parent} contains ${rel.child}`;
|
|
2242
|
+
const allowedTypes = ["focus", "type", "click", "keypress", "hover"];
|
|
2243
|
+
const toSetupAction = (a) => ({
|
|
2244
|
+
...a,
|
|
2245
|
+
type: isAllowedType2(a.type) ? a.type : "click"
|
|
2246
|
+
});
|
|
2247
|
+
const setupActions = rel.setup.map(toSetupAction);
|
|
2248
|
+
const setupResult = await runSetupActions(setupActions, actionExecutor, strategy, page, relDescription, ["submenu", "submenuTrigger", "submenuItems"]);
|
|
2249
|
+
if (setupResult.skip) {
|
|
2250
|
+
skipped.push(setupResult.message || "Setup action skipped");
|
|
2251
|
+
reporter.reportStaticTest(relDescription, "skip", setupResult.message, relationshipLevel);
|
|
2252
|
+
continue;
|
|
2253
|
+
}
|
|
2254
|
+
if (!setupResult.success) {
|
|
2255
|
+
const failure = `Relationship setup failed: ${setupResult.error}`;
|
|
2256
|
+
const outcome = classifyFailure(failure, rel.level);
|
|
2257
|
+
if (outcome.status === "fail") staticFailed += 1;
|
|
2258
|
+
if (outcome.status === "warn") staticWarnings += 1;
|
|
2259
|
+
reporter.reportStaticTest(relDescription, outcome.status, outcome.detail, outcome.level);
|
|
2260
|
+
continue;
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2227
2263
|
if (componentName === "menu" && !hasSubmenuCapability) {
|
|
2228
2264
|
const involvesSubmenu = isSubmenuRelation(rel);
|
|
2229
2265
|
if (involvesSubmenu) {
|
|
@@ -2396,7 +2432,53 @@ This usually means:
|
|
|
2396
2432
|
}
|
|
2397
2433
|
}
|
|
2398
2434
|
const staticAssertionRunner = new AssertionRunner(page, componentContract.selectors, assertionTimeoutMs);
|
|
2435
|
+
async function runSetupActions(setup, actionExecutor, strategy2, page2, description, skipKeywords = []) {
|
|
2436
|
+
if (!Array.isArray(setup) || setup.length === 0) return { success: true };
|
|
2437
|
+
if (strategy2 && typeof strategy2.resetState === "function") {
|
|
2438
|
+
await strategy2.resetState(page2);
|
|
2439
|
+
}
|
|
2440
|
+
for (const setupAct of setup) {
|
|
2441
|
+
let setupResult = { success: true };
|
|
2442
|
+
try {
|
|
2443
|
+
if (setupAct.type === "focus") {
|
|
2444
|
+
if (setupAct.target === "relative" && setupAct.relativeTarget) {
|
|
2445
|
+
setupResult = await actionExecutor.focus("relative", setupAct.relativeTarget);
|
|
2446
|
+
} else {
|
|
2447
|
+
setupResult = await actionExecutor.focus(setupAct.target);
|
|
2448
|
+
}
|
|
2449
|
+
} else if (setupAct.type === "type" && setupAct.value) {
|
|
2450
|
+
setupResult = await actionExecutor.type(setupAct.target, setupAct.value);
|
|
2451
|
+
} else if (setupAct.type === "click") {
|
|
2452
|
+
setupResult = await actionExecutor.click(setupAct.target, setupAct.relativeTarget);
|
|
2453
|
+
} else if (setupAct.type === "keypress" && setupAct.key) {
|
|
2454
|
+
setupResult = await actionExecutor.keypress(setupAct.target, setupAct.key);
|
|
2455
|
+
} else if (setupAct.type === "hover") {
|
|
2456
|
+
setupResult = await actionExecutor.hover(setupAct.target, setupAct.relativeTarget);
|
|
2457
|
+
} else {
|
|
2458
|
+
continue;
|
|
2459
|
+
}
|
|
2460
|
+
} catch (err) {
|
|
2461
|
+
setupResult = { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
2462
|
+
}
|
|
2463
|
+
if (!setupResult.success) {
|
|
2464
|
+
const setupMsg = setupResult.error || "Setup action failed";
|
|
2465
|
+
const isSkip = skipKeywords.some((kw) => description.includes(kw) || setupMsg.includes(kw));
|
|
2466
|
+
if (isSkip) {
|
|
2467
|
+
return { success: false, skip: true, message: `Skipping test - capability not present: ${setupMsg}` };
|
|
2468
|
+
}
|
|
2469
|
+
return { success: false, error: setupMsg };
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
return { success: true };
|
|
2473
|
+
}
|
|
2399
2474
|
for (const test of componentContract.static[0]?.assertions || []) {
|
|
2475
|
+
if (strategy && typeof strategy.resetState === "function") {
|
|
2476
|
+
try {
|
|
2477
|
+
await strategy.resetState(page);
|
|
2478
|
+
} catch (err) {
|
|
2479
|
+
warnings.push(`Warning: resetState failed before static test: ${err instanceof Error ? err.message : String(err)}`);
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2400
2482
|
if (test.target === "relative") continue;
|
|
2401
2483
|
const staticDescription = `${test.target}${test.attribute ? ` (${test.attribute})` : ""}`;
|
|
2402
2484
|
const staticLevel = normalizeLevel(test.level);
|
|
@@ -2406,6 +2488,33 @@ This usually means:
|
|
|
2406
2488
|
reporter.reportStaticTest(staticDescription, "skip", skipMessage, staticLevel);
|
|
2407
2489
|
continue;
|
|
2408
2490
|
}
|
|
2491
|
+
if (Array.isArray(test.setup) && test.setup.length > 0) {
|
|
2492
|
+
let isAllowedType2 = function(t) {
|
|
2493
|
+
return allowedTypes.includes(t);
|
|
2494
|
+
};
|
|
2495
|
+
var isAllowedType = isAllowedType2;
|
|
2496
|
+
const actionExecutor = new ActionExecutor(page, componentContract.selectors, actionTimeoutMs);
|
|
2497
|
+
const allowedTypes = ["focus", "type", "click", "keypress", "hover"];
|
|
2498
|
+
const toSetupAction = (a) => ({
|
|
2499
|
+
...a,
|
|
2500
|
+
type: isAllowedType2(a.type) ? a.type : "click"
|
|
2501
|
+
});
|
|
2502
|
+
const setupActions = test.setup.map(toSetupAction);
|
|
2503
|
+
const setupResult = await runSetupActions(setupActions, actionExecutor, strategy, page, staticDescription, ["submenu", "submenuTrigger", "submenuItems"]);
|
|
2504
|
+
if (setupResult.skip) {
|
|
2505
|
+
skipped.push(setupResult.message || "Setup action skipped");
|
|
2506
|
+
reporter.reportStaticTest(staticDescription, "skip", setupResult.message, staticLevel);
|
|
2507
|
+
continue;
|
|
2508
|
+
}
|
|
2509
|
+
if (!setupResult.success) {
|
|
2510
|
+
const failure = `Static setup failed: ${setupResult.error}`;
|
|
2511
|
+
const outcome = classifyFailure(failure, test.level);
|
|
2512
|
+
if (outcome.status === "fail") staticFailed += 1;
|
|
2513
|
+
if (outcome.status === "warn") staticWarnings += 1;
|
|
2514
|
+
reporter.reportStaticTest(staticDescription, outcome.status, outcome.detail, outcome.level);
|
|
2515
|
+
continue;
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2409
2518
|
const targetSelector = componentContract.selectors[test.target];
|
|
2410
2519
|
if (!targetSelector) {
|
|
2411
2520
|
const failure = `Selector for target ${test.target} not found.`;
|
|
@@ -2532,31 +2641,26 @@ This usually means:
|
|
|
2532
2641
|
const dynamicLevel = normalizeLevel(dynamicTest.level);
|
|
2533
2642
|
const actionExecutor = new ActionExecutor(page, componentContract.selectors, actionTimeoutMs);
|
|
2534
2643
|
if (Array.isArray(setup) && setup.length > 0) {
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
}
|
|
2554
|
-
|
|
2555
|
-
const setupMsg = setupResult.error || "Setup action failed";
|
|
2556
|
-
const outcome = classifyFailure(`Setup failed: ${setupMsg}`, dynamicTest.level);
|
|
2557
|
-
reporter.reportTest({ description: dynamicTest.description, level: dynamicLevel }, outcome.status, outcome.detail);
|
|
2558
|
-
continue;
|
|
2559
|
-
}
|
|
2644
|
+
let isAllowedType2 = function(t) {
|
|
2645
|
+
return allowedTypes.includes(t);
|
|
2646
|
+
};
|
|
2647
|
+
var isAllowedType = isAllowedType2;
|
|
2648
|
+
const allowedTypes = ["focus", "type", "click", "keypress", "hover"];
|
|
2649
|
+
const toSetupAction = (a) => ({
|
|
2650
|
+
...a,
|
|
2651
|
+
type: isAllowedType2(a.type) ? a.type : "click"
|
|
2652
|
+
});
|
|
2653
|
+
const setupActions = setup.map(toSetupAction);
|
|
2654
|
+
const setupResult = await runSetupActions(setupActions, actionExecutor, strategy, page, dynamicTest.description, ["submenu", "submenuTrigger", "submenuItems"]);
|
|
2655
|
+
if (setupResult.skip) {
|
|
2656
|
+
skipped.push(setupResult.message || "Setup action skipped");
|
|
2657
|
+
reporter.reportTest({ description: dynamicTest.description, level: dynamicLevel }, "skip", setupResult.message);
|
|
2658
|
+
continue;
|
|
2659
|
+
}
|
|
2660
|
+
if (!setupResult.success) {
|
|
2661
|
+
const outcome = classifyFailure(`Setup failed: ${setupResult.error}`, dynamicTest.level);
|
|
2662
|
+
reporter.reportTest({ description: dynamicTest.description, level: dynamicLevel }, outcome.status, outcome.detail);
|
|
2663
|
+
continue;
|
|
2560
2664
|
}
|
|
2561
2665
|
}
|
|
2562
2666
|
const failuresBeforeTest = failures.length;
|
|
@@ -3136,25 +3240,6 @@ function validateContractSchema(contract) {
|
|
|
3136
3240
|
});
|
|
3137
3241
|
}
|
|
3138
3242
|
}
|
|
3139
|
-
if (c.states !== void 0) {
|
|
3140
|
-
if (!Array.isArray(c.states)) {
|
|
3141
|
-
errors.push({ path: "$.states", message: "states must be an array" });
|
|
3142
|
-
} else {
|
|
3143
|
-
c.states.forEach((state, idx) => {
|
|
3144
|
-
if (typeof state !== "object" || state === null) {
|
|
3145
|
-
errors.push({ path: `$.states[${idx}]`, message: "state must be an object" });
|
|
3146
|
-
return;
|
|
3147
|
-
}
|
|
3148
|
-
const s = state;
|
|
3149
|
-
if (typeof s.name !== "string") {
|
|
3150
|
-
errors.push({ path: `$.states[${idx}].name`, message: "name is required and must be a string" });
|
|
3151
|
-
}
|
|
3152
|
-
if (!Array.isArray(s.requires)) {
|
|
3153
|
-
errors.push({ path: `$.states[${idx}].requires`, message: "requires is required and must be an array" });
|
|
3154
|
-
}
|
|
3155
|
-
});
|
|
3156
|
-
}
|
|
3157
|
-
}
|
|
3158
3243
|
return {
|
|
3159
3244
|
valid: errors.length === 0,
|
|
3160
3245
|
errors
|
|
@@ -3230,17 +3315,8 @@ function validateTargetReferences(contract, selectorKeys) {
|
|
|
3230
3315
|
});
|
|
3231
3316
|
}
|
|
3232
3317
|
const dynamicItems = c.dynamic;
|
|
3233
|
-
const states = c.states;
|
|
3234
|
-
const stateNames = new Set((states || []).map((s) => String(s.name)));
|
|
3235
3318
|
if (Array.isArray(dynamicItems)) {
|
|
3236
3319
|
dynamicItems.forEach((item, itemIdx) => {
|
|
3237
|
-
const given = item.given;
|
|
3238
|
-
if (given && !stateNames.has(given)) {
|
|
3239
|
-
errors.push({
|
|
3240
|
-
path: `$.dynamic[${itemIdx}].given`,
|
|
3241
|
-
message: `State '${given}' not found in states`
|
|
3242
|
-
});
|
|
3243
|
-
}
|
|
3244
3320
|
const actions = item.action;
|
|
3245
3321
|
if (Array.isArray(actions)) {
|
|
3246
3322
|
actions.forEach((action, actIdx) => {
|
package/dist/cli.js
CHANGED
|
@@ -122,12 +122,12 @@ program.command("audit").description("Run axe-core powered accessibility audit o
|
|
|
122
122
|
process.exit(1);
|
|
123
123
|
});
|
|
124
124
|
program.command("test").description("Run core a11y accessibility standard tests on UI components").action(async () => {
|
|
125
|
-
const { runTest } = await import("./test-
|
|
125
|
+
const { runTest } = await import("./test-WDBS5JWO.js");
|
|
126
126
|
runTest();
|
|
127
127
|
});
|
|
128
128
|
program.command("build").description("Build accessibility artifacts").addCommand(
|
|
129
129
|
new Command("contracts").description("Build DSL contracts to JSON").action(async () => {
|
|
130
|
-
const { buildContracts } = await import("./buildContracts-
|
|
130
|
+
const { buildContracts } = await import("./buildContracts-VIV6GM56.js");
|
|
131
131
|
const { loadConfig: loadConfig2 } = await import("./configLoader-REHK3S3Q.js");
|
|
132
132
|
const cwd = process.cwd();
|
|
133
133
|
const { config, configPath, errors } = await loadConfig2(cwd);
|