xmlui 0.10.13 → 0.10.15

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 (217) hide show
  1. package/dist/lib/{index-Db5iQkFp.mjs → index-axjeT2uJ.mjs} +1626 -1080
  2. package/dist/lib/index.css +1 -1
  3. package/dist/lib/{initMock-B9LtmFJG.mjs → initMock-BoTWMs19.mjs} +1 -1
  4. package/dist/lib/language-server-web-worker.mjs +1 -1
  5. package/dist/lib/language-server.mjs +1 -1
  6. package/dist/lib/{metadata-utils-D90qqMGc.mjs → metadata-utils-CtY0QcvH.mjs} +2 -1
  7. package/dist/lib/{server-common-lmBDLpUh.mjs → server-common-Cine5nRR.mjs} +1 -1
  8. package/dist/lib/xmlui.d.ts +99 -6
  9. package/dist/lib/xmlui.mjs +78 -42
  10. package/dist/metadata/{collectedComponentMetadata-BN8eg9Gr.mjs → collectedComponentMetadata-CQywuPDB.mjs} +17448 -16984
  11. package/dist/metadata/{initMock-J7pN8owj.mjs → initMock-Bi5kF5Af.mjs} +1 -1
  12. package/dist/metadata/style.css +1 -1
  13. package/dist/metadata/xmlui-metadata.mjs +1 -1
  14. package/dist/metadata/xmlui-metadata.umd.js +3 -3
  15. package/dist/scripts/bin/build-lib.js +21 -13
  16. package/dist/scripts/bin/viteConfig.js +3 -1
  17. package/dist/scripts/package.json +2 -3
  18. package/dist/scripts/src/abstractions/scripting/Token.js +2 -0
  19. package/dist/scripts/src/abstractions/scripting/TryScope.js +2 -0
  20. package/dist/scripts/src/abstractions/scripting/modules.js +2 -0
  21. package/dist/scripts/src/components/APICall/APICall.spec.js +910 -0
  22. package/dist/scripts/src/components/Accordion/Accordion.spec.js +969 -0
  23. package/dist/scripts/src/components/Animation/Animation.js +50 -0
  24. package/dist/scripts/src/components/App/App.spec.js +219 -0
  25. package/dist/scripts/src/components/AppHeader/AppHeader.spec.js +169 -0
  26. package/dist/scripts/src/components/AppState/AppState.js +32 -2
  27. package/dist/scripts/src/components/AppState/AppState.spec.js +268 -0
  28. package/dist/scripts/src/components/AppState/AppStateNative.js +27 -3
  29. package/dist/scripts/src/components/AutoComplete/AutoComplete.spec.js +383 -0
  30. package/dist/scripts/src/components/Avatar/Avatar.spec.js +1543 -0
  31. package/dist/scripts/src/components/Backdrop/Backdrop.spec.js +131 -0
  32. package/dist/scripts/src/components/Badge/Badge.spec.js +2214 -0
  33. package/dist/scripts/src/components/Bookmark/Bookmark.spec.js +230 -0
  34. package/dist/scripts/src/components/Breakout/Breakout.spec.js +56 -0
  35. package/dist/scripts/src/components/Button/Button-style.spec.js +274 -0
  36. package/dist/scripts/src/components/Button/Button.js +5 -1
  37. package/dist/scripts/src/components/Button/Button.spec.js +454 -0
  38. package/dist/scripts/src/components/Card/Card.spec.js +150 -0
  39. package/dist/scripts/src/components/Carousel/Carousel.spec.js +343 -0
  40. package/dist/scripts/src/components/Carousel/CarouselNative.js +2 -2
  41. package/dist/scripts/src/components/ChangeListener/ChangeListener.spec.js +169 -0
  42. package/dist/scripts/src/components/Charts/AreaChart/AreaChart.spec.js +999 -0
  43. package/dist/scripts/src/components/Charts/BarChart/BarChart.spec.js +597 -0
  44. package/dist/scripts/src/components/Charts/DonutChart/DonutChart.spec.js +608 -0
  45. package/dist/scripts/src/components/Charts/LabelList/LabelList.spec.js +539 -0
  46. package/dist/scripts/src/components/Charts/Legend/Legend.spec.js +558 -0
  47. package/dist/scripts/src/components/Charts/LineChart/LineChart.spec.js +450 -0
  48. package/dist/scripts/src/components/Charts/PieChart/PieChart.spec.js +584 -0
  49. package/dist/scripts/src/components/Charts/PieChart/PieChartNative.js +41 -2
  50. package/dist/scripts/src/components/Charts/RadarChart/RadarChart.spec.js +571 -0
  51. package/dist/scripts/src/components/Charts/Tooltip/TooltipContent.spec.js +449 -0
  52. package/dist/scripts/src/components/Checkbox/Checkbox.spec.js +964 -0
  53. package/dist/scripts/src/components/CodeBlock/CodeBlock.spec.js +196 -0
  54. package/dist/scripts/src/components/ColorPicker/ColorPicker.spec.js +283 -0
  55. package/dist/scripts/src/components/ColorPicker/ColorPickerNative.js +9 -26
  56. package/dist/scripts/src/components/Column/doc-resources/list-component-data.js +53 -0
  57. package/dist/scripts/src/components/ComponentProvider.js +6 -2
  58. package/dist/scripts/src/components/ContentSeparator/ContentSeparator.spec.js +338 -0
  59. package/dist/scripts/src/components/DateInput/DateInput.spec.js +918 -0
  60. package/dist/scripts/src/components/DatePicker/DatePicker.spec.js +362 -0
  61. package/dist/scripts/src/components/DatePicker/DatePickerNative.js +3 -3
  62. package/dist/scripts/src/components/DropdownMenu/DropdownMenu.spec.js +331 -0
  63. package/dist/scripts/src/components/DropdownMenu/DropdownMenuNative.js +7 -9
  64. package/dist/scripts/src/components/EmojiSelector/EmojiSelector.spec.js +29 -0
  65. package/dist/scripts/src/components/ExpandableItem/ExpandableItem.spec.js +435 -0
  66. package/dist/scripts/src/components/FileInput/FileInput.spec.js +249 -0
  67. package/dist/scripts/src/components/FileUploadDropZone/FileUploadDropZone.spec.js +296 -0
  68. package/dist/scripts/src/components/FlowLayout/FlowLayout.spec.js +518 -0
  69. package/dist/scripts/src/components/Footer/Footer.spec.js +991 -0
  70. package/dist/scripts/src/components/Form/Form.spec.js +1257 -0
  71. package/dist/scripts/src/components/FormItem/FormItem.spec.js +723 -0
  72. package/dist/scripts/src/components/FormItem/ItemWithLabel.js +3 -3
  73. package/dist/scripts/src/components/FormSection/FormSection.js +6 -31
  74. package/dist/scripts/src/components/Fragment/Fragment.spec.js +50 -0
  75. package/dist/scripts/src/components/Heading/H1.spec.js +66 -0
  76. package/dist/scripts/src/components/Heading/H2.spec.js +66 -0
  77. package/dist/scripts/src/components/Heading/H3.spec.js +66 -0
  78. package/dist/scripts/src/components/Heading/H4.spec.js +66 -0
  79. package/dist/scripts/src/components/Heading/H5.spec.js +66 -0
  80. package/dist/scripts/src/components/Heading/H6.spec.js +66 -0
  81. package/dist/scripts/src/components/Heading/Heading.spec.js +897 -0
  82. package/dist/scripts/src/components/HtmlTags/HtmlTags.spec.js +69 -0
  83. package/dist/scripts/src/components/IFrame/IFrame.spec.js +527 -0
  84. package/dist/scripts/src/components/Icon/ArrowDropDown.js +11 -0
  85. package/dist/scripts/src/components/Icon/ArrowDropUp.js +11 -0
  86. package/dist/scripts/src/components/Icon/ArrowLeft.js +11 -0
  87. package/dist/scripts/src/components/Icon/ArrowRight.js +11 -0
  88. package/dist/scripts/src/components/Icon/ChevronDownIcon.js +7 -0
  89. package/dist/scripts/src/components/Icon/ChevronUpIcon.js +7 -0
  90. package/dist/scripts/src/components/Icon/Icon.spec.js +527 -0
  91. package/dist/scripts/src/components/Icon/SunIcon.js +10 -0
  92. package/dist/scripts/src/components/Image/Image.js +2 -1
  93. package/dist/scripts/src/components/Image/Image.spec.js +198 -0
  94. package/dist/scripts/src/components/Image/ImageNative.js +30 -2
  95. package/dist/scripts/src/components/Input/InputLabel.js +25 -0
  96. package/dist/scripts/src/components/Input/index.js +5 -0
  97. package/dist/scripts/src/components/Items/Items.spec.js +397 -0
  98. package/dist/scripts/src/components/Link/Link.spec.js +894 -0
  99. package/dist/scripts/src/components/List/List.spec.js +927 -0
  100. package/dist/scripts/src/components/List/doc-resources/list-component-data.js +53 -0
  101. package/dist/scripts/src/components/Markdown/Markdown.spec.js +188 -0
  102. package/dist/scripts/src/components/ModalDialog/ModalDialog.spec.js +162 -0
  103. package/dist/scripts/src/components/NavGroup/NavGroup.spec.js +212 -0
  104. package/dist/scripts/src/components/NavGroup/NavGroupNative.js +15 -7
  105. package/dist/scripts/src/components/NavLink/NavLink.spec.js +864 -0
  106. package/dist/scripts/src/components/NavPanel/NavPanel.spec.js +864 -0
  107. package/dist/scripts/src/components/NoResult/NoResult.spec.js +863 -0
  108. package/dist/scripts/src/components/NumberBox/NumberBox.spec.js +1237 -0
  109. package/dist/scripts/src/components/Option/Option.spec.js +472 -0
  110. package/dist/scripts/src/components/PageMetaTitle/PageMetaTitle.spec.js +80 -0
  111. package/dist/scripts/src/components/Pagination/Pagination.spec.js +1003 -0
  112. package/dist/scripts/src/components/ProfileMenu/ProfileMenu.js +20 -0
  113. package/dist/scripts/src/components/ProgressBar/ProgressBar.spec.js +166 -0
  114. package/dist/scripts/src/components/Queue/Queue.spec.js +626 -0
  115. package/dist/scripts/src/components/RadioGroup/RadioGroup.spec.js +479 -0
  116. package/dist/scripts/src/components/Redirect/Redirect.spec.js +527 -0
  117. package/dist/scripts/src/components/ResponsiveBar/ResponsiveBar.spec.js +76 -0
  118. package/dist/scripts/src/components/Select/Select.spec.js +527 -0
  119. package/dist/scripts/src/components/SelectionStore/SelectionStoreNative.js +3 -1
  120. package/dist/scripts/src/components/Slider/Slider.js +2 -0
  121. package/dist/scripts/src/components/Slider/Slider.spec.js +574 -0
  122. package/dist/scripts/src/components/Slider/SliderNative.js +63 -26
  123. package/dist/scripts/src/components/Slot/Slot.spec.js +368 -0
  124. package/dist/scripts/src/components/SpaceFiller/SpaceFiller.spec.js +184 -0
  125. package/dist/scripts/src/components/Spinner/Spinner.spec.js +161 -0
  126. package/dist/scripts/src/components/Splitter/HSplitter.spec.js +104 -0
  127. package/dist/scripts/src/components/Splitter/Splitter.spec.js +543 -0
  128. package/dist/scripts/src/components/Splitter/VSplitter.spec.js +104 -0
  129. package/dist/scripts/src/components/Stack/CHStack.spec.js +86 -0
  130. package/dist/scripts/src/components/Stack/CVStack.spec.js +86 -0
  131. package/dist/scripts/src/components/Stack/HStack.spec.js +67 -0
  132. package/dist/scripts/src/components/Stack/Stack.spec.js +654 -0
  133. package/dist/scripts/src/components/Stack/VStack.spec.js +67 -0
  134. package/dist/scripts/src/components/Switch/Switch.spec.js +829 -0
  135. package/dist/scripts/src/components/Table/Table.js +7 -1
  136. package/dist/scripts/src/components/Table/Table.spec.js +555 -0
  137. package/dist/scripts/src/components/Table/TableNative.js +4 -1
  138. package/dist/scripts/src/components/Table/doc-resources/list-component-data.js +53 -0
  139. package/dist/scripts/src/components/Table/useRowSelection.js +215 -1
  140. package/dist/scripts/src/components/TableOfContents/TableOfContents.spec.js +838 -0
  141. package/dist/scripts/src/components/Tabs/Tabs.spec.js +875 -0
  142. package/dist/scripts/src/components/Text/Text.spec.js +1075 -0
  143. package/dist/scripts/src/components/TextArea/TextArea.spec.js +714 -0
  144. package/dist/scripts/src/components/TextBox/TextBox.js +1 -5
  145. package/dist/scripts/src/components/TextBox/TextBox.spec.js +687 -0
  146. package/dist/scripts/src/components/TextBox/TextBoxNative.js +10 -15
  147. package/dist/scripts/src/components/Theme/Theme.spec.js +124 -0
  148. package/dist/scripts/src/components/Theme/ThemeNative.js +2 -6
  149. package/dist/scripts/src/components/TimeInput/TimeInput.js +1 -5
  150. package/dist/scripts/src/components/TimeInput/TimeInput.spec.js +1122 -0
  151. package/dist/scripts/src/components/TimeInput/TimeInputNative.js +2 -9
  152. package/dist/scripts/src/components/Timer/Timer.spec.js +358 -0
  153. package/dist/scripts/src/components/ToneChangerButton/ToneChangerButton.spec.js +414 -0
  154. package/dist/scripts/src/components/ToneSwitch/ToneSwitch.spec.js +89 -0
  155. package/dist/scripts/src/components/Tooltip/Tooltip.spec.js +418 -0
  156. package/dist/scripts/src/components/chart-color-schemes.js +43 -0
  157. package/dist/scripts/src/components-core/ApiBoundComponent.js +38 -24
  158. package/dist/scripts/src/components-core/CompoundComponent.js +1 -1
  159. package/dist/scripts/src/components-core/RestApiProxy.js +84 -8
  160. package/dist/scripts/src/components-core/behaviors/BehaviorContext.js +54 -0
  161. package/dist/scripts/src/components-core/behaviors/CoreBehaviors.js +80 -0
  162. package/dist/scripts/src/components-core/descriptorHelper.js +1 -0
  163. package/dist/scripts/src/components-core/devtools/InspectorDialogVisibilityContext.js +8 -0
  164. package/dist/scripts/src/components-core/parts.js +4 -1
  165. package/dist/scripts/src/components-core/renderers.js +31 -0
  166. package/dist/scripts/src/components-core/rendering/AppRoot.js +2 -1
  167. package/dist/scripts/src/components-core/rendering/ComponentAdapter.js +31 -46
  168. package/dist/scripts/src/components-core/rendering/nodeUtils.js +6 -0
  169. package/dist/scripts/src/components-core/script-runner/simplify-expression.js +386 -0
  170. package/dist/scripts/src/components-core/theming/component-layout-resolver.js +153 -0
  171. package/dist/scripts/src/components-core/theming/layout-resolver.js +2 -0
  172. package/dist/scripts/src/components-core/theming/parse-layout-props.js +98 -0
  173. package/dist/scripts/src/components-core/theming/themes/solid.js +16 -0
  174. package/dist/scripts/src/components-core/utils/audio-utils.js +83 -0
  175. package/dist/scripts/src/index-standalone.js +61 -0
  176. package/dist/scripts/src/index.js +39 -1
  177. package/dist/scripts/src/language-server/server-common.js +151 -0
  178. package/dist/scripts/src/language-server/server-web-worker.js +47 -0
  179. package/dist/scripts/src/language-server/server.js +42 -0
  180. package/dist/scripts/src/language-server/services/common/docs-generation.js +73 -0
  181. package/dist/scripts/src/language-server/services/common/lsp-utils.js +9 -0
  182. package/dist/scripts/src/language-server/services/common/syntax-node-utilities.js +135 -0
  183. package/dist/scripts/src/language-server/services/completion.js +270 -0
  184. package/dist/scripts/src/language-server/services/diagnostic.js +19 -0
  185. package/dist/scripts/src/language-server/services/format.js +430 -0
  186. package/dist/scripts/src/language-server/services/hover.js +164 -0
  187. package/dist/scripts/src/language-server/xmlui-metadata-generated.mjs +16266 -0
  188. package/dist/scripts/src/logging/xmlui.js +21 -0
  189. package/dist/scripts/src/parsers/common/utils.js +19 -0
  190. package/dist/scripts/src/syntax/monaco/grammar.monacoLanguage.js +286 -0
  191. package/dist/scripts/src/syntax/monaco/index.js +14 -0
  192. package/dist/scripts/src/syntax/monaco/xmlui-dark.js +25 -0
  193. package/dist/scripts/src/syntax/monaco/xmlui-light.js +25 -0
  194. package/dist/scripts/src/syntax/monaco/xmluiscript.monacoLanguage.js +310 -0
  195. package/dist/scripts/src/syntax/textMate/index.js +14 -0
  196. package/dist/scripts/src/syntax/textMate/xmlui-dark.json +631 -0
  197. package/dist/scripts/src/syntax/textMate/xmlui-light.json +565 -0
  198. package/dist/scripts/src/syntax/textMate/xmlui.json +564 -0
  199. package/dist/scripts/src/syntax/textMate/xmlui.tmLanguage.json +341 -0
  200. package/dist/scripts/src/testing/ComponentDrivers.js +1327 -0
  201. package/dist/scripts/src/testing/assertions.js +444 -0
  202. package/dist/scripts/src/testing/component-test-helpers.js +389 -0
  203. package/dist/scripts/src/testing/drivers/DateInputDriver.js +19 -0
  204. package/dist/scripts/src/testing/drivers/ModalDialogDriver.js +10 -0
  205. package/dist/scripts/src/testing/drivers/NumberBoxDriver.js +44 -0
  206. package/dist/scripts/src/testing/drivers/SliderDriver.js +20 -0
  207. package/dist/scripts/src/testing/drivers/TextBoxDriver.js +20 -0
  208. package/dist/scripts/src/testing/drivers/TimeInputDriver.js +22 -0
  209. package/dist/scripts/src/testing/drivers/TimerDriver.js +64 -0
  210. package/dist/scripts/src/testing/fixtures.js +513 -0
  211. package/dist/scripts/src/testing/infrastructure/TestBed.js +17 -0
  212. package/dist/scripts/src/testing/infrastructure/main.js +9 -0
  213. package/dist/scripts/src/testing/infrastructure/public/mockServiceWorker.js +266 -0
  214. package/dist/scripts/src/testing/themed-app-test-helpers.js +139 -0
  215. package/dist/standalone/xmlui-standalone.es.d.ts +172 -10
  216. package/dist/standalone/xmlui-standalone.umd.js +36 -36
  217. package/package.json +2 -3
