aria-ease 3.0.3 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +207 -87
- package/bin/cli.cjs +32 -0
- package/bin/cli.js +1 -1
- package/bin/{contractTestRunnerPlaywright-3VJUZSYK.js → contractTestRunnerPlaywright-EZLNNJV5.js} +32 -0
- package/bin/{test-D374H2ZS.js → test-45KMD4F4.js} +1 -1
- package/dist/{contractTestRunnerPlaywright-4UOHWGWD.js → contractTestRunnerPlaywright-UQQI5MYS.js} +32 -0
- package/dist/index.cjs +624 -1
- package/dist/index.d.cts +83 -2
- package/dist/index.d.ts +83 -2
- package/dist/index.js +589 -2
- package/dist/src/{Types.d-uG0Hm1yK.d.ts → Types.d-BrHSyS03.d.cts} +17 -0
- package/dist/src/{Types.d-uG0Hm1yK.d.cts → Types.d-BrHSyS03.d.ts} +17 -0
- package/dist/src/accordion/index.cjs +159 -0
- package/dist/src/accordion/index.d.cts +19 -2
- package/dist/src/accordion/index.d.ts +19 -2
- package/dist/src/accordion/index.js +159 -1
- package/dist/src/block/index.cjs +1 -1
- package/dist/src/block/index.d.cts +6 -2
- package/dist/src/block/index.d.ts +6 -2
- package/dist/src/block/index.js +1 -1
- package/dist/src/checkbox/index.cjs +129 -0
- package/dist/src/checkbox/index.d.cts +15 -2
- package/dist/src/checkbox/index.d.ts +15 -2
- package/dist/src/checkbox/index.js +129 -1
- package/dist/src/combobox/index.d.cts +1 -1
- package/dist/src/combobox/index.d.ts +1 -1
- package/dist/src/menu/index.cjs +32 -0
- package/dist/src/menu/index.d.cts +1 -1
- package/dist/src/menu/index.d.ts +1 -1
- package/dist/src/menu/index.js +32 -0
- package/dist/src/radio/index.cjs +122 -0
- package/dist/src/radio/index.d.cts +17 -2
- package/dist/src/radio/index.d.ts +17 -2
- package/dist/src/radio/index.js +122 -1
- package/dist/src/toggle/index.cjs +145 -0
- package/dist/src/toggle/index.d.cts +17 -2
- package/dist/src/toggle/index.d.ts +17 -2
- package/dist/src/toggle/index.js +145 -1
- package/dist/src/utils/test/{contractTestRunnerPlaywright-4UOHWGWD.js → contractTestRunnerPlaywright-UQQI5MYS.js} +32 -0
- package/dist/src/utils/test/contracts/MenuContract.json +0 -1
- package/dist/src/utils/test/index.cjs +32 -0
- package/dist/src/utils/test/index.js +1 -1
- package/package.json +1 -1
|
@@ -27,4 +27,149 @@ function updateToggleAriaAttribute(toggleId, togglesClass, toggleStates, current
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// src/toggle/src/makeTogggleAccessible/makeToggleAccessible.ts
|
|
31
|
+
function makeToggleAccessible({ toggleId, togglesClass, isSingleToggle = true }) {
|
|
32
|
+
const toggleContainer = document.querySelector(`#${toggleId}`);
|
|
33
|
+
if (!toggleContainer) {
|
|
34
|
+
console.error(`[aria-ease] Element with id="${toggleId}" not found. Make sure the toggle element exists before calling makeToggleAccessible.`);
|
|
35
|
+
return { cleanup: () => {
|
|
36
|
+
} };
|
|
37
|
+
}
|
|
38
|
+
let toggles;
|
|
39
|
+
if (isSingleToggle) {
|
|
40
|
+
toggles = [toggleContainer];
|
|
41
|
+
} else {
|
|
42
|
+
if (!togglesClass) {
|
|
43
|
+
console.error(`[aria-ease] togglesClass is required when isSingleToggle is false.`);
|
|
44
|
+
return { cleanup: () => {
|
|
45
|
+
} };
|
|
46
|
+
}
|
|
47
|
+
toggles = Array.from(toggleContainer.querySelectorAll(`.${togglesClass}`));
|
|
48
|
+
if (toggles.length === 0) {
|
|
49
|
+
console.error(`[aria-ease] No elements with class="${togglesClass}" found. Make sure toggle buttons exist before calling makeToggleAccessible.`);
|
|
50
|
+
return { cleanup: () => {
|
|
51
|
+
} };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const handlerMap = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
const clickHandlerMap = /* @__PURE__ */ new WeakMap();
|
|
56
|
+
function initialize() {
|
|
57
|
+
toggles.forEach((toggle) => {
|
|
58
|
+
if (toggle.tagName.toLowerCase() !== "button" && !toggle.getAttribute("role")) {
|
|
59
|
+
toggle.setAttribute("role", "button");
|
|
60
|
+
}
|
|
61
|
+
if (!toggle.hasAttribute("aria-pressed")) {
|
|
62
|
+
toggle.setAttribute("aria-pressed", "false");
|
|
63
|
+
}
|
|
64
|
+
if (!toggle.hasAttribute("tabindex")) {
|
|
65
|
+
toggle.setAttribute("tabindex", "0");
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function toggleButton(index) {
|
|
70
|
+
if (index < 0 || index >= toggles.length) {
|
|
71
|
+
console.error(`[aria-ease] Invalid toggle index: ${index}`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const toggle = toggles[index];
|
|
75
|
+
const isPressed = toggle.getAttribute("aria-pressed") === "true";
|
|
76
|
+
toggle.setAttribute("aria-pressed", isPressed ? "false" : "true");
|
|
77
|
+
}
|
|
78
|
+
function setPressed(index, pressed) {
|
|
79
|
+
if (index < 0 || index >= toggles.length) {
|
|
80
|
+
console.error(`[aria-ease] Invalid toggle index: ${index}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
toggles[index].setAttribute("aria-pressed", pressed ? "true" : "false");
|
|
84
|
+
}
|
|
85
|
+
function handleToggleClick(index) {
|
|
86
|
+
return () => {
|
|
87
|
+
toggleButton(index);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function handleToggleKeydown(index) {
|
|
91
|
+
return (event) => {
|
|
92
|
+
const { key } = event;
|
|
93
|
+
switch (key) {
|
|
94
|
+
case "Enter":
|
|
95
|
+
case " ":
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
toggleButton(index);
|
|
98
|
+
break;
|
|
99
|
+
case "ArrowDown":
|
|
100
|
+
case "ArrowRight":
|
|
101
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
const nextIndex = (index + 1) % toggles.length;
|
|
104
|
+
toggles[nextIndex].focus();
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
case "ArrowUp":
|
|
108
|
+
case "ArrowLeft":
|
|
109
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
const prevIndex = (index - 1 + toggles.length) % toggles.length;
|
|
112
|
+
toggles[prevIndex].focus();
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
case "Home":
|
|
116
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
117
|
+
event.preventDefault();
|
|
118
|
+
toggles[0].focus();
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
case "End":
|
|
122
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
toggles[toggles.length - 1].focus();
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function addListeners() {
|
|
131
|
+
toggles.forEach((toggle, index) => {
|
|
132
|
+
const clickHandler = handleToggleClick(index);
|
|
133
|
+
const keydownHandler = handleToggleKeydown(index);
|
|
134
|
+
toggle.addEventListener("click", clickHandler);
|
|
135
|
+
toggle.addEventListener("keydown", keydownHandler);
|
|
136
|
+
handlerMap.set(toggle, keydownHandler);
|
|
137
|
+
clickHandlerMap.set(toggle, clickHandler);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function removeListeners() {
|
|
141
|
+
toggles.forEach((toggle) => {
|
|
142
|
+
const keydownHandler = handlerMap.get(toggle);
|
|
143
|
+
const clickHandler = clickHandlerMap.get(toggle);
|
|
144
|
+
if (keydownHandler) {
|
|
145
|
+
toggle.removeEventListener("keydown", keydownHandler);
|
|
146
|
+
handlerMap.delete(toggle);
|
|
147
|
+
}
|
|
148
|
+
if (clickHandler) {
|
|
149
|
+
toggle.removeEventListener("click", clickHandler);
|
|
150
|
+
clickHandlerMap.delete(toggle);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function cleanup() {
|
|
155
|
+
removeListeners();
|
|
156
|
+
}
|
|
157
|
+
function getPressedStates() {
|
|
158
|
+
return toggles.map((toggle) => toggle.getAttribute("aria-pressed") === "true");
|
|
159
|
+
}
|
|
160
|
+
function getPressedIndices() {
|
|
161
|
+
return toggles.map((toggle, index) => toggle.getAttribute("aria-pressed") === "true" ? index : -1).filter((index) => index !== -1);
|
|
162
|
+
}
|
|
163
|
+
initialize();
|
|
164
|
+
addListeners();
|
|
165
|
+
return {
|
|
166
|
+
toggleButton,
|
|
167
|
+
setPressed,
|
|
168
|
+
getPressedStates,
|
|
169
|
+
getPressedIndices,
|
|
170
|
+
cleanup
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
exports.makeToggleAccessible = makeToggleAccessible;
|
|
30
175
|
exports.updateToggleAriaAttribute = updateToggleAriaAttribute;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as ToggleStates } from '../Types.d-
|
|
1
|
+
import { T as ToggleStates, a as AccessibilityInstance } from '../Types.d-BrHSyS03.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adds screen reader accessibility to toggle buttons. Updates the aria attributes of the toggle buttons. Button must be a semantic button element or a non-semantic element with a role of button, and possess the aria-pressed attribute.
|
|
@@ -10,4 +10,19 @@ import { T as ToggleStates } from '../Types.d-uG0Hm1yK.cjs';
|
|
|
10
10
|
|
|
11
11
|
declare function updateToggleAriaAttribute(toggleId: string, togglesClass: string, toggleStates: ToggleStates[], currentPressedToggleIndex: number): void;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Makes a toggle button accessible by managing ARIA attributes and keyboard interactions.
|
|
15
|
+
* Handles toggle button state with proper focus management.
|
|
16
|
+
* @param {string} toggleId - The id of the toggle button or toggle button container.
|
|
17
|
+
* @param {string} togglesClass - The shared class of toggle buttons (for groups).
|
|
18
|
+
* @param {boolean} isSingleToggle - Whether this is a single toggle button (default: true).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface ToggleConfig {
|
|
22
|
+
toggleId: string;
|
|
23
|
+
togglesClass?: string;
|
|
24
|
+
isSingleToggle?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare function makeToggleAccessible({ toggleId, togglesClass, isSingleToggle }: ToggleConfig): AccessibilityInstance;
|
|
27
|
+
|
|
28
|
+
export { makeToggleAccessible, updateToggleAriaAttribute };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as ToggleStates } from '../Types.d-
|
|
1
|
+
import { T as ToggleStates, a as AccessibilityInstance } from '../Types.d-BrHSyS03.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adds screen reader accessibility to toggle buttons. Updates the aria attributes of the toggle buttons. Button must be a semantic button element or a non-semantic element with a role of button, and possess the aria-pressed attribute.
|
|
@@ -10,4 +10,19 @@ import { T as ToggleStates } from '../Types.d-uG0Hm1yK.js';
|
|
|
10
10
|
|
|
11
11
|
declare function updateToggleAriaAttribute(toggleId: string, togglesClass: string, toggleStates: ToggleStates[], currentPressedToggleIndex: number): void;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Makes a toggle button accessible by managing ARIA attributes and keyboard interactions.
|
|
15
|
+
* Handles toggle button state with proper focus management.
|
|
16
|
+
* @param {string} toggleId - The id of the toggle button or toggle button container.
|
|
17
|
+
* @param {string} togglesClass - The shared class of toggle buttons (for groups).
|
|
18
|
+
* @param {boolean} isSingleToggle - Whether this is a single toggle button (default: true).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface ToggleConfig {
|
|
22
|
+
toggleId: string;
|
|
23
|
+
togglesClass?: string;
|
|
24
|
+
isSingleToggle?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare function makeToggleAccessible({ toggleId, togglesClass, isSingleToggle }: ToggleConfig): AccessibilityInstance;
|
|
27
|
+
|
|
28
|
+
export { makeToggleAccessible, updateToggleAriaAttribute };
|
package/dist/src/toggle/index.js
CHANGED
|
@@ -25,4 +25,148 @@ function updateToggleAriaAttribute(toggleId, togglesClass, toggleStates, current
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
// src/toggle/src/makeTogggleAccessible/makeToggleAccessible.ts
|
|
29
|
+
function makeToggleAccessible({ toggleId, togglesClass, isSingleToggle = true }) {
|
|
30
|
+
const toggleContainer = document.querySelector(`#${toggleId}`);
|
|
31
|
+
if (!toggleContainer) {
|
|
32
|
+
console.error(`[aria-ease] Element with id="${toggleId}" not found. Make sure the toggle element exists before calling makeToggleAccessible.`);
|
|
33
|
+
return { cleanup: () => {
|
|
34
|
+
} };
|
|
35
|
+
}
|
|
36
|
+
let toggles;
|
|
37
|
+
if (isSingleToggle) {
|
|
38
|
+
toggles = [toggleContainer];
|
|
39
|
+
} else {
|
|
40
|
+
if (!togglesClass) {
|
|
41
|
+
console.error(`[aria-ease] togglesClass is required when isSingleToggle is false.`);
|
|
42
|
+
return { cleanup: () => {
|
|
43
|
+
} };
|
|
44
|
+
}
|
|
45
|
+
toggles = Array.from(toggleContainer.querySelectorAll(`.${togglesClass}`));
|
|
46
|
+
if (toggles.length === 0) {
|
|
47
|
+
console.error(`[aria-ease] No elements with class="${togglesClass}" found. Make sure toggle buttons exist before calling makeToggleAccessible.`);
|
|
48
|
+
return { cleanup: () => {
|
|
49
|
+
} };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const handlerMap = /* @__PURE__ */ new WeakMap();
|
|
53
|
+
const clickHandlerMap = /* @__PURE__ */ new WeakMap();
|
|
54
|
+
function initialize() {
|
|
55
|
+
toggles.forEach((toggle) => {
|
|
56
|
+
if (toggle.tagName.toLowerCase() !== "button" && !toggle.getAttribute("role")) {
|
|
57
|
+
toggle.setAttribute("role", "button");
|
|
58
|
+
}
|
|
59
|
+
if (!toggle.hasAttribute("aria-pressed")) {
|
|
60
|
+
toggle.setAttribute("aria-pressed", "false");
|
|
61
|
+
}
|
|
62
|
+
if (!toggle.hasAttribute("tabindex")) {
|
|
63
|
+
toggle.setAttribute("tabindex", "0");
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function toggleButton(index) {
|
|
68
|
+
if (index < 0 || index >= toggles.length) {
|
|
69
|
+
console.error(`[aria-ease] Invalid toggle index: ${index}`);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const toggle = toggles[index];
|
|
73
|
+
const isPressed = toggle.getAttribute("aria-pressed") === "true";
|
|
74
|
+
toggle.setAttribute("aria-pressed", isPressed ? "false" : "true");
|
|
75
|
+
}
|
|
76
|
+
function setPressed(index, pressed) {
|
|
77
|
+
if (index < 0 || index >= toggles.length) {
|
|
78
|
+
console.error(`[aria-ease] Invalid toggle index: ${index}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
toggles[index].setAttribute("aria-pressed", pressed ? "true" : "false");
|
|
82
|
+
}
|
|
83
|
+
function handleToggleClick(index) {
|
|
84
|
+
return () => {
|
|
85
|
+
toggleButton(index);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function handleToggleKeydown(index) {
|
|
89
|
+
return (event) => {
|
|
90
|
+
const { key } = event;
|
|
91
|
+
switch (key) {
|
|
92
|
+
case "Enter":
|
|
93
|
+
case " ":
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
toggleButton(index);
|
|
96
|
+
break;
|
|
97
|
+
case "ArrowDown":
|
|
98
|
+
case "ArrowRight":
|
|
99
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
100
|
+
event.preventDefault();
|
|
101
|
+
const nextIndex = (index + 1) % toggles.length;
|
|
102
|
+
toggles[nextIndex].focus();
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
case "ArrowUp":
|
|
106
|
+
case "ArrowLeft":
|
|
107
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
108
|
+
event.preventDefault();
|
|
109
|
+
const prevIndex = (index - 1 + toggles.length) % toggles.length;
|
|
110
|
+
toggles[prevIndex].focus();
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case "Home":
|
|
114
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
115
|
+
event.preventDefault();
|
|
116
|
+
toggles[0].focus();
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
case "End":
|
|
120
|
+
if (!isSingleToggle && toggles.length > 1) {
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
toggles[toggles.length - 1].focus();
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function addListeners() {
|
|
129
|
+
toggles.forEach((toggle, index) => {
|
|
130
|
+
const clickHandler = handleToggleClick(index);
|
|
131
|
+
const keydownHandler = handleToggleKeydown(index);
|
|
132
|
+
toggle.addEventListener("click", clickHandler);
|
|
133
|
+
toggle.addEventListener("keydown", keydownHandler);
|
|
134
|
+
handlerMap.set(toggle, keydownHandler);
|
|
135
|
+
clickHandlerMap.set(toggle, clickHandler);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function removeListeners() {
|
|
139
|
+
toggles.forEach((toggle) => {
|
|
140
|
+
const keydownHandler = handlerMap.get(toggle);
|
|
141
|
+
const clickHandler = clickHandlerMap.get(toggle);
|
|
142
|
+
if (keydownHandler) {
|
|
143
|
+
toggle.removeEventListener("keydown", keydownHandler);
|
|
144
|
+
handlerMap.delete(toggle);
|
|
145
|
+
}
|
|
146
|
+
if (clickHandler) {
|
|
147
|
+
toggle.removeEventListener("click", clickHandler);
|
|
148
|
+
clickHandlerMap.delete(toggle);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function cleanup() {
|
|
153
|
+
removeListeners();
|
|
154
|
+
}
|
|
155
|
+
function getPressedStates() {
|
|
156
|
+
return toggles.map((toggle) => toggle.getAttribute("aria-pressed") === "true");
|
|
157
|
+
}
|
|
158
|
+
function getPressedIndices() {
|
|
159
|
+
return toggles.map((toggle, index) => toggle.getAttribute("aria-pressed") === "true" ? index : -1).filter((index) => index !== -1);
|
|
160
|
+
}
|
|
161
|
+
initialize();
|
|
162
|
+
addListeners();
|
|
163
|
+
return {
|
|
164
|
+
toggleButton,
|
|
165
|
+
setPressed,
|
|
166
|
+
getPressedStates,
|
|
167
|
+
getPressedIndices,
|
|
168
|
+
cleanup
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export { makeToggleAccessible, updateToggleAriaAttribute };
|
|
@@ -141,6 +141,38 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
+
let shouldSkipTest = false;
|
|
145
|
+
for (const act of action) {
|
|
146
|
+
if (act.type === "keypress" && (act.target === "submenuTrigger" || act.target === "submenu")) {
|
|
147
|
+
const submenuSelector = componentContract.selectors[act.target];
|
|
148
|
+
if (submenuSelector) {
|
|
149
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
150
|
+
if (submenuCount === 0) {
|
|
151
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
|
|
152
|
+
shouldSkipTest = true;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!shouldSkipTest) {
|
|
159
|
+
for (const assertion of assertions) {
|
|
160
|
+
if (assertion.target === "submenu" || assertion.target === "submenuTrigger") {
|
|
161
|
+
const submenuSelector = componentContract.selectors[assertion.target];
|
|
162
|
+
if (submenuSelector) {
|
|
163
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
164
|
+
if (submenuCount === 0) {
|
|
165
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${assertion.target} element not found (optional submenu test)`);
|
|
166
|
+
shouldSkipTest = true;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (shouldSkipTest) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
144
176
|
for (const act of action) {
|
|
145
177
|
if (act.type === "focus") {
|
|
146
178
|
const focusSelector = componentContract.selectors[act.target];
|
|
@@ -9405,6 +9405,38 @@ async function runContractTestsPlaywright(componentName, url) {
|
|
|
9405
9405
|
}
|
|
9406
9406
|
}
|
|
9407
9407
|
}
|
|
9408
|
+
let shouldSkipTest = false;
|
|
9409
|
+
for (const act of action) {
|
|
9410
|
+
if (act.type === "keypress" && (act.target === "submenuTrigger" || act.target === "submenu")) {
|
|
9411
|
+
const submenuSelector = componentContract.selectors[act.target];
|
|
9412
|
+
if (submenuSelector) {
|
|
9413
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
9414
|
+
if (submenuCount === 0) {
|
|
9415
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
|
|
9416
|
+
shouldSkipTest = true;
|
|
9417
|
+
break;
|
|
9418
|
+
}
|
|
9419
|
+
}
|
|
9420
|
+
}
|
|
9421
|
+
}
|
|
9422
|
+
if (!shouldSkipTest) {
|
|
9423
|
+
for (const assertion of assertions) {
|
|
9424
|
+
if (assertion.target === "submenu" || assertion.target === "submenuTrigger") {
|
|
9425
|
+
const submenuSelector = componentContract.selectors[assertion.target];
|
|
9426
|
+
if (submenuSelector) {
|
|
9427
|
+
const submenuCount = await page.locator(submenuSelector).count();
|
|
9428
|
+
if (submenuCount === 0) {
|
|
9429
|
+
reporter.reportTest(dynamicTest, "skip", `Skipping test - ${assertion.target} element not found (optional submenu test)`);
|
|
9430
|
+
shouldSkipTest = true;
|
|
9431
|
+
break;
|
|
9432
|
+
}
|
|
9433
|
+
}
|
|
9434
|
+
}
|
|
9435
|
+
}
|
|
9436
|
+
}
|
|
9437
|
+
if (shouldSkipTest) {
|
|
9438
|
+
continue;
|
|
9439
|
+
}
|
|
9408
9440
|
for (const act of action) {
|
|
9409
9441
|
if (act.type === "focus") {
|
|
9410
9442
|
const focusSelector = componentContract.selectors[act.target];
|
|
@@ -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-UQQI5MYS.js');
|
|
12584
12584
|
contract = await runContractTestsPlaywright(componentName, url);
|
|
12585
12585
|
} else {
|
|
12586
12586
|
console.log(`\u{1F9EA} Running jsdom tests (limited event handling)`);
|