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.
- package/dist/lib/{index-Db5iQkFp.mjs → index-axjeT2uJ.mjs} +1626 -1080
- package/dist/lib/index.css +1 -1
- package/dist/lib/{initMock-B9LtmFJG.mjs → initMock-BoTWMs19.mjs} +1 -1
- package/dist/lib/language-server-web-worker.mjs +1 -1
- package/dist/lib/language-server.mjs +1 -1
- package/dist/lib/{metadata-utils-D90qqMGc.mjs → metadata-utils-CtY0QcvH.mjs} +2 -1
- package/dist/lib/{server-common-lmBDLpUh.mjs → server-common-Cine5nRR.mjs} +1 -1
- package/dist/lib/xmlui.d.ts +99 -6
- package/dist/lib/xmlui.mjs +78 -42
- package/dist/metadata/{collectedComponentMetadata-BN8eg9Gr.mjs → collectedComponentMetadata-CQywuPDB.mjs} +17448 -16984
- package/dist/metadata/{initMock-J7pN8owj.mjs → initMock-Bi5kF5Af.mjs} +1 -1
- package/dist/metadata/style.css +1 -1
- package/dist/metadata/xmlui-metadata.mjs +1 -1
- package/dist/metadata/xmlui-metadata.umd.js +3 -3
- package/dist/scripts/bin/build-lib.js +21 -13
- package/dist/scripts/bin/viteConfig.js +3 -1
- package/dist/scripts/package.json +2 -3
- package/dist/scripts/src/abstractions/scripting/Token.js +2 -0
- package/dist/scripts/src/abstractions/scripting/TryScope.js +2 -0
- package/dist/scripts/src/abstractions/scripting/modules.js +2 -0
- package/dist/scripts/src/components/APICall/APICall.spec.js +910 -0
- package/dist/scripts/src/components/Accordion/Accordion.spec.js +969 -0
- package/dist/scripts/src/components/Animation/Animation.js +50 -0
- package/dist/scripts/src/components/App/App.spec.js +219 -0
- package/dist/scripts/src/components/AppHeader/AppHeader.spec.js +169 -0
- package/dist/scripts/src/components/AppState/AppState.js +32 -2
- package/dist/scripts/src/components/AppState/AppState.spec.js +268 -0
- package/dist/scripts/src/components/AppState/AppStateNative.js +27 -3
- package/dist/scripts/src/components/AutoComplete/AutoComplete.spec.js +383 -0
- package/dist/scripts/src/components/Avatar/Avatar.spec.js +1543 -0
- package/dist/scripts/src/components/Backdrop/Backdrop.spec.js +131 -0
- package/dist/scripts/src/components/Badge/Badge.spec.js +2214 -0
- package/dist/scripts/src/components/Bookmark/Bookmark.spec.js +230 -0
- package/dist/scripts/src/components/Breakout/Breakout.spec.js +56 -0
- package/dist/scripts/src/components/Button/Button-style.spec.js +274 -0
- package/dist/scripts/src/components/Button/Button.js +5 -1
- package/dist/scripts/src/components/Button/Button.spec.js +454 -0
- package/dist/scripts/src/components/Card/Card.spec.js +150 -0
- package/dist/scripts/src/components/Carousel/Carousel.spec.js +343 -0
- package/dist/scripts/src/components/Carousel/CarouselNative.js +2 -2
- package/dist/scripts/src/components/ChangeListener/ChangeListener.spec.js +169 -0
- package/dist/scripts/src/components/Charts/AreaChart/AreaChart.spec.js +999 -0
- package/dist/scripts/src/components/Charts/BarChart/BarChart.spec.js +597 -0
- package/dist/scripts/src/components/Charts/DonutChart/DonutChart.spec.js +608 -0
- package/dist/scripts/src/components/Charts/LabelList/LabelList.spec.js +539 -0
- package/dist/scripts/src/components/Charts/Legend/Legend.spec.js +558 -0
- package/dist/scripts/src/components/Charts/LineChart/LineChart.spec.js +450 -0
- package/dist/scripts/src/components/Charts/PieChart/PieChart.spec.js +584 -0
- package/dist/scripts/src/components/Charts/PieChart/PieChartNative.js +41 -2
- package/dist/scripts/src/components/Charts/RadarChart/RadarChart.spec.js +571 -0
- package/dist/scripts/src/components/Charts/Tooltip/TooltipContent.spec.js +449 -0
- package/dist/scripts/src/components/Checkbox/Checkbox.spec.js +964 -0
- package/dist/scripts/src/components/CodeBlock/CodeBlock.spec.js +196 -0
- package/dist/scripts/src/components/ColorPicker/ColorPicker.spec.js +283 -0
- package/dist/scripts/src/components/ColorPicker/ColorPickerNative.js +9 -26
- package/dist/scripts/src/components/Column/doc-resources/list-component-data.js +53 -0
- package/dist/scripts/src/components/ComponentProvider.js +6 -2
- package/dist/scripts/src/components/ContentSeparator/ContentSeparator.spec.js +338 -0
- package/dist/scripts/src/components/DateInput/DateInput.spec.js +918 -0
- package/dist/scripts/src/components/DatePicker/DatePicker.spec.js +362 -0
- package/dist/scripts/src/components/DatePicker/DatePickerNative.js +3 -3
- package/dist/scripts/src/components/DropdownMenu/DropdownMenu.spec.js +331 -0
- package/dist/scripts/src/components/DropdownMenu/DropdownMenuNative.js +7 -9
- package/dist/scripts/src/components/EmojiSelector/EmojiSelector.spec.js +29 -0
- package/dist/scripts/src/components/ExpandableItem/ExpandableItem.spec.js +435 -0
- package/dist/scripts/src/components/FileInput/FileInput.spec.js +249 -0
- package/dist/scripts/src/components/FileUploadDropZone/FileUploadDropZone.spec.js +296 -0
- package/dist/scripts/src/components/FlowLayout/FlowLayout.spec.js +518 -0
- package/dist/scripts/src/components/Footer/Footer.spec.js +991 -0
- package/dist/scripts/src/components/Form/Form.spec.js +1257 -0
- package/dist/scripts/src/components/FormItem/FormItem.spec.js +723 -0
- package/dist/scripts/src/components/FormItem/ItemWithLabel.js +3 -3
- package/dist/scripts/src/components/FormSection/FormSection.js +6 -31
- package/dist/scripts/src/components/Fragment/Fragment.spec.js +50 -0
- package/dist/scripts/src/components/Heading/H1.spec.js +66 -0
- package/dist/scripts/src/components/Heading/H2.spec.js +66 -0
- package/dist/scripts/src/components/Heading/H3.spec.js +66 -0
- package/dist/scripts/src/components/Heading/H4.spec.js +66 -0
- package/dist/scripts/src/components/Heading/H5.spec.js +66 -0
- package/dist/scripts/src/components/Heading/H6.spec.js +66 -0
- package/dist/scripts/src/components/Heading/Heading.spec.js +897 -0
- package/dist/scripts/src/components/HtmlTags/HtmlTags.spec.js +69 -0
- package/dist/scripts/src/components/IFrame/IFrame.spec.js +527 -0
- package/dist/scripts/src/components/Icon/ArrowDropDown.js +11 -0
- package/dist/scripts/src/components/Icon/ArrowDropUp.js +11 -0
- package/dist/scripts/src/components/Icon/ArrowLeft.js +11 -0
- package/dist/scripts/src/components/Icon/ArrowRight.js +11 -0
- package/dist/scripts/src/components/Icon/ChevronDownIcon.js +7 -0
- package/dist/scripts/src/components/Icon/ChevronUpIcon.js +7 -0
- package/dist/scripts/src/components/Icon/Icon.spec.js +527 -0
- package/dist/scripts/src/components/Icon/SunIcon.js +10 -0
- package/dist/scripts/src/components/Image/Image.js +2 -1
- package/dist/scripts/src/components/Image/Image.spec.js +198 -0
- package/dist/scripts/src/components/Image/ImageNative.js +30 -2
- package/dist/scripts/src/components/Input/InputLabel.js +25 -0
- package/dist/scripts/src/components/Input/index.js +5 -0
- package/dist/scripts/src/components/Items/Items.spec.js +397 -0
- package/dist/scripts/src/components/Link/Link.spec.js +894 -0
- package/dist/scripts/src/components/List/List.spec.js +927 -0
- package/dist/scripts/src/components/List/doc-resources/list-component-data.js +53 -0
- package/dist/scripts/src/components/Markdown/Markdown.spec.js +188 -0
- package/dist/scripts/src/components/ModalDialog/ModalDialog.spec.js +162 -0
- package/dist/scripts/src/components/NavGroup/NavGroup.spec.js +212 -0
- package/dist/scripts/src/components/NavGroup/NavGroupNative.js +15 -7
- package/dist/scripts/src/components/NavLink/NavLink.spec.js +864 -0
- package/dist/scripts/src/components/NavPanel/NavPanel.spec.js +864 -0
- package/dist/scripts/src/components/NoResult/NoResult.spec.js +863 -0
- package/dist/scripts/src/components/NumberBox/NumberBox.spec.js +1237 -0
- package/dist/scripts/src/components/Option/Option.spec.js +472 -0
- package/dist/scripts/src/components/PageMetaTitle/PageMetaTitle.spec.js +80 -0
- package/dist/scripts/src/components/Pagination/Pagination.spec.js +1003 -0
- package/dist/scripts/src/components/ProfileMenu/ProfileMenu.js +20 -0
- package/dist/scripts/src/components/ProgressBar/ProgressBar.spec.js +166 -0
- package/dist/scripts/src/components/Queue/Queue.spec.js +626 -0
- package/dist/scripts/src/components/RadioGroup/RadioGroup.spec.js +479 -0
- package/dist/scripts/src/components/Redirect/Redirect.spec.js +527 -0
- package/dist/scripts/src/components/ResponsiveBar/ResponsiveBar.spec.js +76 -0
- package/dist/scripts/src/components/Select/Select.spec.js +527 -0
- package/dist/scripts/src/components/SelectionStore/SelectionStoreNative.js +3 -1
- package/dist/scripts/src/components/Slider/Slider.js +2 -0
- package/dist/scripts/src/components/Slider/Slider.spec.js +574 -0
- package/dist/scripts/src/components/Slider/SliderNative.js +63 -26
- package/dist/scripts/src/components/Slot/Slot.spec.js +368 -0
- package/dist/scripts/src/components/SpaceFiller/SpaceFiller.spec.js +184 -0
- package/dist/scripts/src/components/Spinner/Spinner.spec.js +161 -0
- package/dist/scripts/src/components/Splitter/HSplitter.spec.js +104 -0
- package/dist/scripts/src/components/Splitter/Splitter.spec.js +543 -0
- package/dist/scripts/src/components/Splitter/VSplitter.spec.js +104 -0
- package/dist/scripts/src/components/Stack/CHStack.spec.js +86 -0
- package/dist/scripts/src/components/Stack/CVStack.spec.js +86 -0
- package/dist/scripts/src/components/Stack/HStack.spec.js +67 -0
- package/dist/scripts/src/components/Stack/Stack.spec.js +654 -0
- package/dist/scripts/src/components/Stack/VStack.spec.js +67 -0
- package/dist/scripts/src/components/Switch/Switch.spec.js +829 -0
- package/dist/scripts/src/components/Table/Table.js +7 -1
- package/dist/scripts/src/components/Table/Table.spec.js +555 -0
- package/dist/scripts/src/components/Table/TableNative.js +4 -1
- package/dist/scripts/src/components/Table/doc-resources/list-component-data.js +53 -0
- package/dist/scripts/src/components/Table/useRowSelection.js +215 -1
- package/dist/scripts/src/components/TableOfContents/TableOfContents.spec.js +838 -0
- package/dist/scripts/src/components/Tabs/Tabs.spec.js +875 -0
- package/dist/scripts/src/components/Text/Text.spec.js +1075 -0
- package/dist/scripts/src/components/TextArea/TextArea.spec.js +714 -0
- package/dist/scripts/src/components/TextBox/TextBox.js +1 -5
- package/dist/scripts/src/components/TextBox/TextBox.spec.js +687 -0
- package/dist/scripts/src/components/TextBox/TextBoxNative.js +10 -15
- package/dist/scripts/src/components/Theme/Theme.spec.js +124 -0
- package/dist/scripts/src/components/Theme/ThemeNative.js +2 -6
- package/dist/scripts/src/components/TimeInput/TimeInput.js +1 -5
- package/dist/scripts/src/components/TimeInput/TimeInput.spec.js +1122 -0
- package/dist/scripts/src/components/TimeInput/TimeInputNative.js +2 -9
- package/dist/scripts/src/components/Timer/Timer.spec.js +358 -0
- package/dist/scripts/src/components/ToneChangerButton/ToneChangerButton.spec.js +414 -0
- package/dist/scripts/src/components/ToneSwitch/ToneSwitch.spec.js +89 -0
- package/dist/scripts/src/components/Tooltip/Tooltip.spec.js +418 -0
- package/dist/scripts/src/components/chart-color-schemes.js +43 -0
- package/dist/scripts/src/components-core/ApiBoundComponent.js +38 -24
- package/dist/scripts/src/components-core/CompoundComponent.js +1 -1
- package/dist/scripts/src/components-core/RestApiProxy.js +84 -8
- package/dist/scripts/src/components-core/behaviors/BehaviorContext.js +54 -0
- package/dist/scripts/src/components-core/behaviors/CoreBehaviors.js +80 -0
- package/dist/scripts/src/components-core/descriptorHelper.js +1 -0
- package/dist/scripts/src/components-core/devtools/InspectorDialogVisibilityContext.js +8 -0
- package/dist/scripts/src/components-core/parts.js +4 -1
- package/dist/scripts/src/components-core/renderers.js +31 -0
- package/dist/scripts/src/components-core/rendering/AppRoot.js +2 -1
- package/dist/scripts/src/components-core/rendering/ComponentAdapter.js +31 -46
- package/dist/scripts/src/components-core/rendering/nodeUtils.js +6 -0
- package/dist/scripts/src/components-core/script-runner/simplify-expression.js +386 -0
- package/dist/scripts/src/components-core/theming/component-layout-resolver.js +153 -0
- package/dist/scripts/src/components-core/theming/layout-resolver.js +2 -0
- package/dist/scripts/src/components-core/theming/parse-layout-props.js +98 -0
- package/dist/scripts/src/components-core/theming/themes/solid.js +16 -0
- package/dist/scripts/src/components-core/utils/audio-utils.js +83 -0
- package/dist/scripts/src/index-standalone.js +61 -0
- package/dist/scripts/src/index.js +39 -1
- package/dist/scripts/src/language-server/server-common.js +151 -0
- package/dist/scripts/src/language-server/server-web-worker.js +47 -0
- package/dist/scripts/src/language-server/server.js +42 -0
- package/dist/scripts/src/language-server/services/common/docs-generation.js +73 -0
- package/dist/scripts/src/language-server/services/common/lsp-utils.js +9 -0
- package/dist/scripts/src/language-server/services/common/syntax-node-utilities.js +135 -0
- package/dist/scripts/src/language-server/services/completion.js +270 -0
- package/dist/scripts/src/language-server/services/diagnostic.js +19 -0
- package/dist/scripts/src/language-server/services/format.js +430 -0
- package/dist/scripts/src/language-server/services/hover.js +164 -0
- package/dist/scripts/src/language-server/xmlui-metadata-generated.mjs +16266 -0
- package/dist/scripts/src/logging/xmlui.js +21 -0
- package/dist/scripts/src/parsers/common/utils.js +19 -0
- package/dist/scripts/src/syntax/monaco/grammar.monacoLanguage.js +286 -0
- package/dist/scripts/src/syntax/monaco/index.js +14 -0
- package/dist/scripts/src/syntax/monaco/xmlui-dark.js +25 -0
- package/dist/scripts/src/syntax/monaco/xmlui-light.js +25 -0
- package/dist/scripts/src/syntax/monaco/xmluiscript.monacoLanguage.js +310 -0
- package/dist/scripts/src/syntax/textMate/index.js +14 -0
- package/dist/scripts/src/syntax/textMate/xmlui-dark.json +631 -0
- package/dist/scripts/src/syntax/textMate/xmlui-light.json +565 -0
- package/dist/scripts/src/syntax/textMate/xmlui.json +564 -0
- package/dist/scripts/src/syntax/textMate/xmlui.tmLanguage.json +341 -0
- package/dist/scripts/src/testing/ComponentDrivers.js +1327 -0
- package/dist/scripts/src/testing/assertions.js +444 -0
- package/dist/scripts/src/testing/component-test-helpers.js +389 -0
- package/dist/scripts/src/testing/drivers/DateInputDriver.js +19 -0
- package/dist/scripts/src/testing/drivers/ModalDialogDriver.js +10 -0
- package/dist/scripts/src/testing/drivers/NumberBoxDriver.js +44 -0
- package/dist/scripts/src/testing/drivers/SliderDriver.js +20 -0
- package/dist/scripts/src/testing/drivers/TextBoxDriver.js +20 -0
- package/dist/scripts/src/testing/drivers/TimeInputDriver.js +22 -0
- package/dist/scripts/src/testing/drivers/TimerDriver.js +64 -0
- package/dist/scripts/src/testing/fixtures.js +513 -0
- package/dist/scripts/src/testing/infrastructure/TestBed.js +17 -0
- package/dist/scripts/src/testing/infrastructure/main.js +9 -0
- package/dist/scripts/src/testing/infrastructure/public/mockServiceWorker.js +266 -0
- package/dist/scripts/src/testing/themed-app-test-helpers.js +139 -0
- package/dist/standalone/xmlui-standalone.es.d.ts +172 -10
- package/dist/standalone/xmlui-standalone.umd.js +36 -36
- 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
|
+
});
|