xmlui 0.10.25 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/{index-CCEPGw_x.mjs → index-CEq6OdjV.js} +6186 -6523
- package/dist/lib/index.css +1 -1
- package/dist/lib/{initMock-DFcCR7ey.mjs → initMock-DhUnLKrR.js} +1 -1
- package/dist/lib/{language-server-web-worker.mjs → language-server-web-worker.js} +1 -1
- package/dist/lib/{language-server.mjs → language-server.js} +1 -1
- package/dist/lib/{metadata-utils-Dx-2qZBh.mjs → metadata-utils-D27cn-XB.js} +7 -7
- package/dist/lib/{server-common--BHVvP1o.mjs → server-common-2DaoOOL5.js} +625 -616
- package/dist/lib/testing.d.ts +2011 -0
- package/dist/lib/testing.js +2386 -0
- package/dist/lib/vite-xmlui-plugin/index.js +13968 -0
- package/dist/lib/vite-xmlui-plugin/package.json +3 -0
- package/dist/lib/xmlui-parser-BZZ430Wm.js +523 -0
- package/dist/lib/xmlui-parser.d.ts +2 -1
- package/dist/lib/{xmlui-parser.mjs → xmlui-parser.js} +2 -2
- package/dist/lib/{xmlui-serializer-uCYa8_tZ.mjs → xmlui-serializer-D9D2mQ8m.js} +1 -1
- package/dist/lib/xmlui.d.ts +1 -0
- package/dist/lib/{xmlui.mjs → xmlui.js} +24 -23
- package/dist/metadata/{collectedComponentMetadata-mwkNkxN_.mjs → collectedComponentMetadata-BAI5eK2v.js} +13057 -12883
- package/dist/metadata/{initMock-BVxHA6wu.mjs → initMock-CekNG5Ax.js} +1 -1
- package/dist/metadata/style.css +1 -1
- package/dist/metadata/{xmlui-metadata.mjs → xmlui-metadata.js} +1 -1
- package/dist/metadata/xmlui-metadata.umd.cjs +207 -0
- package/dist/scripts/bin/bootstrap.cjs +4 -0
- package/dist/scripts/bin/index.js +85 -13
- package/dist/scripts/package.json +30 -22
- package/dist/scripts/src/components/App/App.spec.js +127 -15
- package/dist/scripts/src/components/App/AppNative.js +13 -2
- package/dist/scripts/src/components/AppHeader/AppHeader.js +1 -6
- package/dist/scripts/src/components/AppHeader/AppHeaderNative.js +6 -7
- package/dist/scripts/src/components/Avatar/Avatar.spec.js +0 -29
- package/dist/scripts/src/components/Button/Button.spec.js +0 -29
- package/dist/scripts/src/components/Charts/BarChart/BarChartNative.js +2 -0
- package/dist/scripts/src/components/Charts/LineChart/LineChartNative.js +2 -2
- package/dist/scripts/src/components/Charts/Tooltip/TooltipContent.spec.js +8 -6
- package/dist/scripts/src/components/Form/Form.js +19 -0
- package/dist/scripts/src/components/Form/Form.spec.js +444 -0
- package/dist/scripts/src/components/Form/FormNative.js +46 -15
- package/dist/scripts/src/components/Form/formActions.js +3 -2
- package/dist/scripts/src/components/FormItem/FormItem.js +10 -2
- package/dist/scripts/src/components/FormItem/FormItem.spec.js +159 -0
- package/dist/scripts/src/components/FormItem/FormItemNative.js +6 -5
- package/dist/scripts/src/components/Heading/Heading.js +45 -5
- package/dist/scripts/src/components/Heading/Heading.spec.js +116 -47
- package/dist/scripts/src/components/Queue/Queue.js +1 -16
- package/dist/scripts/src/components/Queue/QueueNative.js +60 -2
- package/dist/scripts/src/components/TableOfContents/TableOfContents.js +7 -5
- package/dist/scripts/src/components-core/appContext/misc-utils.js +2 -1
- package/dist/scripts/src/components-core/devtools/InspectorDialog.js +2 -2
- package/dist/scripts/src/components-core/rendering/valueExtractor.js +9 -1
- package/dist/scripts/src/components-core/script-runner/eval-tree-async.js +2 -0
- package/dist/scripts/src/components-core/utils/base64-utils.js +2 -0
- package/dist/scripts/src/components-core/utils/extractParam.js +2 -1
- package/dist/scripts/src/components-core/utils/misc.js +44 -0
- package/dist/scripts/src/language-server/server-common.js +2 -2
- package/dist/scripts/src/language-server/{xmlui-metadata-generated.mjs → xmlui-metadata-generated.js} +625 -615
- package/dist/scripts/src/testing/drivers/index.js +9 -0
- package/dist/scripts/src/testing/index.js +69 -0
- package/dist/standalone/xmlui-standalone.es.d.ts +32 -16
- package/dist/standalone/xmlui-standalone.umd.js +36 -36
- package/package.json +45 -37
- package/dist/metadata/xmlui-metadata.umd.js +0 -207
- package/dist/scripts/bin/bootstrap.js +0 -11
- /package/dist/lib/{apiInterceptorWorker-QiltRtq1.mjs → apiInterceptorWorker-QiltRtq1.js} +0 -0
- /package/dist/lib/{syntax-monaco.mjs → syntax-monaco.js} +0 -0
- /package/dist/lib/{syntax-textmate.mjs → syntax-textmate.js} +0 -0
- /package/dist/lib/{transform-Tooy42EB.mjs → transform-Tooy42EB.js} +0 -0
- /package/dist/metadata/{apiInterceptorWorker-Dql7QGw2.mjs → apiInterceptorWorker-Dql7QGw2.js} +0 -0
|
@@ -260,6 +260,7 @@ function BarChart({ data = [], layout = exports.defaultProps.layout, nameKey, st
|
|
|
260
260
|
height: miniMode || hideX ? 0 : xAxisHeight,
|
|
261
261
|
tick: miniMode || hideTickX ? false : { fill: "currentColor", fontSize },
|
|
262
262
|
tickFormatter: miniMode || hideTickX ? undefined : tickFormatterX,
|
|
263
|
+
domain: [0, (dataMax) => dataMax * 1.05],
|
|
263
264
|
}
|
|
264
265
|
: {
|
|
265
266
|
type: "category",
|
|
@@ -292,6 +293,7 @@ function BarChart({ data = [], layout = exports.defaultProps.layout, nameKey, st
|
|
|
292
293
|
tickCount: yTickCount,
|
|
293
294
|
tickFormatter: miniMode || hideTickY ? undefined : tickFormatterY,
|
|
294
295
|
width: miniMode || hideY ? 0 : yAxisWidth,
|
|
296
|
+
domain: [0, (dataMax) => dataMax * 1.1],
|
|
295
297
|
};
|
|
296
298
|
return ((0, jsx_runtime_1.jsxs)(ChartProvider_1.default, { value: chartContextValue, children: [children, (0, jsx_runtime_1.jsx)("div", { ref: labelsRef, style: { position: "absolute", visibility: "hidden", height: 0, overflow: "hidden" }, children: validData
|
|
297
299
|
.map((d) => d[nameKey])
|
|
@@ -123,7 +123,7 @@ exports.LineChart = (0, react_1.forwardRef)(function LineChart({ data, dataKeys
|
|
|
123
123
|
payloadArray.push({
|
|
124
124
|
label: dataKey,
|
|
125
125
|
value: originalPayload[dataKey],
|
|
126
|
-
color: colorValues[index] || colorValues[0]
|
|
126
|
+
color: colorValues[index] || colorValues[0],
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
129
|
});
|
|
@@ -181,7 +181,7 @@ exports.LineChart = (0, react_1.forwardRef)(function LineChart({ data, dataKeys
|
|
|
181
181
|
? safeData
|
|
182
182
|
.map((d) => d === null || d === void 0 ? void 0 : d[nameKey])
|
|
183
183
|
.map((label, idx) => ((0, jsx_runtime_1.jsx)("span", { style: { fontSize: 12, whiteSpace: "nowrap" }, children: label }, idx)))
|
|
184
|
-
: null }), (0, jsx_runtime_1.jsx)("div", { ref: forwardedRef, className: (0, classnames_1.default)(className, LineChart_module_scss_1.default.wrapper), style: Object.assign({ flexGrow: 1 }, style), children: (0, jsx_runtime_1.jsx)(recharts_1.ResponsiveContainer, { ref: containerRef, width: "100%", height: "100%", minWidth: 60, minHeight: 30, debounce: 100, children: (0, jsx_runtime_1.jsxs)(recharts_1.LineChart, { accessibilityLayer: true, data: data, margin: miniMode ? { left: 0, right: 0, top: 0, bottom: 0 } : chartMargin, children: [(0, jsx_runtime_1.jsx)(recharts_1.XAxis, { interval: interval, tickLine: false, dataKey: nameKey, angle: tickAngle, textAnchor: tickAnchor, tick: miniMode ? false : !hideTickX && { fill: "currentColor", fontSize }, tickFormatter: miniMode ? undefined : tickFormatterX, height: miniMode || hideX ? 0 : xAxisHeight, hide: miniMode || hideX }), (0, jsx_runtime_1.jsx)(recharts_1.YAxis, { hide: miniMode || hideY, tickLine: false, tickFormatter: miniMode ? undefined : tickFormatterY, tick: miniMode ? false : !hideTickY && { fill: "currentColor", fontSize } }), !miniMode && !hideTooltip && (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { content: safeTooltipRenderer }), dataKeys.map((dataKey, i) => ((0, jsx_runtime_1.jsx)(recharts_1.Line, { type: "monotone", dataKey: dataKey, name: dataKey, stroke: colorValues[i], strokeWidth: strokeWidth, dot: false }, dataKey))), showLegend && ((0, jsx_runtime_1.jsx)(recharts_1.Legend, { wrapperStyle: {
|
|
184
|
+
: null }), (0, jsx_runtime_1.jsx)("div", { ref: forwardedRef, className: (0, classnames_1.default)(className, LineChart_module_scss_1.default.wrapper), style: Object.assign({ flexGrow: 1 }, style), children: (0, jsx_runtime_1.jsx)(recharts_1.ResponsiveContainer, { ref: containerRef, width: "100%", height: "100%", minWidth: 60, minHeight: 30, debounce: 100, children: (0, jsx_runtime_1.jsxs)(recharts_1.LineChart, { accessibilityLayer: true, data: data, margin: miniMode ? { left: 0, right: 0, top: 0, bottom: 0 } : chartMargin, children: [(0, jsx_runtime_1.jsx)(recharts_1.XAxis, { interval: interval, tickLine: false, dataKey: nameKey, angle: tickAngle, textAnchor: tickAnchor, tick: miniMode ? false : !hideTickX && { fill: "currentColor", fontSize }, tickFormatter: miniMode ? undefined : tickFormatterX, height: miniMode || hideX ? 0 : xAxisHeight, hide: miniMode || hideX }), (0, jsx_runtime_1.jsx)(recharts_1.YAxis, { hide: miniMode || hideY, tickLine: false, tickFormatter: miniMode ? undefined : tickFormatterY, tick: miniMode ? false : !hideTickY && { fill: "currentColor", fontSize }, domain: [(dataMin) => dataMin * 0.95, (dataMax) => dataMax * 1.05] }), !miniMode && !hideTooltip && (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { content: safeTooltipRenderer }), dataKeys.map((dataKey, i) => ((0, jsx_runtime_1.jsx)(recharts_1.Line, { type: "monotone", dataKey: dataKey, name: dataKey, stroke: colorValues[i], strokeWidth: strokeWidth, dot: false }, dataKey))), showLegend && ((0, jsx_runtime_1.jsx)(recharts_1.Legend, { wrapperStyle: {
|
|
185
185
|
bottom: 0,
|
|
186
186
|
left: 0,
|
|
187
187
|
right: 0,
|
|
@@ -266,10 +266,10 @@ fixtures_1.test.describe("Basic Functionality", () => {
|
|
|
266
266
|
const indicator = page.locator(tooltipIndicatorSelector);
|
|
267
267
|
yield (0, fixtures_1.expect)(indicator).toBeVisible();
|
|
268
268
|
// Indicator should have background color
|
|
269
|
-
const backgroundColor = yield indicator.evaluate(el => window.getComputedStyle(el).backgroundColor);
|
|
269
|
+
const backgroundColor = yield indicator.evaluate((el) => window.getComputedStyle(el).backgroundColor);
|
|
270
270
|
(0, fixtures_1.expect)(backgroundColor).not.toBe("rgba(0, 0, 0, 0)"); // Not transparent
|
|
271
271
|
}));
|
|
272
|
-
(0, fixtures_1.test)("applies consistent styling across different chart types", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
272
|
+
(0, fixtures_1.test)("applies consistent styling across different chart types", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, }) {
|
|
273
273
|
// Test in LineChart context
|
|
274
274
|
yield initTestBed(`
|
|
275
275
|
<LineChart
|
|
@@ -281,9 +281,11 @@ fixtures_1.test.describe("Basic Functionality", () => {
|
|
|
281
281
|
/>
|
|
282
282
|
`);
|
|
283
283
|
yield page.waitForSelector(chartRoot, { timeout: 10000 });
|
|
284
|
-
// Hover over
|
|
285
|
-
const
|
|
286
|
-
yield
|
|
284
|
+
// Hover over chart area to trigger tooltip (Recharts tooltip activates on chart area, not just line)
|
|
285
|
+
const chartSvg = page.locator(".recharts-surface").first();
|
|
286
|
+
yield chartSvg.hover({ position: { x: 200, y: 200 } });
|
|
287
|
+
// Wait for tooltip to appear
|
|
288
|
+
yield page.waitForTimeout(500);
|
|
287
289
|
yield (0, fixtures_1.expect)(page.locator(tooltipContentSelector)).toBeVisible();
|
|
288
290
|
// Should have consistent styling
|
|
289
291
|
const indicator = page.locator(tooltipIndicatorSelector);
|
|
@@ -337,7 +339,7 @@ fixtures_1.test.describe("Accessibility", () => {
|
|
|
337
339
|
yield (0, fixtures_1.expect)(valueText).toHaveCSS("font-size", /\d+px/);
|
|
338
340
|
// Should have proper contrast (background vs text)
|
|
339
341
|
const tooltipContainer = page.locator(tooltipContentSelector);
|
|
340
|
-
const backgroundColor = yield tooltipContainer.evaluate(el => window.getComputedStyle(el).backgroundColor);
|
|
342
|
+
const backgroundColor = yield tooltipContainer.evaluate((el) => window.getComputedStyle(el).backgroundColor);
|
|
341
343
|
(0, fixtures_1.expect)(backgroundColor).not.toBe("transparent");
|
|
342
344
|
}));
|
|
343
345
|
(0, fixtures_1.test)("tooltip appears on keyboard navigation", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
@@ -78,6 +78,17 @@ exports.FormMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
78
78
|
type: "boolean",
|
|
79
79
|
defaultValue: FormNative_1.defaultProps.hideButtonRowUntilDirty,
|
|
80
80
|
},
|
|
81
|
+
hideButtonRow: {
|
|
82
|
+
description: `This property hides the button row entirely when set to true.`,
|
|
83
|
+
type: "boolean",
|
|
84
|
+
defaultValue: FormNative_1.defaultProps.hideButtonRow,
|
|
85
|
+
},
|
|
86
|
+
enableSubmit: {
|
|
87
|
+
description: `This property controls whether the submit button is enabled. When set to false, ` +
|
|
88
|
+
`the submit button is disabled and the form cannot be submitted.`,
|
|
89
|
+
type: "boolean",
|
|
90
|
+
defaultValue: FormNative_1.defaultProps.enableSubmit,
|
|
91
|
+
},
|
|
81
92
|
submitUrl: (0, metadata_helpers_1.d)(`URL to submit the form data.`),
|
|
82
93
|
submitMethod: {
|
|
83
94
|
description: "This property sets the HTTP method to use when submitting the form data. If not " +
|
|
@@ -117,6 +128,14 @@ exports.FormMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
117
128
|
data: "An object containing the form data to update.",
|
|
118
129
|
},
|
|
119
130
|
},
|
|
131
|
+
validate: {
|
|
132
|
+
description: "This method triggers validation on all form fields without submitting the form. " +
|
|
133
|
+
"It displays validation errors and returns the validation result along with the cleaned form data. " +
|
|
134
|
+
"This is useful for implementing custom submit buttons or performing operations that require " +
|
|
135
|
+
"validated data without actually submitting the form.",
|
|
136
|
+
signature: "validate(): Promise<{ isValid: boolean, data: Record<string, any>, errors: ValidationResult[], warnings: ValidationResult[], validationResults: Record<string, ValidationResult> }>",
|
|
137
|
+
returns: "A promise that resolves to an object containing validation status, cleaned data, and detailed validation results.",
|
|
138
|
+
},
|
|
120
139
|
},
|
|
121
140
|
themeVars: (0, themeVars_1.parseScssVar)(Form_module_scss_1.default.themeVars),
|
|
122
141
|
defaultThemeVars: {
|
|
@@ -97,6 +97,334 @@ fixtures_1.test.describe("Basic Functionality", () => {
|
|
|
97
97
|
yield (0, fixtures_1.expect)(buttons.last()).toHaveText("Cancel");
|
|
98
98
|
}));
|
|
99
99
|
// =============================================================================
|
|
100
|
+
// HIDE BUTTON ROW TESTS
|
|
101
|
+
// =============================================================================
|
|
102
|
+
fixtures_1.test.describe("hideButtonRow property", () => {
|
|
103
|
+
(0, fixtures_1.test)("hides button row when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
104
|
+
yield initTestBed(`<Form hideButtonRow="true"/>`);
|
|
105
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
|
|
106
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
107
|
+
}));
|
|
108
|
+
(0, fixtures_1.test)("shows button row when set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
109
|
+
yield initTestBed(`<Form hideButtonRow="false"/>`);
|
|
110
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
111
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
112
|
+
}));
|
|
113
|
+
(0, fixtures_1.test)("shows button row by default when property not set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
114
|
+
yield initTestBed(`<Form/>`);
|
|
115
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
116
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
117
|
+
}));
|
|
118
|
+
(0, fixtures_1.test)("hides custom button row template when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
119
|
+
yield initTestBed(`
|
|
120
|
+
<Form hideButtonRow="true">
|
|
121
|
+
<property name="buttonRowTemplate">
|
|
122
|
+
<Button label="Custom Save" type="submit" testId="customSave" />
|
|
123
|
+
<Button label="Custom Cancel" type="button" testId="customCancel" />
|
|
124
|
+
</property>
|
|
125
|
+
</Form>
|
|
126
|
+
`);
|
|
127
|
+
yield (0, fixtures_1.expect)(page.getByTestId("customSave")).not.toBeVisible();
|
|
128
|
+
yield (0, fixtures_1.expect)(page.getByTestId("customCancel")).not.toBeVisible();
|
|
129
|
+
}));
|
|
130
|
+
(0, fixtures_1.test)("overrides hideButtonRowUntilDirty when both are set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
131
|
+
yield initTestBed(`
|
|
132
|
+
<Form hideButtonRow="true" hideButtonRowUntilDirty="true">
|
|
133
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
134
|
+
</Form>
|
|
135
|
+
`);
|
|
136
|
+
// Button row should be hidden even before making changes
|
|
137
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
138
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
|
|
139
|
+
// Make the form dirty
|
|
140
|
+
const driver = yield createFormItemDriver("nameField");
|
|
141
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
142
|
+
yield input.field.fill("John");
|
|
143
|
+
// Button row should still be hidden even after making changes
|
|
144
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
145
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
|
|
146
|
+
}));
|
|
147
|
+
(0, fixtures_1.test)("handles null value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
148
|
+
yield initTestBed(`<Form hideButtonRow="{null}"/>`);
|
|
149
|
+
// Should show button row (default behavior)
|
|
150
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
151
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
152
|
+
}));
|
|
153
|
+
(0, fixtures_1.test)("handles undefined value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
154
|
+
yield initTestBed(`<Form hideButtonRow="{undefined}"/>`);
|
|
155
|
+
// Should show button row (default behavior)
|
|
156
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
157
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
158
|
+
}));
|
|
159
|
+
(0, fixtures_1.test)("handles string 'true' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
160
|
+
yield initTestBed(`<Form hideButtonRow="true"/>`);
|
|
161
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
|
|
162
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
163
|
+
}));
|
|
164
|
+
(0, fixtures_1.test)("handles string 'false' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
165
|
+
yield initTestBed(`<Form hideButtonRow="false"/>`);
|
|
166
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
167
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
168
|
+
}));
|
|
169
|
+
(0, fixtures_1.test)("form submission still works with hidden button row via external submit", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
170
|
+
const { testStateDriver } = yield initTestBed(`
|
|
171
|
+
<Fragment>
|
|
172
|
+
<Form id="testForm" hideButtonRow="true" onSubmit="arg => testState = arg">
|
|
173
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
174
|
+
<Button type="submit" label="External Submit" testId="externalSubmit" />
|
|
175
|
+
</Form>
|
|
176
|
+
</Fragment>
|
|
177
|
+
`);
|
|
178
|
+
const driver = yield createFormItemDriver("nameField");
|
|
179
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
180
|
+
yield input.field.fill("John Doe");
|
|
181
|
+
yield page.getByTestId("externalSubmit").click();
|
|
182
|
+
const submittedData = yield testStateDriver.testState();
|
|
183
|
+
(0, fixtures_1.expect)(submittedData).toEqual({ name: "John Doe" });
|
|
184
|
+
}));
|
|
185
|
+
});
|
|
186
|
+
// =============================================================================
|
|
187
|
+
// HIDE BUTTON ROW UNTIL DIRTY TESTS
|
|
188
|
+
// =============================================================================
|
|
189
|
+
fixtures_1.test.describe("hideButtonRowUntilDirty property", () => {
|
|
190
|
+
(0, fixtures_1.test)("hides button row initially when form is not dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
191
|
+
yield initTestBed(`
|
|
192
|
+
<Form hideButtonRowUntilDirty="true">
|
|
193
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
194
|
+
</Form>
|
|
195
|
+
`);
|
|
196
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).not.toBeVisible();
|
|
197
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
198
|
+
}));
|
|
199
|
+
(0, fixtures_1.test)("shows button row when form becomes dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
200
|
+
yield initTestBed(`
|
|
201
|
+
<Form hideButtonRowUntilDirty="true">
|
|
202
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
203
|
+
</Form>
|
|
204
|
+
`);
|
|
205
|
+
// Initially hidden
|
|
206
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
207
|
+
// Make form dirty
|
|
208
|
+
const driver = yield createFormItemDriver("nameField");
|
|
209
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
210
|
+
yield input.field.fill("John");
|
|
211
|
+
// Now visible
|
|
212
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
213
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
214
|
+
}));
|
|
215
|
+
(0, fixtures_1.test)("keeps button row visible after form becomes dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
216
|
+
yield initTestBed(`
|
|
217
|
+
<Form hideButtonRowUntilDirty="true">
|
|
218
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
219
|
+
</Form>
|
|
220
|
+
`);
|
|
221
|
+
const driver = yield createFormItemDriver("nameField");
|
|
222
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
223
|
+
// Make form dirty
|
|
224
|
+
yield input.field.fill("John");
|
|
225
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
226
|
+
// Clear the input (form is still dirty)
|
|
227
|
+
yield input.field.clear();
|
|
228
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
229
|
+
}));
|
|
230
|
+
(0, fixtures_1.test)("shows button row by default when property set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, }) {
|
|
231
|
+
yield initTestBed(`
|
|
232
|
+
<Form hideButtonRowUntilDirty="false">
|
|
233
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
234
|
+
</Form>
|
|
235
|
+
`);
|
|
236
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
237
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
238
|
+
}));
|
|
239
|
+
(0, fixtures_1.test)("shows button row by default when property not set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
240
|
+
yield initTestBed(`
|
|
241
|
+
<Form>
|
|
242
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
243
|
+
</Form>
|
|
244
|
+
`);
|
|
245
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
246
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
247
|
+
}));
|
|
248
|
+
(0, fixtures_1.test)("works with multiple form items", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
249
|
+
yield initTestBed(`
|
|
250
|
+
<Form hideButtonRowUntilDirty="true">
|
|
251
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
252
|
+
<FormItem label="Email" bindTo="email" testId="emailField" />
|
|
253
|
+
</Form>
|
|
254
|
+
`);
|
|
255
|
+
// Initially hidden
|
|
256
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
257
|
+
// Modify second field
|
|
258
|
+
const emailDriver = yield createFormItemDriver("emailField");
|
|
259
|
+
const emailInput = yield createTextBoxDriver(emailDriver.input);
|
|
260
|
+
yield emailInput.field.fill("test@example.com");
|
|
261
|
+
// Now visible
|
|
262
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
263
|
+
}));
|
|
264
|
+
(0, fixtures_1.test)("hides custom button row template until dirty", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
265
|
+
yield initTestBed(`
|
|
266
|
+
<Form hideButtonRowUntilDirty="true">
|
|
267
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
268
|
+
<property name="buttonRowTemplate">
|
|
269
|
+
<Button label="Custom Save" type="submit" testId="customSave" />
|
|
270
|
+
</property>
|
|
271
|
+
</Form>
|
|
272
|
+
`);
|
|
273
|
+
// Initially hidden
|
|
274
|
+
yield (0, fixtures_1.expect)(page.getByTestId("customSave")).not.toBeVisible();
|
|
275
|
+
// Make form dirty
|
|
276
|
+
const driver = yield createFormItemDriver("nameField");
|
|
277
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
278
|
+
yield input.field.fill("John");
|
|
279
|
+
// Now visible
|
|
280
|
+
yield (0, fixtures_1.expect)(page.getByTestId("customSave")).toBeVisible();
|
|
281
|
+
}));
|
|
282
|
+
(0, fixtures_1.test)("handles null value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
283
|
+
yield initTestBed(`
|
|
284
|
+
<Form hideButtonRowUntilDirty="{null}">
|
|
285
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
286
|
+
</Form>
|
|
287
|
+
`);
|
|
288
|
+
// Should show button row (default behavior)
|
|
289
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
290
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
291
|
+
}));
|
|
292
|
+
(0, fixtures_1.test)("handles undefined value gracefully", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
293
|
+
yield initTestBed(`
|
|
294
|
+
<Form hideButtonRowUntilDirty="{undefined}">
|
|
295
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
296
|
+
</Form>
|
|
297
|
+
`);
|
|
298
|
+
// Should show button row (default behavior)
|
|
299
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Cancel" })).toBeVisible();
|
|
300
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
301
|
+
}));
|
|
302
|
+
(0, fixtures_1.test)("works with form initialized with data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
303
|
+
yield initTestBed(`
|
|
304
|
+
<Form hideButtonRowUntilDirty="true" data="{{ name: 'Initial' }}">
|
|
305
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
306
|
+
</Form>
|
|
307
|
+
`);
|
|
308
|
+
// Initially hidden (form has data but is not dirty)
|
|
309
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
310
|
+
// Make form dirty
|
|
311
|
+
const driver = yield createFormItemDriver("nameField");
|
|
312
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
313
|
+
yield input.field.fill("Modified");
|
|
314
|
+
// Now visible
|
|
315
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
316
|
+
}));
|
|
317
|
+
(0, fixtures_1.test)("button row appears when checkbox is checked", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
318
|
+
yield initTestBed(`
|
|
319
|
+
<Form hideButtonRowUntilDirty="true">
|
|
320
|
+
<FormItem label="Accept Terms" bindTo="terms" type="checkbox" />
|
|
321
|
+
</Form>
|
|
322
|
+
`);
|
|
323
|
+
// Initially hidden
|
|
324
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
325
|
+
// Check the checkbox
|
|
326
|
+
const checkbox = page.getByRole("checkbox");
|
|
327
|
+
yield checkbox.check();
|
|
328
|
+
// Now visible
|
|
329
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
330
|
+
}));
|
|
331
|
+
(0, fixtures_1.test)("button row appears when slider value changes", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
332
|
+
yield initTestBed(`
|
|
333
|
+
<Form hideButtonRowUntilDirty="true">
|
|
334
|
+
<FormItem label="Volume" bindTo="volume" type="slider" testId="volumeField" />
|
|
335
|
+
</Form>
|
|
336
|
+
`);
|
|
337
|
+
// Initially hidden
|
|
338
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).not.toBeVisible();
|
|
339
|
+
// Move the slider using keyboard
|
|
340
|
+
const slider = page.getByRole("slider");
|
|
341
|
+
yield slider.press("ArrowRight");
|
|
342
|
+
// Now visible
|
|
343
|
+
yield (0, fixtures_1.expect)(page.getByRole("button", { name: "Save" })).toBeVisible();
|
|
344
|
+
}));
|
|
345
|
+
});
|
|
346
|
+
// =============================================================================
|
|
347
|
+
// ENABLE SUBMIT PROPERTY TESTS
|
|
348
|
+
// =============================================================================
|
|
349
|
+
fixtures_1.test.describe("enableSubmit property", () => {
|
|
350
|
+
(0, fixtures_1.test)("disables submit button when set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
351
|
+
yield initTestBed(`<Form enableSubmit="false"/>`);
|
|
352
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
353
|
+
yield (0, fixtures_1.expect)(saveButton).toBeVisible();
|
|
354
|
+
yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
|
|
355
|
+
}));
|
|
356
|
+
(0, fixtures_1.test)("enables submit button when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
357
|
+
yield initTestBed(`<Form enableSubmit="true"/>`);
|
|
358
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
359
|
+
yield (0, fixtures_1.expect)(saveButton).toBeVisible();
|
|
360
|
+
yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
|
|
361
|
+
}));
|
|
362
|
+
(0, fixtures_1.test)("submit button is enabled by default when property not set", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, }) {
|
|
363
|
+
yield initTestBed(`<Form/>`);
|
|
364
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
365
|
+
yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
|
|
366
|
+
}));
|
|
367
|
+
(0, fixtures_1.test)("prevents form submission when set to false", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
368
|
+
const { testStateDriver } = yield initTestBed(`
|
|
369
|
+
<Form enableSubmit="false" onSubmit="arg => testState = arg">
|
|
370
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
371
|
+
</Form>
|
|
372
|
+
`);
|
|
373
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
374
|
+
yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
|
|
375
|
+
// Verify form does not submit (button is disabled, so click won't work)
|
|
376
|
+
yield saveButton.click({ force: true }); // Force click on disabled button
|
|
377
|
+
// testState should remain null since submit was prevented
|
|
378
|
+
yield fixtures_1.expect.poll(testStateDriver.testState).toBeNull();
|
|
379
|
+
}));
|
|
380
|
+
(0, fixtures_1.test)("allows form submission when set to true", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
381
|
+
const { testStateDriver } = yield initTestBed(`
|
|
382
|
+
<Form enableSubmit="true" onSubmit="arg => testState = arg">
|
|
383
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
384
|
+
</Form>
|
|
385
|
+
`);
|
|
386
|
+
const driver = yield createFormItemDriver("nameField");
|
|
387
|
+
const input = yield createTextBoxDriver(driver.input);
|
|
388
|
+
yield input.field.fill("John Doe");
|
|
389
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
390
|
+
yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
|
|
391
|
+
yield saveButton.click();
|
|
392
|
+
const submittedData = yield testStateDriver.testState();
|
|
393
|
+
(0, fixtures_1.expect)(submittedData).toEqual({ name: "John Doe" });
|
|
394
|
+
}));
|
|
395
|
+
(0, fixtures_1.test)("handles null value gracefully (defaults to enabled)", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
396
|
+
yield initTestBed(`<Form enableSubmit="{null}"/>`);
|
|
397
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
398
|
+
yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
|
|
399
|
+
}));
|
|
400
|
+
(0, fixtures_1.test)("handles string 'true' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
401
|
+
yield initTestBed(`<Form enableSubmit="true"/>`);
|
|
402
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
403
|
+
yield (0, fixtures_1.expect)(saveButton).toBeEnabled();
|
|
404
|
+
}));
|
|
405
|
+
(0, fixtures_1.test)("handles string 'false' value", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
406
|
+
yield initTestBed(`<Form enableSubmit="false"/>`);
|
|
407
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
408
|
+
yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
|
|
409
|
+
}));
|
|
410
|
+
(0, fixtures_1.test)("does not affect cancel button", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
411
|
+
yield initTestBed(`<Form enableSubmit="false"/>`);
|
|
412
|
+
const cancelButton = page.getByRole("button", { name: "Cancel" });
|
|
413
|
+
yield (0, fixtures_1.expect)(cancelButton).toBeEnabled();
|
|
414
|
+
}));
|
|
415
|
+
(0, fixtures_1.test)("works with custom submit button label", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
416
|
+
yield initTestBed(`<Form enableSubmit="false" saveLabel="Submit Now"/>`);
|
|
417
|
+
const submitButton = page.getByRole("button", { name: "Submit Now" });
|
|
418
|
+
yield (0, fixtures_1.expect)(submitButton).toBeDisabled();
|
|
419
|
+
}));
|
|
420
|
+
(0, fixtures_1.test)("works together with form disabled state", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
421
|
+
yield initTestBed(`<Form enabled="false" enableSubmit="true"/>`);
|
|
422
|
+
const saveButton = page.getByRole("button", { name: "Save" });
|
|
423
|
+
// Form disabled takes precedence
|
|
424
|
+
yield (0, fixtures_1.expect)(saveButton).toBeDisabled();
|
|
425
|
+
}));
|
|
426
|
+
});
|
|
427
|
+
// =============================================================================
|
|
100
428
|
// DATA PROPERTY TESTS
|
|
101
429
|
// =============================================================================
|
|
102
430
|
fixtures_1.test.describe("data property", () => {
|
|
@@ -366,6 +694,122 @@ fixtures_1.test.describe("Basic Functionality", () => {
|
|
|
366
694
|
yield page.getByRole("button", { name: "Reset" }).click();
|
|
367
695
|
yield (0, fixtures_1.expect)(nameInput.field).toHaveValue("Initial");
|
|
368
696
|
}));
|
|
697
|
+
(0, fixtures_1.test)("validate method returns validation results without submitting", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
698
|
+
const { testStateDriver } = yield initTestBed(`
|
|
699
|
+
<Form id="testForm">
|
|
700
|
+
<FormItem label="Name" bindTo="name" required="true" testId="nameField" />
|
|
701
|
+
<FormItem label="Email" bindTo="email" testId="emailField" />
|
|
702
|
+
<Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
|
|
703
|
+
</Form>
|
|
704
|
+
`);
|
|
705
|
+
// Click validate button without filling required field
|
|
706
|
+
yield page.getByTestId("validateBtn").click();
|
|
707
|
+
// Wait for validation to complete
|
|
708
|
+
yield page.waitForTimeout(100);
|
|
709
|
+
const result = yield testStateDriver.testState();
|
|
710
|
+
(0, fixtures_1.expect)(result).toBeTruthy();
|
|
711
|
+
(0, fixtures_1.expect)(result.isValid).toBe(false);
|
|
712
|
+
(0, fixtures_1.expect)(result.errors).toBeDefined();
|
|
713
|
+
(0, fixtures_1.expect)(result.errors.length).toBeGreaterThan(0);
|
|
714
|
+
}));
|
|
715
|
+
(0, fixtures_1.test)("validate method returns isValid true when all validations pass", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
716
|
+
const { testStateDriver } = yield initTestBed(`
|
|
717
|
+
<Form id="testForm">
|
|
718
|
+
<FormItem label="Name" bindTo="name" required="true" testId="nameField" />
|
|
719
|
+
<Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
|
|
720
|
+
</Form>
|
|
721
|
+
`);
|
|
722
|
+
// Fill the required field
|
|
723
|
+
const nameDriver = yield createFormItemDriver("nameField");
|
|
724
|
+
const nameInput = yield createTextBoxDriver(nameDriver.input);
|
|
725
|
+
yield nameInput.field.fill("John Doe");
|
|
726
|
+
// Click validate button
|
|
727
|
+
yield page.getByTestId("validateBtn").click();
|
|
728
|
+
// Wait for validation to complete
|
|
729
|
+
yield page.waitForTimeout(100);
|
|
730
|
+
const result = yield testStateDriver.testState();
|
|
731
|
+
(0, fixtures_1.expect)(result).toBeTruthy();
|
|
732
|
+
(0, fixtures_1.expect)(result.isValid).toBe(true);
|
|
733
|
+
(0, fixtures_1.expect)(result.errors.length).toBe(0);
|
|
734
|
+
}));
|
|
735
|
+
(0, fixtures_1.test)("validate method returns cleaned form data", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
736
|
+
const { testStateDriver } = yield initTestBed(`
|
|
737
|
+
<Form id="testForm">
|
|
738
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
739
|
+
<FormItem label="Age" bindTo="age" type="integer" testId="ageField" />
|
|
740
|
+
<Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
|
|
741
|
+
</Form>
|
|
742
|
+
`);
|
|
743
|
+
// Fill form fields
|
|
744
|
+
const nameDriver = yield createFormItemDriver("nameField");
|
|
745
|
+
const nameInput = yield createTextBoxDriver(nameDriver.input);
|
|
746
|
+
yield nameInput.field.fill("John Doe");
|
|
747
|
+
const ageDriver = yield createFormItemDriver("ageField");
|
|
748
|
+
const ageInput = yield createTextBoxDriver(ageDriver.input);
|
|
749
|
+
yield ageInput.field.fill("30");
|
|
750
|
+
// Click validate button
|
|
751
|
+
yield page.getByTestId("validateBtn").click();
|
|
752
|
+
// Wait for validation to complete
|
|
753
|
+
yield page.waitForTimeout(100);
|
|
754
|
+
const result = yield testStateDriver.testState();
|
|
755
|
+
(0, fixtures_1.expect)(result).toBeTruthy();
|
|
756
|
+
(0, fixtures_1.expect)(result.data).toEqual({ name: "John Doe", age: "30" });
|
|
757
|
+
}));
|
|
758
|
+
(0, fixtures_1.test)("validate method displays validation errors on form", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, }) {
|
|
759
|
+
yield initTestBed(`
|
|
760
|
+
<Form id="testForm">
|
|
761
|
+
<FormItem label="Name" bindTo="name" required="true" testId="nameField" />
|
|
762
|
+
<Button onClick="testForm.validate()" label="Validate" testId="validateBtn" />
|
|
763
|
+
</Form>
|
|
764
|
+
`);
|
|
765
|
+
// Click validate without filling required field
|
|
766
|
+
yield page.getByTestId("validateBtn").click();
|
|
767
|
+
// Validation error should be displayed
|
|
768
|
+
const nameField = page.getByTestId("nameField");
|
|
769
|
+
yield (0, fixtures_1.expect)(nameField).toContainText("This field is required");
|
|
770
|
+
}));
|
|
771
|
+
(0, fixtures_1.test)("validate method does not trigger form submission", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
772
|
+
const { testStateDriver } = yield initTestBed(`
|
|
773
|
+
<Form id="testForm" onSubmit="testState = 'submitted'">
|
|
774
|
+
<FormItem label="Name" bindTo="name" testId="nameField" />
|
|
775
|
+
<Button onClick="testForm.validate()" label="Validate" testId="validateBtn" />
|
|
776
|
+
</Form>
|
|
777
|
+
`);
|
|
778
|
+
// Fill form
|
|
779
|
+
const nameDriver = yield createFormItemDriver("nameField");
|
|
780
|
+
const nameInput = yield createTextBoxDriver(nameDriver.input);
|
|
781
|
+
yield nameInput.field.fill("John");
|
|
782
|
+
// Click validate button
|
|
783
|
+
yield page.getByTestId("validateBtn").click();
|
|
784
|
+
// Wait a bit
|
|
785
|
+
yield page.waitForTimeout(200);
|
|
786
|
+
// testState should remain null (not 'submitted')
|
|
787
|
+
yield fixtures_1.expect.poll(testStateDriver.testState).toBeNull();
|
|
788
|
+
}));
|
|
789
|
+
(0, fixtures_1.test)("validate method returns complete validation results object", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createFormItemDriver, createTextBoxDriver, }) {
|
|
790
|
+
const { testStateDriver } = yield initTestBed(`
|
|
791
|
+
<Form id="testForm">
|
|
792
|
+
<FormItem label="Name" bindTo="name" required="true" testId="nameField" />
|
|
793
|
+
<FormItem label="Email" bindTo="email" testId="emailField" />
|
|
794
|
+
<Button onClick="testState = testForm.validate()" label="Validate" testId="validateBtn" />
|
|
795
|
+
</Form>
|
|
796
|
+
`);
|
|
797
|
+
// Fill only email (name is required)
|
|
798
|
+
const emailDriver = yield createFormItemDriver("emailField");
|
|
799
|
+
const emailInput = yield createTextBoxDriver(emailDriver.input);
|
|
800
|
+
yield emailInput.field.fill("test@example.com");
|
|
801
|
+
// Click validate button
|
|
802
|
+
yield page.getByTestId("validateBtn").click();
|
|
803
|
+
// Wait for validation to complete
|
|
804
|
+
yield page.waitForTimeout(100);
|
|
805
|
+
const result = yield testStateDriver.testState();
|
|
806
|
+
(0, fixtures_1.expect)(result).toBeTruthy();
|
|
807
|
+
(0, fixtures_1.expect)(result.isValid).toBeDefined();
|
|
808
|
+
(0, fixtures_1.expect)(result.data).toBeDefined();
|
|
809
|
+
(0, fixtures_1.expect)(result.errors).toBeDefined();
|
|
810
|
+
(0, fixtures_1.expect)(result.warnings).toBeDefined();
|
|
811
|
+
(0, fixtures_1.expect)(result.validationResults).toBeDefined();
|
|
812
|
+
}));
|
|
369
813
|
});
|
|
370
814
|
// =============================================================================
|
|
371
815
|
// CONTEXT VARIABLE TESTS
|