@@ -0,0 +1,910 @@
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
+ const fixtures_1 = require("../../testing/fixtures");
13
+ // Test data constants for API mocking
14
+ const basicApiInterceptor = {
15
+ operations: {
16
+ "get-test": {
17
+ url: "/api/test",
18
+ method: "get",
19
+ handler: `console.log('GET!!!'); return { message: "GET success", id: 1 };`,
20
+ },
21
+ "post-test": {
22
+ url: "/api/test/1",
23
+ method: "post",
24
+ handler: `return { message: "POST success", id: 2, data: $requestBody };`,
25
+ },
26
+ "put-test": {
27
+ url: "/api/test/1",
28
+ method: "put",
29
+ handler: `return { message: "PUT success", id: 1, data: $requestBody };`,
30
+ },
31
+ "delete-test": {
32
+ url: "/api/test/1",
33
+ method: "delete",
34
+ handler: `return { message: "DELETE success", deleted: true };`,
35
+ },
36
+ "query-params-test": {
37
+ url: "/api/search",
38
+ method: "get",
39
+ handler: `return { query: $queryParams, results: ["item1", "item2"] };`,
40
+ },
41
+ "headers-test": {
42
+ url: "/api/headers",
43
+ method: "get",
44
+ handler: `console.log('hd', $requestHeaders); return { headers: $requestHeaders };`,
45
+ },
46
+ "error-test": {
47
+ url: "/api/error",
48
+ method: "post",
49
+ handler: `throw Errors.HttpError(400, { message: "Bad request", details: "Invalid data" });`,
50
+ },
51
+ "slow-test": {
52
+ url: "/api/slow",
53
+ method: "get",
54
+ handler: `
55
+ await new Promise(resolve => setTimeout(resolve, 100));
56
+ return { message: "Slow response" };
57
+ `,
58
+ },
59
+ },
60
+ };
61
+ const confirmationInterceptor = {
62
+ operations: {
63
+ "confirm-test": {
64
+ url: "/api/confirm",
65
+ method: "post",
66
+ handler: `return { message: "Confirmed action", timestamp: Date.now() };`,
67
+ },
68
+ },
69
+ };
70
+ // =============================================================================
71
+ // BASIC FUNCTIONALITY TESTS
72
+ // =============================================================================
73
+ fixtures_1.test.describe("Basic Functionality", () => {
74
+ (0, fixtures_1.test)("component renders and initializes correctly", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
75
+ yield initTestBed(`<APICall id="test" url="/api/test" method="get" />`, {
76
+ apiInterceptor: basicApiInterceptor,
77
+ });
78
+ // APICall is non-visual, so we check for proper registration by checking if it exists in context
79
+ const component = page.getByTestId("test-id-component");
80
+ (0, fixtures_1.expect)(yield component.count()).toBe(0); // Non-visual component
81
+ }));
82
+ (0, fixtures_1.test)("component executes with basic properties", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
83
+ const { testStateDriver } = yield initTestBed(`
84
+ <Fragment>
85
+ <APICall id="api" url="/api/test" method="get" onSuccess="arg => testState = arg.message" />
86
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
87
+ </Fragment>
88
+ `, {
89
+ apiInterceptor: basicApiInterceptor,
90
+ });
91
+ const button = yield createButtonDriver("trigger");
92
+ yield button.click();
93
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("GET success");
94
+ }));
95
+ // =============================================================================
96
+ // HTTP METHOD TESTS
97
+ // =============================================================================
98
+ fixtures_1.test.describe("HTTP method property", () => {
99
+ const methods = ["get", "post", "put", "delete"];
100
+ methods.forEach((method) => {
101
+ (0, fixtures_1.test)(`executes ${method.toUpperCase()} request correctly`, (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
102
+ const { testStateDriver } = yield initTestBed(`
103
+ <Fragment>
104
+ <APICall
105
+ id="api"
106
+ url="/api/test${method === "get" ? "" : "/1"}"
107
+ method="${method}"
108
+ ${method !== "get" ? `body='{{ "test": "data" }}'` : ""}
109
+ onSuccess="result => testState = result.message"
110
+ />
111
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
112
+ </Fragment>
113
+ `, {
114
+ apiInterceptor: basicApiInterceptor,
115
+ });
116
+ const button = yield createButtonDriver("trigger");
117
+ yield button.click();
118
+ yield fixtures_1.expect
119
+ .poll(testStateDriver.testState, { timeout: 2000 })
120
+ .toEqual(`${method.toUpperCase()} success`);
121
+ }));
122
+ });
123
+ (0, fixtures_1.test)("supports additional HTTP methods like PATCH", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
124
+ const { testStateDriver } = yield initTestBed(`
125
+ <Fragment>
126
+ <APICall
127
+ id="api"
128
+ url="/api/test/1"
129
+ method="patch"
130
+ body='{{ "test": "data" }}'
131
+ onSuccess="() => testState = 'patch-success'"
132
+ />
133
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
134
+ </Fragment>
135
+ `, {
136
+ apiInterceptor: {
137
+ operations: {
138
+ "real-patch": {
139
+ url: "/api/test/1",
140
+ method: "patch",
141
+ handler: `return { message: "PATCH success" };`,
142
+ },
143
+ },
144
+ },
145
+ });
146
+ const button = yield createButtonDriver("trigger");
147
+ yield button.click();
148
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("patch-success");
149
+ }));
150
+ (0, fixtures_1.test)("defaults to GET method when not specified", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
151
+ const { testStateDriver } = yield initTestBed(`
152
+ <Fragment>
153
+ <APICall id="api" url="/api/test" onSuccess="result => testState = result.message" />
154
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
155
+ </Fragment>
156
+ `, {
157
+ apiInterceptor: basicApiInterceptor,
158
+ });
159
+ const button = yield createButtonDriver("trigger");
160
+ yield button.click();
161
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("GET success");
162
+ }));
163
+ (0, fixtures_1.test)("handles invalid method gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
164
+ const { testStateDriver } = yield initTestBed(`
165
+ <Fragment>
166
+ <APICall id="api" url="/api/test" method="invalid" onError="() => testState = 'error'" />
167
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
168
+ </Fragment>
169
+ `, {
170
+ apiInterceptor: basicApiInterceptor,
171
+ });
172
+ const button = yield createButtonDriver("trigger");
173
+ yield button.click();
174
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("error");
175
+ }));
176
+ });
177
+ // =============================================================================
178
+ // URL PROPERTY TESTS
179
+ // =============================================================================
180
+ fixtures_1.test.describe("url property", () => {
181
+ (0, fixtures_1.test)("handles absolute URLs", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
182
+ const { testStateDriver } = yield initTestBed(`
183
+ <Fragment>
184
+ <APICall id="api" url="/api/test" onSuccess="() => testState = 'success'" />
185
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
186
+ </Fragment>
187
+ `, {
188
+ apiInterceptor: basicApiInterceptor,
189
+ });
190
+ const button = yield createButtonDriver("trigger");
191
+ yield button.click();
192
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
193
+ }));
194
+ (0, fixtures_1.test)("handles relative URLs", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
195
+ const { testStateDriver } = yield initTestBed(`
196
+ <Fragment>
197
+ <APICall id="api" url="api/test" onSuccess="() => testState = 'success'" />
198
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
199
+ </Fragment>
200
+ `, {
201
+ apiInterceptor: {
202
+ operations: {
203
+ "relative-test": {
204
+ url: "**/api/test",
205
+ method: "get",
206
+ handler: `return { success: true };`,
207
+ },
208
+ },
209
+ },
210
+ });
211
+ const button = yield createButtonDriver("trigger");
212
+ yield button.click();
213
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
214
+ }));
215
+ (0, fixtures_1.test)("handles URL with special characters", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
216
+ const { testStateDriver } = yield initTestBed(`
217
+ <Fragment>
218
+ <APICall id="api" url="/api/test?q=hello%20world&filter=a%26b" onSuccess="() => testState = 'success'" />
219
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
220
+ </Fragment>
221
+ `, {
222
+ apiInterceptor: {
223
+ operations: {
224
+ "special-chars": {
225
+ url: "**/api/test**",
226
+ method: "get",
227
+ handler: `return { success: true };`,
228
+ },
229
+ },
230
+ },
231
+ });
232
+ const button = yield createButtonDriver("trigger");
233
+ yield button.click();
234
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
235
+ }));
236
+ });
237
+ // =============================================================================
238
+ // BODY PROPERTY TESTS
239
+ // =============================================================================
240
+ fixtures_1.test.describe("body property", () => {
241
+ (0, fixtures_1.test)("sends JSON body correctly", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
242
+ const { testStateDriver } = yield initTestBed(`
243
+ <Fragment>
244
+ <APICall
245
+ id="api"
246
+ url="/api/test/1"
247
+ method="post"
248
+ body="{{ name: 'John', age: 30 }}"
249
+ onSuccess="result => testState = result.data.name"
250
+ />
251
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
252
+ </Fragment>
253
+ `, {
254
+ apiInterceptor: basicApiInterceptor,
255
+ });
256
+ const button = yield createButtonDriver("trigger");
257
+ yield button.click();
258
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("John");
259
+ }));
260
+ (0, fixtures_1.test)("handles empty body", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
261
+ const { testStateDriver } = yield initTestBed(`
262
+ <Fragment>
263
+ <APICall id="api" url="/api/test/1" method="post" body="" onSuccess="() => testState = 'success'" />
264
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
265
+ </Fragment>
266
+ `, {
267
+ apiInterceptor: basicApiInterceptor,
268
+ });
269
+ const button = yield createButtonDriver("trigger");
270
+ yield button.click();
271
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
272
+ }));
273
+ (0, fixtures_1.test)("handles complex nested objects in body", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
274
+ const { testStateDriver } = yield initTestBed(`
275
+ <Fragment>
276
+ <APICall
277
+ id="api"
278
+ url="/api/test/1"
279
+ method="post"
280
+ body="{{ user: { profile: { name: 'Jane', settings: { theme: 'dark' } } }, items: [1, 2, 3] }}"
281
+ onSuccess="result => testState = result.data.user.profile.name"
282
+ />
283
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
284
+ </Fragment>
285
+ `, {
286
+ apiInterceptor: basicApiInterceptor,
287
+ });
288
+ const button = yield createButtonDriver("trigger");
289
+ yield button.click();
290
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("Jane");
291
+ }));
292
+ });
293
+ // =============================================================================
294
+ // RAW BODY PROPERTY TESTS
295
+ // =============================================================================
296
+ fixtures_1.test.describe("rawBody property", () => {
297
+ (0, fixtures_1.test)("sends raw string body", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
298
+ const { testStateDriver } = yield initTestBed(`
299
+ <Fragment>
300
+ <APICall
301
+ id="api"
302
+ url="/api/test"
303
+ method="post"
304
+ rawBody="plain text content"
305
+ onSuccess="() => testState = 'success'"
306
+ />
307
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
308
+ </Fragment>
309
+ `, {
310
+ apiInterceptor: {
311
+ operations: {
312
+ "raw-body": {
313
+ url: "/api/test",
314
+ method: "post",
315
+ handler: `return { received: $requestBody };`,
316
+ },
317
+ },
318
+ },
319
+ });
320
+ const button = yield createButtonDriver("trigger");
321
+ yield button.click();
322
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
323
+ }));
324
+ (0, fixtures_1.test)("rawBody takes precedence over body", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
325
+ const { testStateDriver } = yield initTestBed(`
326
+ <Fragment>
327
+ <APICall
328
+ id="api"
329
+ url="/api/test"
330
+ method="post"
331
+ body="{{ name: 'John' }}"
332
+ rawBody="raw content"
333
+ onSuccess="() => testState = 'success'"
334
+ />
335
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
336
+ </Fragment>
337
+ `, {
338
+ apiInterceptor: {
339
+ operations: {
340
+ "precedence-test": {
341
+ url: "/api/test",
342
+ method: "post",
343
+ handler: `return { received: $requestBody };`,
344
+ },
345
+ },
346
+ },
347
+ });
348
+ const button = yield createButtonDriver("trigger");
349
+ yield button.click();
350
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
351
+ }));
352
+ });
353
+ // =============================================================================
354
+ // QUERY PARAMS PROPERTY TESTS
355
+ // =============================================================================
356
+ fixtures_1.test.describe("queryParams property", () => {
357
+ (0, fixtures_1.test)("sends query parameters correctly", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
358
+ const { testStateDriver } = yield initTestBed(`
359
+ <Fragment>
360
+ <APICall
361
+ id="api"
362
+ url="/api/search"
363
+ queryParams="{{ q: 'test', limit: 10, active: true }}"
364
+ onSuccess="result => testState = result.query.q"
365
+ />
366
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
367
+ </Fragment>
368
+ `, {
369
+ apiInterceptor: basicApiInterceptor,
370
+ });
371
+ const button = yield createButtonDriver("trigger");
372
+ yield button.click();
373
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("test");
374
+ }));
375
+ (0, fixtures_1.test)("handles empty query parameters", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
376
+ const { testStateDriver } = yield initTestBed(`
377
+ <Fragment>
378
+ <APICall id="api" url="/api/search" queryParams="{{}}" onSuccess="() => testState = 'success'" />
379
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
380
+ </Fragment>
381
+ `, {
382
+ apiInterceptor: basicApiInterceptor,
383
+ });
384
+ const button = yield createButtonDriver("trigger");
385
+ yield button.click();
386
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
387
+ }));
388
+ (0, fixtures_1.test)("handles special characters in query parameters", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
389
+ const { testStateDriver } = yield initTestBed(`
390
+ <Fragment>
391
+ <APICall
392
+ id="api"
393
+ url="/api/search"
394
+ queryParams="{{ q: 'hello world', special: 'a&b=c' }}"
395
+ onSuccess="result => testState = result.query.q"
396
+ />
397
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
398
+ </Fragment>
399
+ `, {
400
+ apiInterceptor: basicApiInterceptor,
401
+ });
402
+ const button = yield createButtonDriver("trigger");
403
+ yield button.click();
404
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("hello world");
405
+ }));
406
+ });
407
+ // =============================================================================
408
+ // HEADERS PROPERTY TESTS
409
+ // =============================================================================
410
+ fixtures_1.test.describe("headers property", () => {
411
+ (0, fixtures_1.test)("sends custom headers correctly", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
412
+ const { testStateDriver } = yield initTestBed(`
413
+ <Fragment>
414
+ <APICall
415
+ id="api"
416
+ url="/api/headers"
417
+ headers="{{ 'X-Custom-Header': 'test-value', 'Authorization': 'Bearer token123' }}"
418
+ onSuccess="result => testState = result.headers['x-custom-header']"
419
+ />
420
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
421
+ </Fragment>
422
+ `, {
423
+ apiInterceptor: basicApiInterceptor,
424
+ });
425
+ const button = yield createButtonDriver("trigger");
426
+ yield button.click();
427
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("test-value");
428
+ }));
429
+ (0, fixtures_1.test)("handles empty headers", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
430
+ const { testStateDriver } = yield initTestBed(`
431
+ <Fragment>
432
+ <APICall id="api" url="/api/headers" headers="{{}}" onSuccess="() => testState = 'success'" />
433
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
434
+ </Fragment>
435
+ `, {
436
+ apiInterceptor: basicApiInterceptor,
437
+ });
438
+ const button = yield createButtonDriver("trigger");
439
+ yield button.click();
440
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
441
+ }));
442
+ });
443
+ // =============================================================================
444
+ // CONFIRMATION DIALOG TESTS
445
+ // =============================================================================
446
+ fixtures_1.test.describe("confirmation dialog properties", () => {
447
+ (0, fixtures_1.test)("shows confirmation dialog with custom title and message", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, page, }) {
448
+ yield initTestBed(`
449
+ <Fragment>
450
+ <APICall
451
+ id="api"
452
+ url="/api/confirm"
453
+ method="post"
454
+ confirmTitle="Custom Title"
455
+ confirmMessage="Are you sure you want to proceed?"
456
+ confirmButtonLabel="Yes, Continue"
457
+ />
458
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
459
+ </Fragment>
460
+ `, {
461
+ apiInterceptor: confirmationInterceptor,
462
+ });
463
+ const button = yield createButtonDriver("trigger");
464
+ yield button.click();
465
+ // Check for confirmation dialog
466
+ yield (0, fixtures_1.expect)(page.getByText("Custom Title")).toBeVisible();
467
+ yield (0, fixtures_1.expect)(page.getByText("Are you sure you want to proceed?")).toBeVisible();
468
+ yield (0, fixtures_1.expect)(page.getByText("Yes, Continue")).toBeVisible();
469
+ }));
470
+ (0, fixtures_1.test)("API call proceeds when confirmation is accepted", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, page, }) {
471
+ const { testStateDriver } = yield initTestBed(`
472
+ <Fragment>
473
+ <APICall
474
+ id="api"
475
+ url="/api/confirm"
476
+ method="post"
477
+ confirmTitle="Confirm"
478
+ confirmMessage="Proceed?"
479
+ onSuccess="() => testState = 'confirmed'"
480
+ />
481
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
482
+ </Fragment>
483
+ `, {
484
+ apiInterceptor: confirmationInterceptor,
485
+ });
486
+ const button = yield createButtonDriver("trigger");
487
+ yield button.click();
488
+ // Accept confirmation
489
+ yield page.getByRole("button", { name: /yes/i }).click();
490
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("confirmed");
491
+ }));
492
+ (0, fixtures_1.test)("API call is cancelled when confirmation is rejected", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, page, }) {
493
+ const { testStateDriver } = yield initTestBed(`
494
+ <Fragment>
495
+ <APICall
496
+ id="api"
497
+ url="/api/confirm"
498
+ method="post"
499
+ confirmTitle="Confirm"
500
+ confirmMessage="Proceed?"
501
+ onSuccess="() => testState = 'confirmed'"
502
+ onError="() => testState = 'error'"
503
+ />
504
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
505
+ </Fragment>
506
+ `, {
507
+ apiInterceptor: confirmationInterceptor,
508
+ });
509
+ const button = yield createButtonDriver("trigger");
510
+ yield button.click();
511
+ // Reject confirmation
512
+ yield page.getByRole("button", { name: /cancel|no/i }).click();
513
+ // Should not execute API call
514
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual(null);
515
+ }));
516
+ });
517
+ // =============================================================================
518
+ // NOTIFICATION MESSAGE TESTS
519
+ // =============================================================================
520
+ fixtures_1.test.describe("notification message properties", () => {
521
+ (0, fixtures_1.test)("shows progress notification during API call", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, page, }) {
522
+ yield initTestBed(`
523
+ <Fragment>
524
+ <APICall
525
+ id="api"
526
+ url="/api/slow"
527
+ inProgressNotificationMessage="Processing your request..."
528
+ />
529
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
530
+ </Fragment>
531
+ `, {
532
+ apiInterceptor: basicApiInterceptor,
533
+ });
534
+ const button = yield createButtonDriver("trigger");
535
+ yield button.click();
536
+ // Check for progress notification
537
+ yield (0, fixtures_1.expect)(page.getByText("Processing your request...")).toBeVisible();
538
+ }));
539
+ (0, fixtures_1.test)("shows success notification with result data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, page, }) {
540
+ yield initTestBed(`
541
+ <Fragment>
542
+ <APICall
543
+ id="api"
544
+ url="/api/test"
545
+ completedNotificationMessage="Success: {$result.message}"
546
+ />
547
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
548
+ </Fragment>
549
+ `, {
550
+ apiInterceptor: basicApiInterceptor,
551
+ });
552
+ const button = yield createButtonDriver("trigger");
553
+ yield button.click();
554
+ // Check for success notification
555
+ yield (0, fixtures_1.expect)(page.getByText("Success: GET success")).toBeVisible();
556
+ }));
557
+ (0, fixtures_1.test)("shows error notification with error details", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, page, }) {
558
+ yield initTestBed(`
559
+ <Fragment>
560
+ <APICall
561
+ id="api"
562
+ url="/api/error"
563
+ method="post"
564
+ errorNotificationMessage="Error {$error.statusCode}: {$error.details.message}"
565
+ />
566
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
567
+ </Fragment>
568
+ `, {
569
+ apiInterceptor: basicApiInterceptor,
570
+ });
571
+ const button = yield createButtonDriver("trigger");
572
+ yield button.click();
573
+ // Check for error notification
574
+ yield (0, fixtures_1.expect)(page.getByText("Error 400: Bad request")).toBeVisible();
575
+ }));
576
+ });
577
+ // =============================================================================
578
+ // EXECUTE METHOD TESTS
579
+ // =============================================================================
580
+ fixtures_1.test.describe("execute method", () => {
581
+ (0, fixtures_1.test)("triggers API call", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
582
+ const { testStateDriver } = yield initTestBed(`
583
+ <Fragment>
584
+ <APICall id="api" url="/api/test" onSuccess="() => testState = 'executed'" />
585
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
586
+ </Fragment>
587
+ `, {
588
+ apiInterceptor: basicApiInterceptor,
589
+ });
590
+ const button = yield createButtonDriver("trigger");
591
+ yield button.click();
592
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("executed");
593
+ }));
594
+ (0, fixtures_1.test)("accepts parameters", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
595
+ const { testStateDriver } = yield initTestBed(`
596
+ <Fragment>
597
+ <APICall
598
+ id="api"
599
+ url="/api/test/1"
600
+ method="post"
601
+ body="{$param}"
602
+ onSuccess="result => testState = result.data.name"
603
+ />
604
+ <Button testId="trigger" onClick="api.execute({ name: 'John', age: 30 })" label="Execute" />
605
+ </Fragment>
606
+ `, {
607
+ apiInterceptor: basicApiInterceptor,
608
+ });
609
+ const button = yield createButtonDriver("trigger");
610
+ yield button.click();
611
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("John");
612
+ }));
613
+ (0, fixtures_1.test)("provides access to multiple parameters", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
614
+ const { testStateDriver } = yield initTestBed(`
615
+ <Fragment>
616
+ <APICall
617
+ id="api"
618
+ url="/api/test/1"
619
+ method="post"
620
+ body="{{ first: $params[0], second: $params[1], third: $params[2] }}"
621
+ onSuccess="result => testState = result.data.first + '-' + result.data.second + '-' + result.data.third"
622
+ />
623
+ <Button testId="trigger" onClick="api.execute('param1', 'param2', 'param3')" label="Execute" />
624
+ </Fragment>
625
+ `, {
626
+ apiInterceptor: basicApiInterceptor,
627
+ });
628
+ const button = yield createButtonDriver("trigger");
629
+ yield button.click();
630
+ yield fixtures_1.expect
631
+ .poll(testStateDriver.testState, { timeout: 2000 })
632
+ .toEqual("param1-param2-param3");
633
+ }));
634
+ (0, fixtures_1.test)("can be called multiple times", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
635
+ const { testStateDriver } = yield initTestBed(`
636
+ <Fragment var.callCount="{0}">
637
+ <Button testId="trigger" label="Execute {callCount}" >
638
+ <event name="click">
639
+ <APICall
640
+ url="/api/test"
641
+ onSuccess="console.log('before', callCount); callCount++; console.log('after', callCount); testState = callCount;"
642
+ />
643
+ </event>
644
+ </Button>
645
+ </Fragment>
646
+ `, {
647
+ apiInterceptor: basicApiInterceptor,
648
+ });
649
+ const button = yield createButtonDriver("trigger");
650
+ yield button.click();
651
+ yield new Promise((resolve) => setTimeout(resolve, 100)); // Wait for async execution
652
+ //await expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual(1);
653
+ yield button.click();
654
+ //await expect.poll(testStateDriver.testState).toEqual(2);
655
+ yield button.click();
656
+ //await expect.poll(testStateDriver.testState).toEqual(3);
657
+ }));
658
+ });
659
+ // =============================================================================
660
+ // CONTEXT VARIABLE TESTS
661
+ // =============================================================================
662
+ fixtures_1.test.describe("context variables", () => {
663
+ (0, fixtures_1.test)("$param provides access to first parameter", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
664
+ const { testStateDriver } = yield initTestBed(`
665
+ <Fragment>
666
+ <APICall
667
+ id="api"
668
+ url="/api/test/1"
669
+ method="post"
670
+ body="{$param}"
671
+ onSuccess="result => testState = result.data.message"
672
+ />
673
+ <Button testId="trigger" onClick="api.execute({ message: 'hello' })" label="Execute" />
674
+ </Fragment>
675
+ `, {
676
+ apiInterceptor: basicApiInterceptor,
677
+ });
678
+ const button = yield createButtonDriver("trigger");
679
+ yield button.click();
680
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("hello");
681
+ }));
682
+ (0, fixtures_1.test)("$params provides access to all parameters", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
683
+ const { testStateDriver } = yield initTestBed(`
684
+ <Fragment>
685
+ <APICall
686
+ id="api"
687
+ url="/api/test/1"
688
+ method="post"
689
+ body="{{ all: $params }}"
690
+ onSuccess="result => testState = result.data.all.length"
691
+ />
692
+ <Button testId="trigger" onClick="api.execute('a', 'b', 'c')" label="Execute" />
693
+ </Fragment>
694
+ `, {
695
+ apiInterceptor: basicApiInterceptor,
696
+ });
697
+ const button = yield createButtonDriver("trigger");
698
+ yield button.click();
699
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual(3);
700
+ }));
701
+ (0, fixtures_1.test)("$result provides access to response data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
702
+ const { testStateDriver } = yield initTestBed(`
703
+ <Fragment>
704
+ <APICall
705
+ id="api"
706
+ url="/api/test"
707
+ onSuccess="result => testState = result.id + ' - ' + result.message"
708
+ />
709
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
710
+ </Fragment>
711
+ `, {
712
+ apiInterceptor: basicApiInterceptor,
713
+ });
714
+ const button = yield createButtonDriver("trigger");
715
+ yield button.click();
716
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("1 - GET success");
717
+ }));
718
+ (0, fixtures_1.test)("$error provides access to error information", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
719
+ const { testStateDriver } = yield initTestBed(`
720
+ <Fragment>
721
+ <APICall
722
+ id="api"
723
+ url="/api/error"
724
+ method="post"
725
+ onError="error => testState = error.statusCode + ' - ' + error.details.message"
726
+ />
727
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
728
+ </Fragment>
729
+ `, {
730
+ apiInterceptor: basicApiInterceptor,
731
+ });
732
+ const button = yield createButtonDriver("trigger");
733
+ yield button.click();
734
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("400 - Bad request");
735
+ }));
736
+ });
737
+ });
738
+ // =============================================================================
739
+ // OTHER EDGE CASE TESTS
740
+ // =============================================================================
741
+ fixtures_1.test.describe("Other Edge Cases", () => {
742
+ (0, fixtures_1.test)("handles null and undefined parameters gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
743
+ const { testStateDriver } = yield initTestBed(`
744
+ <Fragment>
745
+ <APICall
746
+ id="api"
747
+ url="/api/test/1"
748
+ method="post"
749
+ body="{$param}"
750
+ onSuccess="() => testState = 'success'"
751
+ onError="() => testState = 'error'"
752
+ />
753
+ <Button testId="trigger" onClick="api.execute(null)" label="Execute" />
754
+ </Fragment>
755
+ `, {
756
+ apiInterceptor: basicApiInterceptor,
757
+ });
758
+ const button = yield createButtonDriver("trigger");
759
+ yield button.click();
760
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
761
+ }));
762
+ (0, fixtures_1.test)("handles undefined URL gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
763
+ const { testStateDriver } = yield initTestBed(`
764
+ <Fragment>
765
+ <APICall id="api" onError="() => testState = 'error'" />
766
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
767
+ </Fragment>
768
+ `, {
769
+ apiInterceptor: basicApiInterceptor,
770
+ });
771
+ const button = yield createButtonDriver("trigger");
772
+ yield button.click();
773
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("error");
774
+ }));
775
+ (0, fixtures_1.test)("handles malformed JSON in body gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
776
+ const { testStateDriver } = yield initTestBed(`
777
+ <Fragment>
778
+ <APICall
779
+ id="api"
780
+ url="/api/test"
781
+ method="post"
782
+ body="{ invalid json }"
783
+ onSuccess="() => testState = 'success'"
784
+ onError="() => testState = 'error'"
785
+ />
786
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
787
+ </Fragment>
788
+ `, {
789
+ apiInterceptor: basicApiInterceptor,
790
+ });
791
+ const button = yield createButtonDriver("trigger");
792
+ yield button.click();
793
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("error");
794
+ }));
795
+ (0, fixtures_1.test)("handles very large request payloads", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
796
+ const { testStateDriver } = yield initTestBed(`
797
+ <Fragment>
798
+ <APICall
799
+ id="api"
800
+ url="/api/test/1"
801
+ method="post"
802
+ body="{$param}"
803
+ onSuccess="() => testState = 'success'"
804
+ />
805
+ <Button testId="trigger" onClick="api.execute({ data: 'x'.repeat(10000) })" label="Execute" />
806
+ </Fragment>
807
+ `, {
808
+ apiInterceptor: basicApiInterceptor,
809
+ });
810
+ const button = yield createButtonDriver("trigger");
811
+ yield button.click();
812
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
813
+ }));
814
+ (0, fixtures_1.test)("handles special Unicode characters in data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
815
+ const { testStateDriver } = yield initTestBed(`
816
+ <Fragment>
817
+ <APICall
818
+ id="api"
819
+ url="/api/test/1"
820
+ method="post"
821
+ body="{$param}"
822
+ onSuccess="result => testState = result.data.emoji"
823
+ />
824
+ <Button testId="trigger" onClick="api.execute({ emoji: '👨‍👩‍👧‍👦🚀', chinese: '你好世界' })" label="Execute" />
825
+ </Fragment>
826
+ `, {
827
+ apiInterceptor: basicApiInterceptor,
828
+ });
829
+ const button = yield createButtonDriver("trigger");
830
+ yield button.click();
831
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("👨‍👩‍👧‍👦🚀");
832
+ }));
833
+ (0, fixtures_1.test)("handles rapid successive API calls", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed, createButtonDriver }) {
834
+ const { testStateDriver } = yield initTestBed(`
835
+ <Fragment>
836
+ <APICall
837
+ id="api"
838
+ url="/api/test"
839
+ onSuccess="testState ??= 0; testState++;"
840
+ />
841
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
842
+ </Fragment>
843
+ `, {
844
+ apiInterceptor: basicApiInterceptor,
845
+ });
846
+ const button = yield createButtonDriver("trigger");
847
+ // Rapidly click multiple times
848
+ yield button.click();
849
+ yield page.waitForTimeout(100);
850
+ yield button.click();
851
+ yield page.waitForTimeout(100);
852
+ yield button.click();
853
+ yield page.waitForTimeout(100);
854
+ // Should handle all calls
855
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 5000 }).toEqual(3);
856
+ }));
857
+ (0, fixtures_1.test)("handles component cleanup correctly", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver }) {
858
+ const { testStateDriver } = yield initTestBed(`
859
+ <Fragment var.showApi="true">
860
+ <Fragment if="showApi">
861
+ <APICall id="api" url="/api/test" onSuccess="() => testState = 'success'" />
862
+ </Fragment>
863
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
864
+ <Button testId="hide" onClick="showApi = false" label="Hide" />
865
+ </Fragment>
866
+ `, {
867
+ apiInterceptor: basicApiInterceptor,
868
+ });
869
+ const executeButton = yield createButtonDriver("trigger");
870
+ const hideButton = yield createButtonDriver("hide");
871
+ // Execute API call first
872
+ yield executeButton.click();
873
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
874
+ // Hide the component
875
+ yield hideButton.click();
876
+ // Try to execute again (should not crash)
877
+ try {
878
+ yield executeButton.click();
879
+ }
880
+ catch (error) {
881
+ // This is expected as the component is no longer available
882
+ }
883
+ }));
884
+ (0, fixtures_1.test)("handles when condition preventing execution", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createButtonDriver, }) {
885
+ const { testStateDriver } = yield initTestBed(`
886
+ <Fragment var.allowExecution="false">
887
+ <APICall
888
+ id="api"
889
+ url="/api/test"
890
+ when="allowExecution"
891
+ onSuccess="() => testState = 'success'"
892
+ onError="() => testState = 'error'"
893
+ />
894
+ <Button testId="trigger" onClick="api.execute()" label="Execute" />
895
+ <Button testId="allow" onClick="allowExecution = true" label="Allow" />
896
+ </Fragment>
897
+ `, {
898
+ apiInterceptor: basicApiInterceptor,
899
+ });
900
+ const executeButton = yield createButtonDriver("trigger");
901
+ const allowButton = yield createButtonDriver("allow");
902
+ // Try to execute when not allowed
903
+ yield executeButton.click();
904
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual(null);
905
+ // Allow execution and try again
906
+ yield allowButton.click();
907
+ yield executeButton.click();
908
+ yield fixtures_1.expect.poll(testStateDriver.testState, { timeout: 2000 }).toEqual("success");
909
+ }));
910
+ });