xmlui 0.10.13 → 0.10.14

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.
Files changed (186) hide show
  1. package/dist/lib/{index-Db5iQkFp.mjs → index-779mp2Bm.mjs} +943 -736
  2. package/dist/lib/index.css +1 -1
  3. package/dist/lib/{initMock-B9LtmFJG.mjs → initMock-CAXdczCj.mjs} +1 -1
  4. package/dist/lib/xmlui.d.ts +16 -1
  5. package/dist/lib/xmlui.mjs +33 -32
  6. package/dist/metadata/{collectedComponentMetadata-BN8eg9Gr.mjs → collectedComponentMetadata-7DFXlw-J.mjs} +15057 -14865
  7. package/dist/metadata/{initMock-J7pN8owj.mjs → initMock-AFWEftc6.mjs} +1 -1
  8. package/dist/metadata/style.css +1 -1
  9. package/dist/metadata/xmlui-metadata.mjs +1 -1
  10. package/dist/metadata/xmlui-metadata.umd.js +3 -3
  11. package/dist/scripts/bin/build-lib.js +21 -13
  12. package/dist/scripts/bin/viteConfig.js +3 -1
  13. package/dist/scripts/package.json +1 -1
  14. package/dist/scripts/src/abstractions/scripting/Token.js +2 -0
  15. package/dist/scripts/src/abstractions/scripting/TryScope.js +2 -0
  16. package/dist/scripts/src/abstractions/scripting/modules.js +2 -0
  17. package/dist/scripts/src/components/APICall/APICall.spec.js +910 -0
  18. package/dist/scripts/src/components/Accordion/Accordion.spec.js +969 -0
  19. package/dist/scripts/src/components/Animation/Animation.js +50 -0
  20. package/dist/scripts/src/components/App/App.spec.js +219 -0
  21. package/dist/scripts/src/components/AppHeader/AppHeader.spec.js +169 -0
  22. package/dist/scripts/src/components/AppState/AppState.spec.js +268 -0
  23. package/dist/scripts/src/components/AutoComplete/AutoComplete.spec.js +383 -0
  24. package/dist/scripts/src/components/Avatar/Avatar.spec.js +1543 -0
  25. package/dist/scripts/src/components/Backdrop/Backdrop.spec.js +131 -0
  26. package/dist/scripts/src/components/Badge/Badge.spec.js +2214 -0
  27. package/dist/scripts/src/components/Bookmark/Bookmark.spec.js +230 -0
  28. package/dist/scripts/src/components/Breakout/Breakout.spec.js +56 -0
  29. package/dist/scripts/src/components/Button/Button-style.spec.js +274 -0
  30. package/dist/scripts/src/components/Button/Button.spec.js +454 -0
  31. package/dist/scripts/src/components/Card/Card.spec.js +150 -0
  32. package/dist/scripts/src/components/Carousel/Carousel.spec.js +343 -0
  33. package/dist/scripts/src/components/Carousel/CarouselNative.js +2 -2
  34. package/dist/scripts/src/components/ChangeListener/ChangeListener.spec.js +169 -0
  35. package/dist/scripts/src/components/Charts/AreaChart/AreaChart.spec.js +999 -0
  36. package/dist/scripts/src/components/Charts/BarChart/BarChart.spec.js +597 -0
  37. package/dist/scripts/src/components/Charts/DonutChart/DonutChart.spec.js +608 -0
  38. package/dist/scripts/src/components/Charts/LabelList/LabelList.spec.js +539 -0
  39. package/dist/scripts/src/components/Charts/Legend/Legend.spec.js +558 -0
  40. package/dist/scripts/src/components/Charts/LineChart/LineChart.spec.js +450 -0
  41. package/dist/scripts/src/components/Charts/PieChart/PieChart.spec.js +584 -0
  42. package/dist/scripts/src/components/Charts/RadarChart/RadarChart.spec.js +571 -0
  43. package/dist/scripts/src/components/Charts/Tooltip/TooltipContent.spec.js +449 -0
  44. package/dist/scripts/src/components/Checkbox/Checkbox.spec.js +964 -0
  45. package/dist/scripts/src/components/CodeBlock/CodeBlock.spec.js +196 -0
  46. package/dist/scripts/src/components/ColorPicker/ColorPicker.spec.js +283 -0
  47. package/dist/scripts/src/components/ColorPicker/ColorPickerNative.js +9 -26
  48. package/dist/scripts/src/components/Column/doc-resources/list-component-data.js +53 -0
  49. package/dist/scripts/src/components/ComponentProvider.js +6 -2
  50. package/dist/scripts/src/components/ContentSeparator/ContentSeparator.spec.js +338 -0
  51. package/dist/scripts/src/components/DateInput/DateInput.spec.js +918 -0
  52. package/dist/scripts/src/components/DatePicker/DatePicker.spec.js +362 -0
  53. package/dist/scripts/src/components/DatePicker/DatePickerNative.js +3 -3
  54. package/dist/scripts/src/components/DropdownMenu/DropdownMenu.spec.js +331 -0
  55. package/dist/scripts/src/components/EmojiSelector/EmojiSelector.spec.js +29 -0
  56. package/dist/scripts/src/components/ExpandableItem/ExpandableItem.spec.js +435 -0
  57. package/dist/scripts/src/components/FileInput/FileInput.spec.js +249 -0
  58. package/dist/scripts/src/components/FileUploadDropZone/FileUploadDropZone.spec.js +296 -0
  59. package/dist/scripts/src/components/FlowLayout/FlowLayout.spec.js +518 -0
  60. package/dist/scripts/src/components/Footer/Footer.spec.js +991 -0
  61. package/dist/scripts/src/components/Form/Form.spec.js +1257 -0
  62. package/dist/scripts/src/components/FormItem/FormItem.spec.js +723 -0
  63. package/dist/scripts/src/components/FormSection/FormSection.js +6 -31
  64. package/dist/scripts/src/components/Fragment/Fragment.spec.js +50 -0
  65. package/dist/scripts/src/components/Heading/H1.spec.js +66 -0
  66. package/dist/scripts/src/components/Heading/H2.spec.js +66 -0
  67. package/dist/scripts/src/components/Heading/H3.spec.js +66 -0
  68. package/dist/scripts/src/components/Heading/H4.spec.js +66 -0
  69. package/dist/scripts/src/components/Heading/H5.spec.js +66 -0
  70. package/dist/scripts/src/components/Heading/H6.spec.js +66 -0
  71. package/dist/scripts/src/components/Heading/Heading.spec.js +897 -0
  72. package/dist/scripts/src/components/HtmlTags/HtmlTags.spec.js +69 -0
  73. package/dist/scripts/src/components/IFrame/IFrame.spec.js +527 -0
  74. package/dist/scripts/src/components/Icon/ArrowDropDown.js +11 -0
  75. package/dist/scripts/src/components/Icon/ArrowDropUp.js +11 -0
  76. package/dist/scripts/src/components/Icon/ArrowLeft.js +11 -0
  77. package/dist/scripts/src/components/Icon/ArrowRight.js +11 -0
  78. package/dist/scripts/src/components/Icon/ChevronDownIcon.js +7 -0
  79. package/dist/scripts/src/components/Icon/ChevronUpIcon.js +7 -0
  80. package/dist/scripts/src/components/Icon/Icon.spec.js +527 -0
  81. package/dist/scripts/src/components/Icon/SunIcon.js +10 -0
  82. package/dist/scripts/src/components/Image/Image.js +2 -1
  83. package/dist/scripts/src/components/Image/Image.spec.js +198 -0
  84. package/dist/scripts/src/components/Image/ImageNative.js +30 -2
  85. package/dist/scripts/src/components/Input/InputLabel.js +25 -0
  86. package/dist/scripts/src/components/Input/index.js +5 -0
  87. package/dist/scripts/src/components/Items/Items.spec.js +397 -0
  88. package/dist/scripts/src/components/Link/Link.spec.js +894 -0
  89. package/dist/scripts/src/components/List/List.spec.js +927 -0
  90. package/dist/scripts/src/components/List/doc-resources/list-component-data.js +53 -0
  91. package/dist/scripts/src/components/Markdown/Markdown.spec.js +188 -0
  92. package/dist/scripts/src/components/ModalDialog/ModalDialog.spec.js +162 -0
  93. package/dist/scripts/src/components/NavGroup/NavGroup.spec.js +153 -0
  94. package/dist/scripts/src/components/NavGroup/NavGroupNative.js +2 -2
  95. package/dist/scripts/src/components/NavLink/NavLink.spec.js +864 -0
  96. package/dist/scripts/src/components/NavPanel/NavPanel.spec.js +864 -0
  97. package/dist/scripts/src/components/NoResult/NoResult.spec.js +863 -0
  98. package/dist/scripts/src/components/NumberBox/NumberBox.spec.js +1231 -0
  99. package/dist/scripts/src/components/Option/Option.spec.js +472 -0
  100. package/dist/scripts/src/components/PageMetaTitle/PageMetaTitle.spec.js +80 -0
  101. package/dist/scripts/src/components/Pagination/Pagination.spec.js +1003 -0
  102. package/dist/scripts/src/components/ProfileMenu/ProfileMenu.js +20 -0
  103. package/dist/scripts/src/components/ProgressBar/ProgressBar.spec.js +166 -0
  104. package/dist/scripts/src/components/Queue/Queue.spec.js +626 -0
  105. package/dist/scripts/src/components/RadioGroup/RadioGroup.spec.js +479 -0
  106. package/dist/scripts/src/components/Redirect/Redirect.spec.js +527 -0
  107. package/dist/scripts/src/components/ResponsiveBar/ResponsiveBar.spec.js +76 -0
  108. package/dist/scripts/src/components/Select/Select.spec.js +527 -0
  109. package/dist/scripts/src/components/Slider/Slider.js +2 -0
  110. package/dist/scripts/src/components/Slider/Slider.spec.js +574 -0
  111. package/dist/scripts/src/components/Slider/SliderNative.js +62 -25
  112. package/dist/scripts/src/components/Slot/Slot.spec.js +368 -0
  113. package/dist/scripts/src/components/SpaceFiller/SpaceFiller.spec.js +184 -0
  114. package/dist/scripts/src/components/Spinner/Spinner.spec.js +161 -0
  115. package/dist/scripts/src/components/Splitter/HSplitter.spec.js +104 -0
  116. package/dist/scripts/src/components/Splitter/Splitter.spec.js +543 -0
  117. package/dist/scripts/src/components/Splitter/VSplitter.spec.js +104 -0
  118. package/dist/scripts/src/components/Stack/CHStack.spec.js +86 -0
  119. package/dist/scripts/src/components/Stack/CVStack.spec.js +86 -0
  120. package/dist/scripts/src/components/Stack/HStack.spec.js +67 -0
  121. package/dist/scripts/src/components/Stack/Stack.spec.js +654 -0
  122. package/dist/scripts/src/components/Stack/VStack.spec.js +67 -0
  123. package/dist/scripts/src/components/Switch/Switch.spec.js +829 -0
  124. package/dist/scripts/src/components/Table/Table.spec.js +555 -0
  125. package/dist/scripts/src/components/Table/doc-resources/list-component-data.js +53 -0
  126. package/dist/scripts/src/components/TableOfContents/TableOfContents.spec.js +838 -0
  127. package/dist/scripts/src/components/Tabs/Tabs.spec.js +875 -0
  128. package/dist/scripts/src/components/Text/Text.spec.js +1075 -0
  129. package/dist/scripts/src/components/TextArea/TextArea.spec.js +714 -0
  130. package/dist/scripts/src/components/TextBox/TextBox.spec.js +643 -0
  131. package/dist/scripts/src/components/Theme/Theme.spec.js +124 -0
  132. package/dist/scripts/src/components/TimeInput/TimeInput.spec.js +1122 -0
  133. package/dist/scripts/src/components/Timer/Timer.spec.js +358 -0
  134. package/dist/scripts/src/components/ToneChangerButton/ToneChangerButton.spec.js +414 -0
  135. package/dist/scripts/src/components/ToneSwitch/ToneSwitch.spec.js +89 -0
  136. package/dist/scripts/src/components/Tooltip/Tooltip.spec.js +418 -0
  137. package/dist/scripts/src/components/chart-color-schemes.js +43 -0
  138. package/dist/scripts/src/components-core/CompoundComponent.js +1 -1
  139. package/dist/scripts/src/components-core/RestApiProxy.js +85 -8
  140. package/dist/scripts/src/components-core/devtools/InspectorDialogVisibilityContext.js +8 -0
  141. package/dist/scripts/src/components-core/renderers.js +31 -0
  142. package/dist/scripts/src/components-core/script-runner/simplify-expression.js +386 -0
  143. package/dist/scripts/src/components-core/theming/component-layout-resolver.js +153 -0
  144. package/dist/scripts/src/components-core/theming/parse-layout-props.js +98 -0
  145. package/dist/scripts/src/components-core/theming/themes/solid.js +16 -0
  146. package/dist/scripts/src/components-core/utils/audio-utils.js +83 -0
  147. package/dist/scripts/src/index-standalone.js +61 -0
  148. package/dist/scripts/src/index.js +2 -1
  149. package/dist/scripts/src/language-server/server-common.js +151 -0
  150. package/dist/scripts/src/language-server/server-web-worker.js +47 -0
  151. package/dist/scripts/src/language-server/server.js +42 -0
  152. package/dist/scripts/src/language-server/services/common/docs-generation.js +73 -0
  153. package/dist/scripts/src/language-server/services/common/lsp-utils.js +9 -0
  154. package/dist/scripts/src/language-server/services/common/syntax-node-utilities.js +135 -0
  155. package/dist/scripts/src/language-server/services/completion.js +270 -0
  156. package/dist/scripts/src/language-server/services/diagnostic.js +19 -0
  157. package/dist/scripts/src/language-server/services/format.js +430 -0
  158. package/dist/scripts/src/language-server/services/hover.js +164 -0
  159. package/dist/scripts/src/language-server/xmlui-metadata-generated.mjs +16266 -0
  160. package/dist/scripts/src/logging/xmlui.js +21 -0
  161. package/dist/scripts/src/parsers/common/utils.js +19 -0
  162. package/dist/scripts/src/syntax/monaco/grammar.monacoLanguage.js +286 -0
  163. package/dist/scripts/src/syntax/monaco/index.js +14 -0
  164. package/dist/scripts/src/syntax/monaco/xmlui-dark.js +25 -0
  165. package/dist/scripts/src/syntax/monaco/xmlui-light.js +25 -0
  166. package/dist/scripts/src/syntax/monaco/xmluiscript.monacoLanguage.js +310 -0
  167. package/dist/scripts/src/syntax/textMate/index.js +14 -0
  168. package/dist/scripts/src/syntax/textMate/xmlui-dark.json +631 -0
  169. package/dist/scripts/src/syntax/textMate/xmlui-light.json +565 -0
  170. package/dist/scripts/src/syntax/textMate/xmlui.json +564 -0
  171. package/dist/scripts/src/syntax/textMate/xmlui.tmLanguage.json +341 -0
  172. package/dist/scripts/src/testing/ComponentDrivers.js +1355 -0
  173. package/dist/scripts/src/testing/assertions.js +444 -0
  174. package/dist/scripts/src/testing/component-test-helpers.js +389 -0
  175. package/dist/scripts/src/testing/drivers/DateInputDriver.js +19 -0
  176. package/dist/scripts/src/testing/drivers/ModalDialogDriver.js +10 -0
  177. package/dist/scripts/src/testing/drivers/TimeInputDriver.js +22 -0
  178. package/dist/scripts/src/testing/drivers/TimerDriver.js +64 -0
  179. package/dist/scripts/src/testing/fixtures.js +487 -0
  180. package/dist/scripts/src/testing/infrastructure/TestBed.js +17 -0
  181. package/dist/scripts/src/testing/infrastructure/main.js +9 -0
  182. package/dist/scripts/src/testing/infrastructure/public/mockServiceWorker.js +266 -0
  183. package/dist/scripts/src/testing/themed-app-test-helpers.js +139 -0
  184. package/dist/standalone/xmlui-standalone.es.d.ts +18 -1
  185. package/dist/standalone/xmlui-standalone.umd.js +36 -36
  186. package/package.json +1 -1
@@ -0,0 +1,1355 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SpinnerDriver = exports.LabelDriver = exports.CheckboxDriver = exports.CodeBlockDriver = exports.HtmlTagDriver = exports.FormItemDriver = exports.OptionDriver = exports.NoResultDriver = exports.BadgeDriver = exports.AppFooterDriver = exports.AppHeaderDriver = exports.AccordionDriver = exports.CardDriver = exports.NavPanelDriver = exports.NavGroupDriver = exports.NavLinkDriver = exports.LinkDriver = exports.VStackDriver = exports.HStackDriver = exports.StackDriver = exports.IconDriver = exports.HeadingDriver = exports.TextDriver = exports.ListDriver = exports.ProgressBarDriver = exports.TextAreaDriver = exports.TextBoxDriver = exports.NumberBoxDriver = exports.RadioGroupDriver = exports.SelectDriver = exports.AutoCompleteDriver = exports.DatePickerDriver = exports.RangeDriver = exports.SliderDriver = exports.ItemsDriver = exports.MarkdownDriver = exports.ValidationDisplayDriver = exports.ValidationSummaryDriver = exports.FormDriver = exports.BackdropDriver = exports.FileUploadDropZoneDriver = exports.FileInputDriver = exports.ExpandableItemDriver = exports.SplitterDriver = exports.AvatarDriver = exports.ContentSeparatorDriver = exports.ButtonDriver = exports.TestStateDriver = exports.InputComponentDriver = exports.ComponentDriver = void 0;
13
+ exports.DropdownMenuDriver = void 0;
14
+ const component_test_helpers_1 = require("./component-test-helpers");
15
+ class ComponentDriver {
16
+ constructor({ locator, page }) {
17
+ // NOTE: methods must be created using the arrow function notation.
18
+ // Otherwise, the "this" will not be correctly bound to the class instance when destructuring.
19
+ this.click = (options) => __awaiter(this, void 0, void 0, function* () {
20
+ yield this.locator.click(options);
21
+ });
22
+ this.dblclick = (options) => __awaiter(this, void 0, void 0, function* () {
23
+ yield this.locator.dblclick(options);
24
+ });
25
+ this.focus = (options) => __awaiter(this, void 0, void 0, function* () {
26
+ yield this.locator.focus(options);
27
+ });
28
+ this.blur = (options) => __awaiter(this, void 0, void 0, function* () {
29
+ yield this.locator.blur(options);
30
+ });
31
+ this.hover = (options) => __awaiter(this, void 0, void 0, function* () {
32
+ yield this.locator.hover(options);
33
+ });
34
+ this.locator = locator;
35
+ this.page = page;
36
+ }
37
+ get component() {
38
+ return this.locator;
39
+ }
40
+ getByPartName(part) {
41
+ return this.component.locator(`[data-part-id="${part}"]`).first();
42
+ }
43
+ /**
44
+ * Gets the html tag name of the final rendered component
45
+ */
46
+ getComponentTagName() {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ return this.component.evaluate((el) => el.tagName.toLowerCase());
49
+ });
50
+ }
51
+ }
52
+ exports.ComponentDriver = ComponentDriver;
53
+ class InputComponentDriver extends ComponentDriver {
54
+ get field() {
55
+ return this.getByPartName("input");
56
+ }
57
+ get label() {
58
+ return this.getByPartName("label");
59
+ }
60
+ get placeholder() {
61
+ return this.field.getAttribute("placeholder");
62
+ }
63
+ get requiredIndicator() {
64
+ return this.component.getByText("*");
65
+ }
66
+ }
67
+ exports.InputComponentDriver = InputComponentDriver;
68
+ class TestStateDriver {
69
+ constructor(testStateLocator) {
70
+ this.testStateLocator = testStateLocator;
71
+ }
72
+ /** returns an async function that can query the test state */
73
+ get testState() {
74
+ return () => __awaiter(this, void 0, void 0, function* () {
75
+ const text = yield this.testStateLocator.textContent();
76
+ const testState = text === "undefined" ? undefined : JSON.parse(text);
77
+ return testState;
78
+ });
79
+ }
80
+ }
81
+ exports.TestStateDriver = TestStateDriver;
82
+ // --- Button
83
+ class ButtonDriver extends ComponentDriver {
84
+ // Ensure we either get rtl or ltr strings
85
+ /* async getWritingDirection() {
86
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir
87
+ const attribute = await this.locator.getAttribute("dir");
88
+ if (attribute && attribute !== "auto") return attribute as "rtl" | "ltr";
89
+ const style = await this.locator.evaluate(
90
+ (element) => window.getComputedStyle(element).direction,
91
+ );
92
+ // Default is ltr: https://developer.mozilla.org/en-US/docs/Web/CSS/direction#values
93
+ return style === "rtl" ? "rtl" : "ltr";
94
+ } */
95
+ // Unused as of yet
96
+ /* async getTextNodes() {
97
+ return await this.locator.evaluate((element) =>
98
+ [...element.childNodes]
99
+ .filter((e) => e.nodeType === Node.TEXT_NODE && e.textContent.trim())
100
+ .map((e) => e.textContent.trim()),
101
+ );
102
+ }
103
+ */
104
+ getFirstNonTextNode() {
105
+ return this.locator.locator("> *").first();
106
+ }
107
+ // NOTE: Accounts for icons being passed as children as well
108
+ getIcons() {
109
+ return this.locator.locator("> svg").or(this.locator.locator("> img"));
110
+ }
111
+ }
112
+ exports.ButtonDriver = ButtonDriver;
113
+ // --- ContentSeparator
114
+ class ContentSeparatorDriver extends ComponentDriver {
115
+ get separator() {
116
+ return this.component;
117
+ }
118
+ getOrientation() {
119
+ return __awaiter(this, void 0, void 0, function* () {
120
+ const classList = yield this.separator.evaluate((el) => el.className);
121
+ if (classList.includes("horizontal"))
122
+ return "horizontal";
123
+ if (classList.includes("vertical"))
124
+ return "vertical";
125
+ return "unknown";
126
+ });
127
+ }
128
+ getComputedHeight() {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ return yield this.separator.evaluate((el) => {
131
+ return window.getComputedStyle(el).height;
132
+ });
133
+ });
134
+ }
135
+ getComputedWidth() {
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ return yield this.separator.evaluate((el) => {
138
+ return window.getComputedStyle(el).width;
139
+ });
140
+ });
141
+ }
142
+ getBackgroundColor() {
143
+ return __awaiter(this, void 0, void 0, function* () {
144
+ return yield this.separator.evaluate((el) => {
145
+ return window.getComputedStyle(el).backgroundColor;
146
+ });
147
+ });
148
+ }
149
+ }
150
+ exports.ContentSeparatorDriver = ContentSeparatorDriver;
151
+ // --- Avatar
152
+ class AvatarDriver extends ComponentDriver {
153
+ }
154
+ exports.AvatarDriver = AvatarDriver;
155
+ // --- Splitter
156
+ class SplitterDriver extends ComponentDriver {
157
+ /**
158
+ * Gets the resizer element (non-floating)
159
+ */
160
+ getResizer() {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ // Look for the non-floating resizer element
163
+ const allResizerCandidates = this.locator.locator('[class*="resizer"]');
164
+ const resizerCount = yield allResizerCandidates.count();
165
+ for (let i = 0; i < resizerCount; i++) {
166
+ const candidate = allResizerCandidates.nth(i);
167
+ const className = yield candidate.getAttribute("class");
168
+ // Look for resizer that doesn't contain "floating" in its class
169
+ if (className && className.includes("resizer") && !className.includes("floating")) {
170
+ return candidate;
171
+ }
172
+ }
173
+ // Fallback: return first resizer element
174
+ return allResizerCandidates.first();
175
+ });
176
+ }
177
+ /**
178
+ * Gets the floating resizer element
179
+ */
180
+ getFloatingResizer() {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ // Look for the floating resizer element
183
+ const allResizerCandidates = this.locator.locator('[class*="resizer"]');
184
+ const resizerCount = yield allResizerCandidates.count();
185
+ for (let i = 0; i < resizerCount; i++) {
186
+ const candidate = allResizerCandidates.nth(i);
187
+ const className = yield candidate.getAttribute("class");
188
+ // Look for resizer that contains "floating" in its class
189
+ if (className && className.includes("floating")) {
190
+ return candidate;
191
+ }
192
+ }
193
+ // If no floating resizer found, return null locator
194
+ return this.locator.locator('[class*="floating"][class*="resizer"]').first();
195
+ });
196
+ }
197
+ /**
198
+ * Hovers near the resizer area to trigger floating resizer visibility
199
+ */
200
+ hoverNearResizer() {
201
+ return __awaiter(this, void 0, void 0, function* () {
202
+ // Get the center of the splitter and hover there
203
+ const bounds = yield this.locator.boundingBox();
204
+ if (bounds) {
205
+ yield this.page.mouse.move(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
206
+ // Wait a bit for the hover effect to take place
207
+ yield this.page.waitForTimeout(200);
208
+ }
209
+ });
210
+ }
211
+ /**
212
+ * Drags the resizer by the specified offset
213
+ * @param deltaX - Horizontal offset in pixels
214
+ * @param deltaY - Vertical offset in pixels
215
+ */
216
+ dragResizer(deltaX, deltaY) {
217
+ return __awaiter(this, void 0, void 0, function* () {
218
+ // Try to get both types of resizers
219
+ const resizer = yield this.getResizer();
220
+ const floatingResizer = yield this.getFloatingResizer();
221
+ // Determine which resizer to use based on visibility
222
+ let targetResizer = resizer;
223
+ try {
224
+ const isResizerVisible = yield resizer.isVisible();
225
+ const isFloatingResizerVisible = yield floatingResizer.isVisible();
226
+ if (!isResizerVisible && isFloatingResizerVisible) {
227
+ targetResizer = floatingResizer;
228
+ }
229
+ else if (!isResizerVisible) {
230
+ // If neither is visible, try to hover to make floating resizer visible
231
+ yield this.hoverNearResizer();
232
+ targetResizer = floatingResizer;
233
+ }
234
+ }
235
+ catch (error) {
236
+ // If there's any error checking visibility, use the regular resizer
237
+ targetResizer = resizer;
238
+ }
239
+ // Get the resizer bounds
240
+ const resizerBounds = yield targetResizer.boundingBox();
241
+ if (!resizerBounds) {
242
+ throw new Error("Could not get resizer bounds for drag operation");
243
+ }
244
+ const startX = resizerBounds.x + resizerBounds.width / 2;
245
+ const startY = resizerBounds.y + resizerBounds.height / 2;
246
+ const endX = startX + deltaX;
247
+ const endY = startY + deltaY;
248
+ // Perform the drag operation
249
+ yield this.page.mouse.move(startX, startY);
250
+ yield this.page.mouse.down();
251
+ yield this.page.mouse.move(endX, endY, { steps: 5 });
252
+ yield this.page.mouse.up();
253
+ // Wait a bit for the component to update
254
+ yield this.page.waitForTimeout(100);
255
+ });
256
+ }
257
+ /**
258
+ * Gets the primary panel element
259
+ */
260
+ getPrimaryPanel() {
261
+ return __awaiter(this, void 0, void 0, function* () {
262
+ return this.locator.locator('[class*="primaryPanel"]').first();
263
+ });
264
+ }
265
+ /**
266
+ * Gets the secondary panel element
267
+ */
268
+ getSecondaryPanel() {
269
+ return __awaiter(this, void 0, void 0, function* () {
270
+ return this.locator.locator('[class*="secondaryPanel"]').first();
271
+ });
272
+ }
273
+ }
274
+ exports.SplitterDriver = SplitterDriver;
275
+ // --- ExpandableItem
276
+ class ExpandableItemDriver extends ComponentDriver {
277
+ getSummary() {
278
+ return this.component.locator('[class*="_summary_"]');
279
+ }
280
+ getSummaryContent() {
281
+ return this.component.locator('[class*="_summaryContent_"]');
282
+ }
283
+ getContent() {
284
+ return this.component.locator('[class*="_content_"]');
285
+ }
286
+ getIcon() {
287
+ return this.component.locator('[class*="_icon_"] svg');
288
+ }
289
+ getSwitch() {
290
+ // Get the actual switch input element, not the wrapper
291
+ return this.component.getByRole("switch");
292
+ }
293
+ isExpanded() {
294
+ return __awaiter(this, void 0, void 0, function* () {
295
+ return yield this.component.locator('[class*="_content_"]').isVisible();
296
+ });
297
+ }
298
+ isDisabled() {
299
+ return __awaiter(this, void 0, void 0, function* () {
300
+ return yield this.component.evaluate((el) => el.className.includes("disabled"));
301
+ });
302
+ }
303
+ expand() {
304
+ return __awaiter(this, void 0, void 0, function* () {
305
+ if (!(yield this.isExpanded())) {
306
+ yield this.getSummary().click();
307
+ }
308
+ });
309
+ }
310
+ collapse() {
311
+ return __awaiter(this, void 0, void 0, function* () {
312
+ if (yield this.isExpanded()) {
313
+ yield this.getSummary().click();
314
+ }
315
+ });
316
+ }
317
+ toggle() {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ yield this.getSummary().click();
320
+ });
321
+ }
322
+ }
323
+ exports.ExpandableItemDriver = ExpandableItemDriver;
324
+ // --- FileInput
325
+ class FileInputDriver extends ComponentDriver {
326
+ getTextBox() {
327
+ return this.component.locator("input[readonly]");
328
+ }
329
+ getHiddenInput() {
330
+ return this.component.locator('input[type="file"]');
331
+ }
332
+ getBrowseButton() {
333
+ return this.component.locator('[class*="_button_"]');
334
+ }
335
+ getContainer() {
336
+ return this.component;
337
+ }
338
+ isEnabled() {
339
+ return __awaiter(this, void 0, void 0, function* () {
340
+ const browseButton = this.getBrowseButton();
341
+ return !(yield browseButton.isDisabled());
342
+ });
343
+ }
344
+ getSelectedFiles() {
345
+ return __awaiter(this, void 0, void 0, function* () {
346
+ const textBox = this.getTextBox();
347
+ const value = yield textBox.inputValue();
348
+ return value || "";
349
+ });
350
+ }
351
+ openFileDialog() {
352
+ return __awaiter(this, void 0, void 0, function* () {
353
+ yield this.getBrowseButton().click();
354
+ });
355
+ }
356
+ getPlaceholder() {
357
+ return __awaiter(this, void 0, void 0, function* () {
358
+ const textBox = this.getTextBox();
359
+ return (yield textBox.getAttribute("placeholder")) || "";
360
+ });
361
+ }
362
+ focusButton() {
363
+ return __awaiter(this, void 0, void 0, function* () {
364
+ yield this.getBrowseButton().focus();
365
+ });
366
+ }
367
+ hasReadOnlyAttribute() {
368
+ return __awaiter(this, void 0, void 0, function* () {
369
+ const textBox = this.getTextBox();
370
+ return (yield textBox.getAttribute("readonly")) !== null;
371
+ });
372
+ }
373
+ getAcceptedFileTypes() {
374
+ return __awaiter(this, void 0, void 0, function* () {
375
+ const hiddenInput = this.getHiddenInput();
376
+ return (yield hiddenInput.getAttribute("accept")) || "";
377
+ });
378
+ }
379
+ isMultiple() {
380
+ return __awaiter(this, void 0, void 0, function* () {
381
+ const hiddenInput = this.getHiddenInput();
382
+ return (yield hiddenInput.getAttribute("multiple")) !== null;
383
+ });
384
+ }
385
+ isDirectory() {
386
+ return __awaiter(this, void 0, void 0, function* () {
387
+ const hiddenInput = this.getHiddenInput();
388
+ return (yield hiddenInput.getAttribute("webkitdirectory")) !== null;
389
+ });
390
+ }
391
+ }
392
+ exports.FileInputDriver = FileInputDriver;
393
+ // --- FileUploadDropZone
394
+ class FileUploadDropZoneDriver extends ComponentDriver {
395
+ getWrapper() {
396
+ return this.component.locator('[class*="_wrapper_"]');
397
+ }
398
+ getHiddenInput() {
399
+ return this.component.locator('input[type="file"]');
400
+ }
401
+ getDropPlaceholder() {
402
+ return this.component.locator('[class*="_dropPlaceholder_"]');
403
+ }
404
+ getDropIcon() {
405
+ return this.getDropPlaceholder().locator("svg");
406
+ }
407
+ isDropPlaceholderVisible() {
408
+ return __awaiter(this, void 0, void 0, function* () {
409
+ return yield this.getDropPlaceholder().isVisible();
410
+ });
411
+ }
412
+ isEnabled() {
413
+ return __awaiter(this, void 0, void 0, function* () {
414
+ const input = this.getHiddenInput();
415
+ const isDisabled = yield input.isDisabled();
416
+ return !isDisabled;
417
+ });
418
+ }
419
+ getDropText() {
420
+ return __awaiter(this, void 0, void 0, function* () {
421
+ return (yield this.getDropPlaceholder().textContent()) || "";
422
+ });
423
+ }
424
+ triggerDragEnter() {
425
+ return __awaiter(this, void 0, void 0, function* () {
426
+ yield this.component.dispatchEvent("dragenter");
427
+ });
428
+ }
429
+ triggerDragLeave() {
430
+ return __awaiter(this, void 0, void 0, function* () {
431
+ yield this.component.dispatchEvent("dragleave");
432
+ });
433
+ }
434
+ triggerDrop() {
435
+ return __awaiter(this, arguments, void 0, function* (files = ["test.txt"]) {
436
+ // Simulate file drop event by creating File objects and using setInputFiles
437
+ const hiddenInput = this.getHiddenInput();
438
+ // Create temporary files for testing
439
+ const fileObjects = files.map((name) => {
440
+ return {
441
+ name,
442
+ mimeType: "text/plain",
443
+ buffer: Buffer.from("test content")
444
+ };
445
+ });
446
+ // Set files on the hidden input
447
+ yield hiddenInput.setInputFiles(fileObjects);
448
+ // Trigger the drop event with a proper structure
449
+ yield this.component.evaluate((element, fileNames) => {
450
+ // Create a proper drop event
451
+ const event = new DragEvent("drop", {
452
+ bubbles: true,
453
+ cancelable: true,
454
+ dataTransfer: new DataTransfer()
455
+ });
456
+ // Add files to dataTransfer if needed for component logic
457
+ fileNames.forEach((fileName) => {
458
+ var _a;
459
+ const file = new File(["test content"], fileName, { type: "text/plain" });
460
+ (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.items.add(file);
461
+ });
462
+ element.dispatchEvent(event);
463
+ }, files);
464
+ });
465
+ }
466
+ triggerPaste() {
467
+ return __awaiter(this, void 0, void 0, function* () {
468
+ yield this.component.dispatchEvent("paste", {
469
+ clipboardData: {
470
+ files: [{ name: "pasted.txt", type: "text/plain", size: 50 }],
471
+ items: [{ kind: "file", getAsFile: () => ({ name: "pasted.txt" }) }],
472
+ },
473
+ });
474
+ });
475
+ }
476
+ hasChildren() {
477
+ return __awaiter(this, void 0, void 0, function* () {
478
+ const childrenCount = yield this.component
479
+ .locator('> *:not(input):not([class*="_dropPlaceholder_"])')
480
+ .count();
481
+ return childrenCount > 0;
482
+ });
483
+ }
484
+ }
485
+ exports.FileUploadDropZoneDriver = FileUploadDropZoneDriver;
486
+ class BackdropDriver extends ComponentDriver {
487
+ getBackdrop() {
488
+ return this.component.locator("> *").first();
489
+ }
490
+ getOverlay() {
491
+ return this.component.locator("> *").nth(1);
492
+ }
493
+ getDefaultBackgroundColor() {
494
+ return "rgb(0, 0, 0)"; // Default backdrop color
495
+ }
496
+ getDefaultOpacity() {
497
+ return "0.1"; // Default backdrop opacity
498
+ }
499
+ }
500
+ exports.BackdropDriver = BackdropDriver;
501
+ class FormDriver extends ComponentDriver {
502
+ mockExternalApi(url, apiOptions) {
503
+ return __awaiter(this, void 0, void 0, function* () {
504
+ const { status = 200, headers = {}, body = {} } = apiOptions;
505
+ yield this.page.route(url, (route) => route.fulfill({ status, headers, body: JSON.stringify(body) }));
506
+ });
507
+ }
508
+ get submitButton() {
509
+ return this.getByPartName("submitButton");
510
+ }
511
+ get cancelButton() {
512
+ return this.getByPartName("cancelButton");
513
+ }
514
+ hasSubmitButton() {
515
+ return __awaiter(this, void 0, void 0, function* () {
516
+ return (yield this.submitButton.count()) > 0;
517
+ });
518
+ }
519
+ submitForm() {
520
+ return __awaiter(this, arguments, void 0, function* (trigger = "click") {
521
+ if (trigger === "keypress") {
522
+ if ((yield this.hasSubmitButton()) && (yield this.submitButton.isEnabled())) {
523
+ yield this.submitButton.focus();
524
+ }
525
+ yield this.locator.locator("input").waitFor();
526
+ const firstInputChild = this.locator.locator("input");
527
+ if ((yield firstInputChild.count()) > 0) {
528
+ yield firstInputChild.first().focus();
529
+ }
530
+ yield this.page.keyboard.press("Enter");
531
+ }
532
+ else if (trigger === "click") {
533
+ yield this.submitButton.click();
534
+ }
535
+ });
536
+ }
537
+ getSubmitRequest() {
538
+ return __awaiter(this, arguments, void 0, function* (endpoint = "/entities", requestMethod = "POST", trigger = "click", timeout = 5000) {
539
+ const requestPromise = this.page.waitForRequest((request) => request.url().includes(endpoint) &&
540
+ request.method().toLowerCase() === requestMethod.toLowerCase(), { timeout });
541
+ yield this.submitForm(trigger);
542
+ return requestPromise;
543
+ });
544
+ }
545
+ getSubmitResponse() {
546
+ return __awaiter(this, arguments, void 0, function* (endpoint = "/entities", responseStatus = 200, timeout = 5000) {
547
+ const responsePromise = this.page.waitForResponse((response) => response.url().includes(endpoint) && response.status() === responseStatus, { timeout });
548
+ return responsePromise;
549
+ });
550
+ }
551
+ /**
552
+ * Gets the validation summary component inside the Form.
553
+ * Uses the 'data-validation-summary' attribute to find the component
554
+ */
555
+ getValidationSummary() {
556
+ return __awaiter(this, void 0, void 0, function* () {
557
+ return this.component.locator("[data-validation-summary='true']");
558
+ });
559
+ }
560
+ /**
561
+ * Gets the validation display components inside the Form.
562
+ * Uses the 'data-validation-display-severity' attribute to find the components.
563
+ * The attribute contains the severity of the validation.
564
+ */
565
+ getValidationDisplays() {
566
+ return __awaiter(this, void 0, void 0, function* () {
567
+ return this.component
568
+ .locator("[data-validation-summary='true']")
569
+ .locator("[data-validation-display-severity]");
570
+ });
571
+ }
572
+ getValidationDisplaysBySeverity(severity) {
573
+ return __awaiter(this, void 0, void 0, function* () {
574
+ return this.component
575
+ .locator("[data-validation-summary='true']")
576
+ .locator(`[data-validation-display-severity="${severity}"]`);
577
+ });
578
+ }
579
+ }
580
+ exports.FormDriver = FormDriver;
581
+ // --- ValidationSummary
582
+ class ValidationSummaryDriver extends ComponentDriver {
583
+ /**
584
+ * Gets the validation display components inside the Form.
585
+ * Uses the 'data-validation-display-severity' attribute to find the components.
586
+ * The attribute contains the severity of the validation.
587
+ */
588
+ getValidationDisplays() {
589
+ return __awaiter(this, void 0, void 0, function* () {
590
+ return this.component
591
+ .locator("[data-validation-summary='true']")
592
+ .locator("[data-validation-display-severity]");
593
+ });
594
+ }
595
+ }
596
+ exports.ValidationSummaryDriver = ValidationSummaryDriver;
597
+ // --- ValidationDisplay
598
+ class ValidationDisplayDriver extends ComponentDriver {
599
+ getSeverity() {
600
+ return __awaiter(this, void 0, void 0, function* () {
601
+ return this.component.getAttribute("data-validation-display-severity");
602
+ });
603
+ }
604
+ getText() {
605
+ return __awaiter(this, void 0, void 0, function* () {
606
+ return this.component.locator("li").textContent();
607
+ });
608
+ }
609
+ }
610
+ exports.ValidationDisplayDriver = ValidationDisplayDriver;
611
+ // --- Markdown
612
+ class MarkdownDriver extends ComponentDriver {
613
+ hasHtmlElement(elements) {
614
+ return __awaiter(this, void 0, void 0, function* () {
615
+ const contents = yield this.component.innerHTML();
616
+ elements = typeof elements === "string" ? [elements] : elements;
617
+ return elements.map((e) => `<${e}`).reduce((acc, curr) => acc && contents.includes(curr), true);
618
+ });
619
+ }
620
+ }
621
+ exports.MarkdownDriver = MarkdownDriver;
622
+ // --- Items
623
+ class ItemsDriver extends ComponentDriver {
624
+ }
625
+ exports.ItemsDriver = ItemsDriver;
626
+ // --- Slider
627
+ class SliderDriver extends ComponentDriver {
628
+ }
629
+ exports.SliderDriver = SliderDriver;
630
+ // --- Range
631
+ class RangeDriver extends ComponentDriver {
632
+ }
633
+ exports.RangeDriver = RangeDriver;
634
+ // --- DatePicker
635
+ class DatePickerDriver extends ComponentDriver {
636
+ toggleDropdownVisibility() {
637
+ return __awaiter(this, void 0, void 0, function* () {
638
+ yield this.component.click();
639
+ });
640
+ }
641
+ pickADay(value) {
642
+ return __awaiter(this, void 0, void 0, function* () {
643
+ yield this.component
644
+ .getByRole("gridcell", { name: value })
645
+ .or(this.page.getByRole("gridcell", { name: value }))
646
+ .first()
647
+ .click({ force: true });
648
+ });
649
+ }
650
+ }
651
+ exports.DatePickerDriver = DatePickerDriver;
652
+ // --- AutoComplete
653
+ class AutoCompleteDriver extends ComponentDriver {
654
+ toggleOptionsVisibility() {
655
+ return __awaiter(this, void 0, void 0, function* () {
656
+ yield this.component.click();
657
+ });
658
+ }
659
+ selectLabel(value) {
660
+ return __awaiter(this, void 0, void 0, function* () {
661
+ yield this.component
662
+ .getByRole("option", { name: value })
663
+ .or(this.page.getByRole("option", { name: value }))
664
+ .first()
665
+ .click({ force: true });
666
+ });
667
+ }
668
+ searchFor(value) {
669
+ return __awaiter(this, void 0, void 0, function* () {
670
+ yield this.page.getByRole("combobox").fill(value);
671
+ });
672
+ }
673
+ chooseIndex(index) {
674
+ return __awaiter(this, void 0, void 0, function* () {
675
+ yield this.locator
676
+ .getByRole("option")
677
+ .nth(index)
678
+ .or(this.page.getByRole("option").nth(index))
679
+ .first()
680
+ .click();
681
+ });
682
+ }
683
+ }
684
+ exports.AutoCompleteDriver = AutoCompleteDriver;
685
+ // --- Select
686
+ class SelectDriver extends ComponentDriver {
687
+ toggleOptionsVisibility() {
688
+ return __awaiter(this, void 0, void 0, function* () {
689
+ yield this.component.click();
690
+ });
691
+ }
692
+ selectLabel(value) {
693
+ return __awaiter(this, void 0, void 0, function* () {
694
+ yield this.component
695
+ .getByRole("option", { name: value })
696
+ .or(this.page.getByRole("option", { name: value }))
697
+ .first()
698
+ .click({ force: true });
699
+ });
700
+ }
701
+ selectFirstLabelPostSearh(label) {
702
+ return __awaiter(this, void 0, void 0, function* () {
703
+ yield this.searchFor(label);
704
+ yield this.chooseIndex(0);
705
+ });
706
+ }
707
+ searchFor(value) {
708
+ return __awaiter(this, void 0, void 0, function* () {
709
+ yield this.page.getByRole("combobox").fill(value);
710
+ });
711
+ }
712
+ chooseIndex(index) {
713
+ return __awaiter(this, void 0, void 0, function* () {
714
+ yield this.locator
715
+ .getByRole("option")
716
+ .nth(index)
717
+ .or(this.page.getByRole("option").nth(index))
718
+ .first()
719
+ .click();
720
+ });
721
+ }
722
+ selectMultipleLabels(values) {
723
+ return __awaiter(this, void 0, void 0, function* () {
724
+ for (const value of values) {
725
+ yield this.component
726
+ .getByRole("option", { name: value })
727
+ .or(this.page.getByRole("option", { name: value }))
728
+ .first()
729
+ .click();
730
+ }
731
+ });
732
+ }
733
+ }
734
+ exports.SelectDriver = SelectDriver;
735
+ // --- RadioGroup
736
+ class RadioGroupDriver extends ComponentDriver {
737
+ }
738
+ exports.RadioGroupDriver = RadioGroupDriver;
739
+ // --- NumberBox
740
+ class NumberBoxDriver extends ComponentDriver {
741
+ get field() {
742
+ return this.component.locator("input");
743
+ }
744
+ get label() {
745
+ return this.component.locator("label");
746
+ }
747
+ get placeholder() {
748
+ return this.field.getAttribute("placeholder");
749
+ }
750
+ get spinnerUpButton() {
751
+ return this.component.locator("button").and(this.component.locator("[data-spinner='up']"));
752
+ }
753
+ get spinnerDownButton() {
754
+ return this.component.locator("button").and(this.component.locator("[data-spinner='down']"));
755
+ }
756
+ }
757
+ exports.NumberBoxDriver = NumberBoxDriver;
758
+ // --- TextBox
759
+ class TextBoxDriver extends InputComponentDriver {
760
+ }
761
+ exports.TextBoxDriver = TextBoxDriver;
762
+ // --- TextArea
763
+ class TextAreaDriver extends InputComponentDriver {
764
+ }
765
+ exports.TextAreaDriver = TextAreaDriver;
766
+ // --- ProgressBar
767
+ class ProgressBarDriver extends ComponentDriver {
768
+ get bar() {
769
+ return this.component.locator("> div");
770
+ }
771
+ getProgressRatio() {
772
+ return __awaiter(this, void 0, void 0, function* () {
773
+ const style = yield this.bar.getAttribute("style");
774
+ if (!style)
775
+ return 0;
776
+ const widthMatch = style.match(/width:\s*(\d+(?:\.\d+)?)%/);
777
+ return widthMatch ? parseFloat(widthMatch[1]) / 100 : 0;
778
+ });
779
+ }
780
+ }
781
+ exports.ProgressBarDriver = ProgressBarDriver;
782
+ // --- List
783
+ class ListDriver extends ComponentDriver {
784
+ /**
785
+ * Gets all list item elements
786
+ */
787
+ get items() {
788
+ return this.component
789
+ .locator("[data-list-item]")
790
+ .or(this.component.locator("div").filter({ hasText: /^(?!.*Loading).*/ }));
791
+ }
792
+ /**
793
+ * Gets the loading spinner element
794
+ */
795
+ get loadingSpinner() {
796
+ return this.component.locator('[class*="loadingWrapper"]');
797
+ }
798
+ /**
799
+ * Checks if the loading state is visible
800
+ */
801
+ isLoading() {
802
+ return __awaiter(this, void 0, void 0, function* () {
803
+ return yield this.loadingSpinner.isVisible().catch(() => false);
804
+ });
805
+ }
806
+ /**
807
+ * Gets group header elements
808
+ */
809
+ get groupHeaders() {
810
+ return this.component
811
+ .locator("[data-group-header]")
812
+ .or(this.component.locator("div").filter({ hasText: /^Category:|^Header:/ }));
813
+ }
814
+ /**
815
+ * Gets group footer elements
816
+ */
817
+ get groupFooters() {
818
+ return this.component
819
+ .locator("[data-group-footer]")
820
+ .or(this.component.locator("div").filter({ hasText: /^End of/ }));
821
+ }
822
+ /**
823
+ * Gets the empty state element
824
+ */
825
+ get emptyState() {
826
+ return this.component
827
+ .locator("[data-empty-state]")
828
+ .or(this.component.getByText("No items found!"));
829
+ }
830
+ /**
831
+ * Scrolls the list to a specific position
832
+ */
833
+ scrollTo(position) {
834
+ return __awaiter(this, void 0, void 0, function* () {
835
+ if (position === "top") {
836
+ yield this.component.evaluate((el) => el.scrollTo({ top: 0 }));
837
+ }
838
+ else if (position === "bottom") {
839
+ yield this.component.evaluate((el) => el.scrollTo({ top: el.scrollHeight }));
840
+ }
841
+ else {
842
+ yield this.component.evaluate((el, pos) => el.scrollTo({ top: pos }), position);
843
+ }
844
+ });
845
+ }
846
+ /**
847
+ * Gets the number of visible items (for virtualization testing)
848
+ */
849
+ getVisibleItemCount() {
850
+ return __awaiter(this, void 0, void 0, function* () {
851
+ return yield this.items.count();
852
+ });
853
+ }
854
+ /**
855
+ * Gets item at specific index
856
+ */
857
+ getItemAt(index) {
858
+ return this.items.nth(index);
859
+ }
860
+ /**
861
+ * Gets item by text content
862
+ */
863
+ getItemByText(text) {
864
+ return this.component.getByText(text);
865
+ }
866
+ /**
867
+ * Checks if list is empty
868
+ */
869
+ isEmpty() {
870
+ return __awaiter(this, void 0, void 0, function* () {
871
+ // Check for the actual "No data available" text that appears when list is empty
872
+ const noDataText = yield this.component.textContent();
873
+ const hasNoDataMessage = (noDataText === null || noDataText === void 0 ? void 0 : noDataText.includes("No data available")) || (noDataText === null || noDataText === void 0 ? void 0 : noDataText.includes("No items found"));
874
+ // Also check if there are any actual data items
875
+ const itemCount = yield this.items.count();
876
+ const hasDataItems = itemCount > 0 && !hasNoDataMessage;
877
+ return hasNoDataMessage || !hasDataItems;
878
+ });
879
+ }
880
+ /**
881
+ * Gets all text content from visible items
882
+ */
883
+ getVisibleItemTexts() {
884
+ return __awaiter(this, void 0, void 0, function* () {
885
+ const items = yield this.items.all();
886
+ const texts = yield Promise.all(items.map((item) => item.textContent()));
887
+ return texts.filter((text) => text !== null);
888
+ });
889
+ }
890
+ }
891
+ exports.ListDriver = ListDriver;
892
+ // --- Text
893
+ class TextDriver extends ComponentDriver {
894
+ }
895
+ exports.TextDriver = TextDriver;
896
+ // --- Heading
897
+ class HeadingDriver extends ComponentDriver {
898
+ }
899
+ exports.HeadingDriver = HeadingDriver;
900
+ // --- Icon
901
+ class IconDriver extends ComponentDriver {
902
+ get svgIcon() {
903
+ return this.component.locator("svg");
904
+ }
905
+ }
906
+ exports.IconDriver = IconDriver;
907
+ // --- Stack
908
+ class StackDriver extends ComponentDriver {
909
+ }
910
+ exports.StackDriver = StackDriver;
911
+ // --- HStack
912
+ class HStackDriver extends StackDriver {
913
+ }
914
+ exports.HStackDriver = HStackDriver;
915
+ // --- VStack
916
+ class VStackDriver extends StackDriver {
917
+ }
918
+ exports.VStackDriver = VStackDriver;
919
+ // --- Link
920
+ class LinkDriver extends ComponentDriver {
921
+ }
922
+ exports.LinkDriver = LinkDriver;
923
+ // --- NavLink
924
+ class NavLinkDriver extends ComponentDriver {
925
+ }
926
+ exports.NavLinkDriver = NavLinkDriver;
927
+ // --- NavGroup
928
+ class NavGroupDriver extends ComponentDriver {
929
+ getIcons() {
930
+ return this.locator.locator("> svg").or(this.locator.locator("> img"));
931
+ }
932
+ }
933
+ exports.NavGroupDriver = NavGroupDriver;
934
+ // --- NavPanel
935
+ class NavPanelDriver extends ComponentDriver {
936
+ }
937
+ exports.NavPanelDriver = NavPanelDriver;
938
+ // --- Card
939
+ class CardDriver extends ComponentDriver {
940
+ get avatar() {
941
+ return this.component.getByRole("img", { name: "avatar" });
942
+ }
943
+ }
944
+ exports.CardDriver = CardDriver;
945
+ // --- Accordion
946
+ class AccordionDriver extends ComponentDriver {
947
+ }
948
+ exports.AccordionDriver = AccordionDriver;
949
+ // --- AppHeader
950
+ class AppHeaderDriver extends ComponentDriver {
951
+ }
952
+ exports.AppHeaderDriver = AppHeaderDriver;
953
+ // --- AppFooter
954
+ class AppFooterDriver extends ComponentDriver {
955
+ }
956
+ exports.AppFooterDriver = AppFooterDriver;
957
+ // --- Badge
958
+ class BadgeDriver extends ComponentDriver {
959
+ }
960
+ exports.BadgeDriver = BadgeDriver;
961
+ // --- NoResult
962
+ class NoResultDriver extends ComponentDriver {
963
+ }
964
+ exports.NoResultDriver = NoResultDriver;
965
+ // --- Option
966
+ class OptionDriver extends ComponentDriver {
967
+ }
968
+ exports.OptionDriver = OptionDriver;
969
+ // --- FormItem
970
+ // NOTE (NEW): FormItem will be removed, delete this Driver
971
+ // NOTE: Do not delete these comments.
972
+ // This is an untested proposal to shorten code length.
973
+ // Now, you have to provide the .input element for a specific control driver:
974
+ //
975
+ // element = FormItemDriver().input -> TextBoxDriver(element)
976
+ //
977
+ // This can be shortened to FormItemDriver().input.as("TextBoxDriver") if we extend
978
+ // the locator object only for the return type of the "input" getter to support the "as" method
979
+ //
980
+ /* type DriverMap = {
981
+ TextBoxDriver: TextBoxDriver;
982
+ NumberBoxDriver: NumberBoxDriver;
983
+ };
984
+
985
+ const driverConstructors: {
986
+ [K in keyof DriverMap]: new (obj: ComponentDriverParams) => DriverMap[K]
987
+ } = {
988
+ TextBoxDriver,
989
+ NumberBoxDriver
990
+ };
991
+
992
+ export interface ExtendedLocator extends Locator {
993
+ as?: <K extends keyof DriverMap>(type: K) => DriverMap[K];
994
+ }
995
+
996
+ export const extendLocator = (
997
+ locator: Locator,
998
+ ): ExtendedLocator => ({
999
+ ...locator,
1000
+ locator: (selector, options) =>
1001
+ extendLocator(locator.locator(selector, options)),
1002
+ as: (type) => { return new driverConstructors[type]({ locator, page: locator.page() }); }
1003
+ }); */
1004
+ class FormItemDriver extends ComponentDriver {
1005
+ get input() {
1006
+ return this.component.locator(">input").or(this.component).first();
1007
+ }
1008
+ get textBox() {
1009
+ return this.input.getByRole("textbox");
1010
+ }
1011
+ get checkbox() {
1012
+ return this.input.getByRole("checkbox");
1013
+ }
1014
+ get label() {
1015
+ return this.component.locator("label");
1016
+ }
1017
+ get validationStatusTag() {
1018
+ return "data-validation-status";
1019
+ }
1020
+ getValidationStatusIndicator() {
1021
+ return __awaiter(this, void 0, void 0, function* () {
1022
+ return this.component.locator(`[${this.validationStatusTag}]`);
1023
+ });
1024
+ }
1025
+ }
1026
+ exports.FormItemDriver = FormItemDriver;
1027
+ // --- htmlTags
1028
+ class HtmlTagDriver extends ComponentDriver {
1029
+ }
1030
+ exports.HtmlTagDriver = HtmlTagDriver;
1031
+ // --- CodeBlock
1032
+ class CodeBlockDriver extends ComponentDriver {
1033
+ getHeader() {
1034
+ return this.component.locator('[class*="codeBlockHeader"]');
1035
+ }
1036
+ getContent() {
1037
+ return this.component.locator('[class*="codeBlockContent"]');
1038
+ }
1039
+ getCopyButton() {
1040
+ return this.component.locator('[class*="codeBlockCopyButton"] button');
1041
+ }
1042
+ getFilename() {
1043
+ return this.getHeader().locator("span");
1044
+ }
1045
+ isCopyButtonVisible() {
1046
+ return __awaiter(this, void 0, void 0, function* () {
1047
+ return yield this.getCopyButton().isVisible();
1048
+ });
1049
+ }
1050
+ hasHeader() {
1051
+ return __awaiter(this, void 0, void 0, function* () {
1052
+ return yield this.getHeader().isVisible();
1053
+ });
1054
+ }
1055
+ getCodeText() {
1056
+ return __awaiter(this, void 0, void 0, function* () {
1057
+ return yield this.getContent().textContent();
1058
+ });
1059
+ }
1060
+ clickCopyButton() {
1061
+ return __awaiter(this, void 0, void 0, function* () {
1062
+ yield this.getCopyButton().click();
1063
+ });
1064
+ }
1065
+ hoverContent() {
1066
+ return __awaiter(this, void 0, void 0, function* () {
1067
+ yield this.getContent().hover();
1068
+ });
1069
+ }
1070
+ }
1071
+ exports.CodeBlockDriver = CodeBlockDriver;
1072
+ // --- Checkbox
1073
+ class CheckboxDriver extends InputComponentDriver {
1074
+ getIndicatorColor() {
1075
+ return __awaiter(this, void 0, void 0, function* () {
1076
+ const specifier = this.component.getByRole("checkbox").or(this.component).last();
1077
+ const { boxShadow } = yield (0, component_test_helpers_1.getPseudoStyles)(specifier, "::before", "box-shadow");
1078
+ const colorMatch = boxShadow.match(/(rgba?\([^)]+\)|hsla?\([^)]+\)|#[a-fA-F0-9]{3,8})/);
1079
+ return colorMatch ? colorMatch[1] : null;
1080
+ });
1081
+ }
1082
+ }
1083
+ exports.CheckboxDriver = CheckboxDriver;
1084
+ // --- Label
1085
+ class LabelDriver extends ComponentDriver {
1086
+ }
1087
+ exports.LabelDriver = LabelDriver;
1088
+ // --- Spinner
1089
+ class SpinnerDriver extends ComponentDriver {
1090
+ /**
1091
+ * Gets the main spinner element (the one with the ring animation)
1092
+ */
1093
+ get spinnerElement() {
1094
+ // Filter for spinner elements and use the first one by default
1095
+ return this.page
1096
+ .locator('[data-testid="test-id-component"]')
1097
+ .filter({ has: this.page.locator("div") })
1098
+ .first();
1099
+ }
1100
+ /**
1101
+ * Gets a specific spinner element by index (for multiple spinners)
1102
+ */
1103
+ getSpinnerByIndex(index) {
1104
+ return this.page
1105
+ .locator('[data-testid="test-id-component"]')
1106
+ .filter({ has: this.page.locator("div") })
1107
+ .nth(index);
1108
+ }
1109
+ /**
1110
+ * Gets the fullscreen wrapper element (only exists when fullScreen=true)
1111
+ */
1112
+ get fullScreenWrapper() {
1113
+ return this.page.locator('div[class*="_fullScreenSpinnerWrapper_"]');
1114
+ }
1115
+ /**
1116
+ * Checks if the spinner is in fullscreen mode
1117
+ */
1118
+ isFullScreen() {
1119
+ return __awaiter(this, void 0, void 0, function* () {
1120
+ try {
1121
+ const wrapper = this.fullScreenWrapper;
1122
+ return yield wrapper.isVisible();
1123
+ }
1124
+ catch (_a) {
1125
+ return false;
1126
+ }
1127
+ });
1128
+ }
1129
+ /**
1130
+ * Gets the computed style of the spinner element
1131
+ */
1132
+ getSpinnerStyle() {
1133
+ return __awaiter(this, void 0, void 0, function* () {
1134
+ const element = this.spinnerElement;
1135
+ return yield element.evaluate((el) => {
1136
+ const styles = window.getComputedStyle(el);
1137
+ return {
1138
+ display: styles.display,
1139
+ position: styles.position,
1140
+ width: styles.width,
1141
+ height: styles.height,
1142
+ animationDuration: styles.animationDuration,
1143
+ className: el.className,
1144
+ };
1145
+ });
1146
+ });
1147
+ }
1148
+ /**
1149
+ * Gets the animation duration from the child elements (where the actual animation occurs)
1150
+ */
1151
+ getAnimationDuration() {
1152
+ return __awaiter(this, void 0, void 0, function* () {
1153
+ const element = this.spinnerElement;
1154
+ return yield element.evaluate((el) => {
1155
+ // Check the first child div for animation duration
1156
+ const firstChild = el.querySelector("div");
1157
+ if (firstChild) {
1158
+ const styles = window.getComputedStyle(firstChild);
1159
+ return styles.animationDuration;
1160
+ }
1161
+ return "0s";
1162
+ });
1163
+ });
1164
+ }
1165
+ /**
1166
+ * Waits for the spinner to appear
1167
+ */
1168
+ waitForSpinner() {
1169
+ return __awaiter(this, arguments, void 0, function* (timeout = 5000) {
1170
+ yield this.spinnerElement.waitFor({ state: "visible", timeout });
1171
+ });
1172
+ }
1173
+ /**
1174
+ * Waits for the spinner to disappear
1175
+ */
1176
+ waitForSpinnerToDisappear() {
1177
+ return __awaiter(this, arguments, void 0, function* (timeout = 5000) {
1178
+ yield this.spinnerElement.waitFor({ state: "hidden", timeout });
1179
+ });
1180
+ }
1181
+ /**
1182
+ * Checks if the spinner is visible
1183
+ */
1184
+ isVisible() {
1185
+ return __awaiter(this, void 0, void 0, function* () {
1186
+ return yield this.spinnerElement.isVisible();
1187
+ });
1188
+ }
1189
+ /**
1190
+ * Gets the CSS class name to verify CSS modules are working
1191
+ */
1192
+ getClassName() {
1193
+ return __awaiter(this, void 0, void 0, function* () {
1194
+ return (yield this.spinnerElement.getAttribute("class")) || "";
1195
+ });
1196
+ }
1197
+ /**
1198
+ * Gets the number of child div elements (should be 4 for the ring animation)
1199
+ */
1200
+ getChildCount() {
1201
+ return __awaiter(this, void 0, void 0, function* () {
1202
+ return yield this.spinnerElement.evaluate((el) => {
1203
+ return el.querySelectorAll("div").length;
1204
+ });
1205
+ });
1206
+ }
1207
+ /**
1208
+ * Gets the total number of spinner components on the page
1209
+ */
1210
+ getSpinnerCount() {
1211
+ return __awaiter(this, void 0, void 0, function* () {
1212
+ return yield this.page.locator('[data-testid="test-id-component"]').count();
1213
+ });
1214
+ }
1215
+ /**
1216
+ * Gets a spinner by specific test ID
1217
+ */
1218
+ getSpinnerByTestId(testId) {
1219
+ return this.page.locator(`[data-testid="${testId}"]`);
1220
+ }
1221
+ /**
1222
+ * Checks if fullscreen mode has the correct wrapper structure
1223
+ */
1224
+ getFullScreenWrapperInfo() {
1225
+ return __awaiter(this, void 0, void 0, function* () {
1226
+ const wrapper = this.fullScreenWrapper;
1227
+ if (!(yield wrapper.isVisible())) {
1228
+ return null;
1229
+ }
1230
+ return yield wrapper.evaluate((el) => {
1231
+ const parent = el.parentElement;
1232
+ const styles = window.getComputedStyle(el);
1233
+ return {
1234
+ position: styles.position,
1235
+ inset: styles.inset,
1236
+ parentClassName: (parent === null || parent === void 0 ? void 0 : parent.className) || "",
1237
+ hasSpinnerChild: !!el.querySelector('[class*="_lds-ring_"]'),
1238
+ };
1239
+ });
1240
+ });
1241
+ }
1242
+ }
1243
+ exports.SpinnerDriver = SpinnerDriver;
1244
+ // --- DropdownMenu
1245
+ class DropdownMenuDriver extends ComponentDriver {
1246
+ /**
1247
+ * Get the trigger button element
1248
+ * For DropdownMenu, we'll look for the button on the page level since Radix UI may render it separately
1249
+ */
1250
+ getTrigger() {
1251
+ return this.page.getByRole("button").first();
1252
+ }
1253
+ /**
1254
+ * Open the dropdown menu
1255
+ */
1256
+ open() {
1257
+ return __awaiter(this, void 0, void 0, function* () {
1258
+ const trigger = this.getTrigger();
1259
+ yield trigger.click();
1260
+ });
1261
+ }
1262
+ /**
1263
+ * Close the dropdown menu by clicking outside
1264
+ */
1265
+ close() {
1266
+ return __awaiter(this, void 0, void 0, function* () {
1267
+ // Try clicking on the trigger first to close, then fall back to clicking outside
1268
+ try {
1269
+ yield this.page.keyboard.press("Escape");
1270
+ }
1271
+ catch (_a) {
1272
+ // If escape doesn't work, try clicking on a safe area
1273
+ yield this.page.click("html");
1274
+ }
1275
+ });
1276
+ }
1277
+ /**
1278
+ * Get all menu items
1279
+ */
1280
+ getMenuItems() {
1281
+ return this.page.getByRole("menuitem");
1282
+ }
1283
+ /**
1284
+ * Get a specific menu item by text
1285
+ */
1286
+ getMenuItem(text) {
1287
+ return this.page.getByRole("menuitem", { name: text });
1288
+ }
1289
+ /**
1290
+ * Click a menu item by text
1291
+ */
1292
+ clickMenuItem(text) {
1293
+ return __awaiter(this, void 0, void 0, function* () {
1294
+ yield this.getMenuItem(text).click();
1295
+ });
1296
+ }
1297
+ /**
1298
+ * Get submenu items
1299
+ */
1300
+ getSubMenuItems(parentText) {
1301
+ // First hover over the parent submenu to open it
1302
+ return this.page.getByText(parentText);
1303
+ }
1304
+ /**
1305
+ * Open a submenu by hovering over it
1306
+ */
1307
+ openSubMenu(submenuText) {
1308
+ return __awaiter(this, void 0, void 0, function* () {
1309
+ yield this.page.getByText(submenuText).hover();
1310
+ });
1311
+ }
1312
+ /**
1313
+ * Get menu separators
1314
+ */
1315
+ getMenuSeparators() {
1316
+ return this.page.locator('[class*="DropdownMenuSeparator"]');
1317
+ }
1318
+ /**
1319
+ * Get the menu content container
1320
+ */
1321
+ getMenuContent() {
1322
+ return this.page.locator('[class*="DropdownMenuContent"]');
1323
+ }
1324
+ /**
1325
+ * Check if the menu is open
1326
+ */
1327
+ isOpen() {
1328
+ return __awaiter(this, void 0, void 0, function* () {
1329
+ try {
1330
+ const content = this.getMenuContent();
1331
+ return yield content.isVisible();
1332
+ }
1333
+ catch (_a) {
1334
+ return false;
1335
+ }
1336
+ });
1337
+ }
1338
+ /**
1339
+ * Wait for menu to open
1340
+ */
1341
+ waitForOpen() {
1342
+ return __awaiter(this, void 0, void 0, function* () {
1343
+ yield this.getMenuContent().waitFor({ state: "visible" });
1344
+ });
1345
+ }
1346
+ /**
1347
+ * Wait for menu to close
1348
+ */
1349
+ waitForClose() {
1350
+ return __awaiter(this, void 0, void 0, function* () {
1351
+ yield this.getMenuContent().waitFor({ state: "hidden" });
1352
+ });
1353
+ }
1354
+ }
1355
+ exports.DropdownMenuDriver = DropdownMenuDriver;