@akinon/akiform-builder 1.3.0 → 1.3.2
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/cjs/__tests__/akiform-builder.test.js +354 -345
- package/dist/cjs/akiform-builder.d.ts +7 -0
- package/dist/cjs/akiform-builder.d.ts.map +1 -0
- package/dist/cjs/akiform-builder.js +458 -0
- package/dist/cjs/field-builder.d.ts +54 -0
- package/dist/cjs/field-builder.d.ts.map +1 -0
- package/dist/cjs/field-builder.js +153 -0
- package/dist/cjs/i18n/index.d.ts +2 -0
- package/dist/cjs/i18n/index.d.ts.map +1 -0
- package/dist/cjs/i18n/index.js +14 -0
- package/dist/cjs/i18n/translations/en.d.ts +14 -0
- package/dist/cjs/i18n/translations/en.d.ts.map +1 -0
- package/dist/cjs/i18n/translations/en.js +15 -0
- package/dist/cjs/i18n/translations/tr.d.ts +14 -0
- package/dist/cjs/i18n/translations/tr.d.ts.map +1 -0
- package/dist/cjs/i18n/translations/tr.js +15 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +21 -0
- package/dist/cjs/src/akiform-builder.d.ts +1 -1
- package/dist/cjs/src/akiform-builder.d.ts.map +1 -1
- package/dist/cjs/src/akiform-builder.js +1 -1
- package/dist/cjs/src/field-builder.d.ts +3 -3
- package/dist/cjs/src/field-builder.d.ts.map +1 -1
- package/dist/cjs/src/i18n/index.d.ts +4 -1
- package/dist/cjs/src/i18n/index.d.ts.map +1 -1
- package/dist/cjs/src/types.d.ts +4 -4
- package/dist/cjs/src/types.d.ts.map +1 -1
- package/dist/cjs/types.d.ts +106 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +2 -0
- package/dist/esm/__tests__/akiform-builder.test.js +354 -345
- package/dist/esm/akiform-builder.d.ts +7 -0
- package/dist/esm/akiform-builder.d.ts.map +1 -0
- package/dist/esm/akiform-builder.js +455 -0
- package/dist/esm/field-builder.d.ts +54 -0
- package/dist/esm/field-builder.d.ts.map +1 -0
- package/dist/esm/field-builder.js +150 -0
- package/dist/esm/i18n/index.d.ts +2 -0
- package/dist/esm/i18n/index.d.ts.map +1 -0
- package/dist/esm/i18n/index.js +11 -0
- package/dist/esm/i18n/translations/en.d.ts +14 -0
- package/dist/esm/i18n/translations/en.d.ts.map +1 -0
- package/dist/esm/i18n/translations/en.js +13 -0
- package/dist/esm/i18n/translations/tr.d.ts +14 -0
- package/dist/esm/i18n/translations/tr.d.ts.map +1 -0
- package/dist/esm/i18n/translations/tr.js +13 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/src/akiform-builder.d.ts +1 -1
- package/dist/esm/src/akiform-builder.d.ts.map +1 -1
- package/dist/esm/src/akiform-builder.js +1 -1
- package/dist/esm/src/field-builder.d.ts +3 -3
- package/dist/esm/src/field-builder.d.ts.map +1 -1
- package/dist/esm/src/i18n/index.d.ts +4 -1
- package/dist/esm/src/i18n/index.d.ts.map +1 -1
- package/dist/esm/src/types.d.ts +4 -4
- package/dist/esm/src/types.d.ts.map +1 -1
- package/dist/esm/types.d.ts +106 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +1 -0
- package/package.json +9 -9
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
11
|
import { useController } from '@akinon/akiform';
|
|
3
12
|
import { akival } from '@akinon/akival';
|
|
@@ -10,13 +19,13 @@ describe('AkiformBuilder', () => {
|
|
|
10
19
|
const mockOnSubmit = vi.fn();
|
|
11
20
|
const mockOnReset = vi.fn();
|
|
12
21
|
const mockOnValueChange = vi.fn();
|
|
13
|
-
const expandCollapsable =
|
|
22
|
+
const expandCollapsable = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
23
|
const user = userEvent.setup();
|
|
15
|
-
const expandIcons = (
|
|
24
|
+
const expandIcons = (yield screen.findAllByRole('button')).filter(el => el.className.includes('akinon-collapse-expand-icon'));
|
|
16
25
|
for (const expandIcon of expandIcons) {
|
|
17
|
-
|
|
26
|
+
yield user.click(expandIcon);
|
|
18
27
|
}
|
|
19
|
-
};
|
|
28
|
+
});
|
|
20
29
|
const defaultFields = [
|
|
21
30
|
{
|
|
22
31
|
key: 'name',
|
|
@@ -36,11 +45,11 @@ describe('AkiformBuilder', () => {
|
|
|
36
45
|
vi.clearAllMocks();
|
|
37
46
|
});
|
|
38
47
|
describe('AkiformBuilder in uncontrolled mode', () => {
|
|
39
|
-
it('renders form fields correctly',
|
|
48
|
+
it('renders form fields correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
49
|
const newDefaultFields = defaultFields.map((field, key) => (Object.assign(Object.assign({}, field), { help: `Description text ${key}`, labelDescription: `Label description text ${key}` })));
|
|
41
|
-
|
|
50
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
51
|
render(React.createElement(AkiformBuilder, { fields: newDefaultFields, onSubmit: mockOnSubmit }));
|
|
43
|
-
});
|
|
52
|
+
}));
|
|
44
53
|
for (const field of newDefaultFields) {
|
|
45
54
|
if (field.label) {
|
|
46
55
|
expect(screen.getByText(field.label)).toBeInTheDocument();
|
|
@@ -51,8 +60,8 @@ describe('AkiformBuilder', () => {
|
|
|
51
60
|
expect(screen.getByText(field.help)).toBeInTheDocument();
|
|
52
61
|
expect(screen.getByText(field.labelDescription)).toBeInTheDocument();
|
|
53
62
|
}
|
|
54
|
-
});
|
|
55
|
-
it('renders form fields correctly with row and column fields',
|
|
63
|
+
}));
|
|
64
|
+
it('renders form fields correctly with row and column fields', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
65
|
const newDefaultFields = [
|
|
57
66
|
{
|
|
58
67
|
type: 'row',
|
|
@@ -118,9 +127,9 @@ describe('AkiformBuilder', () => {
|
|
|
118
127
|
]
|
|
119
128
|
}
|
|
120
129
|
];
|
|
121
|
-
|
|
130
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
122
131
|
render(React.createElement(AkiformBuilder, { fields: newDefaultFields, onSubmit: mockOnSubmit }));
|
|
123
|
-
});
|
|
132
|
+
}));
|
|
124
133
|
// Check fields
|
|
125
134
|
expect(screen.getByLabelText('Test Field 1')).toBeInTheDocument();
|
|
126
135
|
expect(screen.getByLabelText('Test Field 2')).toBeInTheDocument();
|
|
@@ -131,8 +140,8 @@ describe('AkiformBuilder', () => {
|
|
|
131
140
|
// Check props
|
|
132
141
|
expect(document.querySelector('.akinon-row-middle')).toBeInTheDocument();
|
|
133
142
|
expect(document.querySelector('.akinon-col-24')).toBeInTheDocument();
|
|
134
|
-
});
|
|
135
|
-
it('handles form with custom field and onChange',
|
|
143
|
+
}));
|
|
144
|
+
it('handles form with custom field and onChange', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
136
145
|
const CustomComponent = ({ field, control }) => {
|
|
137
146
|
const { field: controllerField } = useController({
|
|
138
147
|
name: field.key,
|
|
@@ -149,25 +158,25 @@ describe('AkiformBuilder', () => {
|
|
|
149
158
|
}
|
|
150
159
|
];
|
|
151
160
|
const onValueChangeMock = vi.fn();
|
|
152
|
-
|
|
161
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
153
162
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: mockOnSubmit, onValueChange: onValueChangeMock }));
|
|
154
|
-
});
|
|
163
|
+
}));
|
|
155
164
|
const customInput = screen.getByTestId('custom-input');
|
|
156
165
|
expect(customInput).toBeInTheDocument();
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
});
|
|
160
|
-
|
|
166
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
167
|
+
yield userEvent.type(customInput, 'test value');
|
|
168
|
+
}));
|
|
169
|
+
yield waitFor(() => {
|
|
161
170
|
expect(onValueChangeMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
162
171
|
customField: 'test value'
|
|
163
172
|
}));
|
|
164
173
|
});
|
|
165
|
-
});
|
|
166
|
-
it('resets form when reset button is clicked',
|
|
167
|
-
|
|
174
|
+
}));
|
|
175
|
+
it('resets form when reset button is clicked', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
176
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
177
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, onReset: mockOnReset, showResetButton: true }));
|
|
169
|
-
});
|
|
170
|
-
|
|
178
|
+
}));
|
|
179
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
171
180
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
172
181
|
target: { value: 'John Doe' }
|
|
173
182
|
});
|
|
@@ -175,82 +184,82 @@ describe('AkiformBuilder', () => {
|
|
|
175
184
|
target: { value: '30' }
|
|
176
185
|
});
|
|
177
186
|
fireEvent.click(screen.getByText('RESET'));
|
|
178
|
-
});
|
|
179
|
-
|
|
187
|
+
}));
|
|
188
|
+
yield waitFor(() => {
|
|
180
189
|
expect(mockOnReset).toHaveBeenCalled();
|
|
181
190
|
expect(screen.getByLabelText('Name')).toHaveValue('');
|
|
182
191
|
expect(screen.getByLabelText('Age')).toHaveValue('');
|
|
183
192
|
});
|
|
184
|
-
});
|
|
185
|
-
it('exposes reset method through ref',
|
|
193
|
+
}));
|
|
194
|
+
it('exposes reset method through ref', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
186
195
|
const ref = React.createRef();
|
|
187
196
|
const onResetMock = vi.fn();
|
|
188
|
-
|
|
197
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
189
198
|
render(React.createElement(AkiformBuilder, { ref: ref, fields: defaultFields, onSubmit: mockOnSubmit, onReset: onResetMock }));
|
|
190
|
-
});
|
|
199
|
+
}));
|
|
191
200
|
// Fill in some values
|
|
192
|
-
|
|
201
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
193
202
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
194
203
|
target: { value: 'John Doe' }
|
|
195
204
|
});
|
|
196
|
-
});
|
|
205
|
+
}));
|
|
197
206
|
// Call reset through ref
|
|
198
|
-
|
|
207
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
199
208
|
var _a;
|
|
200
209
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.reset();
|
|
201
|
-
});
|
|
210
|
+
}));
|
|
202
211
|
// Check if form is reset and onReset is called
|
|
203
212
|
expect(screen.getByLabelText('Name')).toHaveValue('');
|
|
204
213
|
expect(onResetMock).toHaveBeenCalled();
|
|
205
214
|
// Test partial reset
|
|
206
|
-
|
|
215
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
207
216
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
208
217
|
target: { value: 'John Doe' }
|
|
209
218
|
});
|
|
210
219
|
fireEvent.change(screen.getByLabelText('Age'), {
|
|
211
220
|
target: { value: '30' }
|
|
212
221
|
});
|
|
213
|
-
});
|
|
214
|
-
|
|
222
|
+
}));
|
|
223
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
215
224
|
var _a;
|
|
216
225
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.reset({ name: 'Jane Doe' });
|
|
217
|
-
});
|
|
226
|
+
}));
|
|
218
227
|
expect(screen.getByLabelText('Name')).toHaveValue('Jane Doe');
|
|
219
228
|
expect(screen.getByLabelText('Age')).toHaveValue('30');
|
|
220
|
-
});
|
|
221
|
-
it('calls onValueChange when form values change in uncontrolled mode',
|
|
222
|
-
|
|
229
|
+
}));
|
|
230
|
+
it('calls onValueChange when form values change in uncontrolled mode', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
231
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
223
232
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, onValueChange: mockOnValueChange }));
|
|
224
|
-
});
|
|
225
|
-
|
|
233
|
+
}));
|
|
234
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
226
235
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
227
236
|
target: { value: 'John Doe' }
|
|
228
237
|
});
|
|
229
|
-
});
|
|
230
|
-
|
|
238
|
+
}));
|
|
239
|
+
yield waitFor(() => {
|
|
231
240
|
expect(mockOnValueChange).toHaveBeenCalledWith(expect.objectContaining({
|
|
232
241
|
name: 'John Doe'
|
|
233
242
|
}));
|
|
234
243
|
});
|
|
235
|
-
});
|
|
236
|
-
it('applies throttling in uncontrolled mode',
|
|
244
|
+
}));
|
|
245
|
+
it('applies throttling in uncontrolled mode', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
237
246
|
vi.useFakeTimers();
|
|
238
|
-
|
|
247
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
239
248
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, onValueChange: mockOnValueChange }));
|
|
240
|
-
});
|
|
241
|
-
|
|
249
|
+
}));
|
|
250
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
242
251
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
243
252
|
target: { value: 'John Doe' }
|
|
244
253
|
});
|
|
245
|
-
});
|
|
254
|
+
}));
|
|
246
255
|
expect(mockOnValueChange).not.toHaveBeenCalled();
|
|
247
|
-
|
|
256
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
248
257
|
vi.advanceTimersByTime(THROTTLE_DELAY);
|
|
249
|
-
});
|
|
258
|
+
}));
|
|
250
259
|
expect(mockOnValueChange).toHaveBeenCalledWith(expect.objectContaining({ name: 'John Doe' }));
|
|
251
260
|
vi.useRealTimers();
|
|
252
|
-
});
|
|
253
|
-
it('renders different field types correctly',
|
|
261
|
+
}));
|
|
262
|
+
it('renders different field types correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
254
263
|
const fields = [
|
|
255
264
|
{
|
|
256
265
|
key: 'name',
|
|
@@ -274,9 +283,9 @@ describe('AkiformBuilder', () => {
|
|
|
274
283
|
{ key: 'birthdate', label: 'Birth Date', type: 'date' },
|
|
275
284
|
{ key: 'bio', label: 'Biography', type: 'textarea' }
|
|
276
285
|
];
|
|
277
|
-
|
|
286
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
278
287
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: mockOnSubmit }));
|
|
279
|
-
});
|
|
288
|
+
}));
|
|
280
289
|
expect(screen.getByPlaceholderText('Enter your name')).toHaveAttribute('type', 'text');
|
|
281
290
|
expect(screen.getByText('Help text')).toBeInTheDocument();
|
|
282
291
|
expect(screen.getByText('Label description text')).toBeInTheDocument();
|
|
@@ -285,8 +294,8 @@ describe('AkiformBuilder', () => {
|
|
|
285
294
|
expect(screen.getByLabelText('Subscribe')).toHaveAttribute('type', 'checkbox');
|
|
286
295
|
expect(screen.getByLabelText('Birth Date')).toBeInTheDocument();
|
|
287
296
|
expect(screen.getByLabelText('Biography')).toBeInTheDocument();
|
|
288
|
-
});
|
|
289
|
-
it('renders field array correctly',
|
|
297
|
+
}));
|
|
298
|
+
it('renders field array correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
290
299
|
const user = userEvent.setup();
|
|
291
300
|
const fields = [
|
|
292
301
|
field()
|
|
@@ -306,18 +315,18 @@ describe('AkiformBuilder', () => {
|
|
|
306
315
|
])
|
|
307
316
|
.build()
|
|
308
317
|
];
|
|
309
|
-
|
|
318
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
310
319
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: mockOnSubmit }));
|
|
311
|
-
});
|
|
320
|
+
}));
|
|
312
321
|
expect(screen.getByText('Add Addresses')).toBeInTheDocument();
|
|
313
|
-
|
|
314
|
-
|
|
322
|
+
yield user.click(screen.getByTestId('addresses-add-button'));
|
|
323
|
+
yield expandCollapsable();
|
|
315
324
|
expect(screen.getAllByText('Street')).toHaveLength(1);
|
|
316
325
|
expect(screen.getAllByText('City')).toHaveLength(1);
|
|
317
326
|
expect(screen.getByText('Help text')).toBeInTheDocument();
|
|
318
327
|
expect(screen.getByText('Label description text')).toBeInTheDocument();
|
|
319
|
-
});
|
|
320
|
-
it('handles form with field array and nested validation',
|
|
328
|
+
}));
|
|
329
|
+
it('handles form with field array and nested validation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
321
330
|
const user = userEvent.setup();
|
|
322
331
|
const fields = [
|
|
323
332
|
{
|
|
@@ -341,40 +350,40 @@ describe('AkiformBuilder', () => {
|
|
|
341
350
|
}
|
|
342
351
|
];
|
|
343
352
|
const onSubmitMock = vi.fn();
|
|
344
|
-
|
|
353
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
345
354
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: onSubmitMock }));
|
|
346
|
-
});
|
|
355
|
+
}));
|
|
347
356
|
// Add an item
|
|
348
|
-
|
|
357
|
+
yield user.click(screen.getByTestId('items-add-button'));
|
|
349
358
|
// Try to submit without filling required fields
|
|
350
|
-
|
|
359
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
351
360
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
352
|
-
});
|
|
353
|
-
|
|
361
|
+
}));
|
|
362
|
+
yield waitFor(() => {
|
|
354
363
|
expect(screen.getByText('An error occurred in here')).toBeInTheDocument();
|
|
355
364
|
expect(onSubmitMock).not.toHaveBeenCalled();
|
|
356
365
|
});
|
|
357
|
-
|
|
366
|
+
yield expandCollapsable();
|
|
358
367
|
// Fill in valid data
|
|
359
|
-
|
|
368
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
360
369
|
const nameInput = screen.getByRole('textbox', { name: /item name/i });
|
|
361
370
|
const quantityInput = screen.getByRole('spinbutton', {
|
|
362
371
|
name: /quantity/i
|
|
363
372
|
});
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
});
|
|
373
|
+
yield userEvent.type(nameInput, 'Test Item');
|
|
374
|
+
yield userEvent.type(quantityInput, '2');
|
|
375
|
+
}));
|
|
367
376
|
// Submit the form
|
|
368
|
-
|
|
377
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
369
378
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
370
|
-
});
|
|
371
|
-
|
|
379
|
+
}));
|
|
380
|
+
yield waitFor(() => {
|
|
372
381
|
expect(onSubmitMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
373
382
|
items: [{ name: 'Test Item', quantity: 2 }]
|
|
374
383
|
}), expect.anything());
|
|
375
384
|
});
|
|
376
|
-
});
|
|
377
|
-
it('handles field array operations correctly',
|
|
385
|
+
}));
|
|
386
|
+
it('handles field array operations correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
378
387
|
const user = userEvent.setup();
|
|
379
388
|
const fields = [
|
|
380
389
|
{
|
|
@@ -395,25 +404,25 @@ describe('AkiformBuilder', () => {
|
|
|
395
404
|
} }),
|
|
396
405
|
React.createElement("div", { "data-testid": "form-values" }, JSON.stringify(formValues))));
|
|
397
406
|
};
|
|
398
|
-
|
|
407
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
399
408
|
render(React.createElement(TestComponent, null));
|
|
400
|
-
});
|
|
409
|
+
}));
|
|
401
410
|
// Add an item
|
|
402
|
-
|
|
403
|
-
|
|
411
|
+
yield user.click(screen.getByTestId('items-add-button'));
|
|
412
|
+
yield expandCollapsable();
|
|
404
413
|
// Fill in the fields
|
|
405
|
-
|
|
414
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
406
415
|
fireEvent.change(screen.getByLabelText('Item Name'), {
|
|
407
416
|
target: { value: 'Test Item' }
|
|
408
417
|
});
|
|
409
|
-
});
|
|
410
|
-
|
|
418
|
+
}));
|
|
419
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
411
420
|
fireEvent.change(screen.getByLabelText('Quantity'), {
|
|
412
421
|
target: { value: '5' }
|
|
413
422
|
});
|
|
414
|
-
});
|
|
423
|
+
}));
|
|
415
424
|
// Wait for the form values to update
|
|
416
|
-
|
|
425
|
+
yield waitFor(() => {
|
|
417
426
|
const formValuesElement = screen.getByTestId('form-values');
|
|
418
427
|
const formValues = JSON.parse(formValuesElement.textContent || '{}');
|
|
419
428
|
expect(formValues).toEqual(expect.objectContaining({
|
|
@@ -421,24 +430,24 @@ describe('AkiformBuilder', () => {
|
|
|
421
430
|
}));
|
|
422
431
|
});
|
|
423
432
|
// Submit the form
|
|
424
|
-
|
|
433
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
425
434
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
426
|
-
});
|
|
435
|
+
}));
|
|
427
436
|
// Check the submitted values
|
|
428
|
-
|
|
437
|
+
yield waitFor(() => {
|
|
429
438
|
expect(mockOnSubmit).toHaveBeenCalledWith(expect.objectContaining({
|
|
430
439
|
items: [{ name: 'Test Item', quantity: 5 }]
|
|
431
440
|
}), expect.anything());
|
|
432
441
|
});
|
|
433
|
-
});
|
|
434
|
-
it('applies layout options correctly',
|
|
435
|
-
|
|
442
|
+
}));
|
|
443
|
+
it('applies layout options correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
444
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
436
445
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, layout: "horizontal", layoutOptions: { labelCol: { span: 8 }, wrapperCol: { span: 16 } } }));
|
|
437
|
-
});
|
|
446
|
+
}));
|
|
438
447
|
const form = screen.getByTestId('akiform-builder');
|
|
439
448
|
expect(form).toHaveClass('akinon-form-horizontal');
|
|
440
|
-
});
|
|
441
|
-
it('conditionally renders and disables fields',
|
|
449
|
+
}));
|
|
450
|
+
it('conditionally renders and disables fields', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
442
451
|
const fields = [
|
|
443
452
|
{ key: 'showField', label: 'Show Field', type: 'checkbox' },
|
|
444
453
|
{
|
|
@@ -455,21 +464,21 @@ describe('AkiformBuilder', () => {
|
|
|
455
464
|
config: { disabled: values => !values.enableField }
|
|
456
465
|
}
|
|
457
466
|
];
|
|
458
|
-
|
|
467
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
459
468
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: mockOnSubmit }));
|
|
460
|
-
});
|
|
469
|
+
}));
|
|
461
470
|
expect(screen.queryByLabelText('Conditional Field')).not.toBeInTheDocument();
|
|
462
|
-
|
|
471
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
463
472
|
fireEvent.click(screen.getByLabelText('Show Field'));
|
|
464
|
-
});
|
|
473
|
+
}));
|
|
465
474
|
expect(screen.getByLabelText('Conditional Field')).toBeInTheDocument();
|
|
466
475
|
expect(screen.getByLabelText('Disableable Field')).toBeDisabled();
|
|
467
|
-
|
|
476
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
468
477
|
fireEvent.click(screen.getByLabelText('Enable Field'));
|
|
469
|
-
});
|
|
478
|
+
}));
|
|
470
479
|
expect(screen.getByLabelText('Disableable Field')).not.toBeDisabled();
|
|
471
|
-
});
|
|
472
|
-
it('applies custom validation',
|
|
480
|
+
}));
|
|
481
|
+
it('applies custom validation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
473
482
|
const fields = [
|
|
474
483
|
{
|
|
475
484
|
key: 'email',
|
|
@@ -478,40 +487,40 @@ describe('AkiformBuilder', () => {
|
|
|
478
487
|
validation: akival.string().email('Invalid email format')
|
|
479
488
|
}
|
|
480
489
|
];
|
|
481
|
-
|
|
490
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
482
491
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: mockOnSubmit }));
|
|
483
|
-
});
|
|
484
|
-
|
|
492
|
+
}));
|
|
493
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
485
494
|
fireEvent.change(screen.getByRole('textbox', { name: /email/i }), {
|
|
486
495
|
target: { value: 'invalid-email' }
|
|
487
496
|
});
|
|
488
497
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
489
|
-
});
|
|
490
|
-
|
|
498
|
+
}));
|
|
499
|
+
yield waitFor(() => {
|
|
491
500
|
expect(screen.getByText('Invalid email format')).toBeInTheDocument();
|
|
492
501
|
});
|
|
493
|
-
});
|
|
494
|
-
it('resets form using ref',
|
|
502
|
+
}));
|
|
503
|
+
it('resets form using ref', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
495
504
|
const ref = React.createRef();
|
|
496
|
-
|
|
505
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
497
506
|
render(React.createElement(AkiformBuilder, { ref: ref, fields: defaultFields, onSubmit: mockOnSubmit }));
|
|
498
|
-
});
|
|
499
|
-
|
|
507
|
+
}));
|
|
508
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
500
509
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
501
510
|
target: { value: 'John Doe' }
|
|
502
511
|
});
|
|
503
512
|
fireEvent.change(screen.getByLabelText('Age'), {
|
|
504
513
|
target: { value: '30' }
|
|
505
514
|
});
|
|
506
|
-
});
|
|
507
|
-
|
|
515
|
+
}));
|
|
516
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
508
517
|
var _a;
|
|
509
518
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.reset();
|
|
510
|
-
});
|
|
519
|
+
}));
|
|
511
520
|
expect(screen.getByLabelText('Name')).toHaveValue('');
|
|
512
521
|
expect(screen.getByLabelText('Age')).toHaveValue('');
|
|
513
|
-
});
|
|
514
|
-
it('displays error states',
|
|
522
|
+
}));
|
|
523
|
+
it('displays error states', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
515
524
|
const fields = [
|
|
516
525
|
{
|
|
517
526
|
key: 'name',
|
|
@@ -520,22 +529,22 @@ describe('AkiformBuilder', () => {
|
|
|
520
529
|
validation: akival.string().required('Name is required')
|
|
521
530
|
}
|
|
522
531
|
];
|
|
523
|
-
|
|
532
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
524
533
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: mockOnSubmit }));
|
|
525
|
-
});
|
|
526
|
-
|
|
534
|
+
}));
|
|
535
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
527
536
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
528
|
-
});
|
|
529
|
-
|
|
537
|
+
}));
|
|
538
|
+
yield waitFor(() => {
|
|
530
539
|
expect(screen.getByText('Name is required')).toBeInTheDocument();
|
|
531
540
|
});
|
|
532
|
-
});
|
|
533
|
-
it('handles form submission',
|
|
541
|
+
}));
|
|
542
|
+
it('handles form submission', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
534
543
|
const onSubmit = vi.fn();
|
|
535
|
-
|
|
544
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
536
545
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: onSubmit }));
|
|
537
|
-
});
|
|
538
|
-
|
|
546
|
+
}));
|
|
547
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
539
548
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
540
549
|
target: { value: 'John Doe' }
|
|
541
550
|
});
|
|
@@ -543,15 +552,15 @@ describe('AkiformBuilder', () => {
|
|
|
543
552
|
target: { value: '30' }
|
|
544
553
|
});
|
|
545
554
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
546
|
-
});
|
|
547
|
-
|
|
555
|
+
}));
|
|
556
|
+
yield waitFor(() => {
|
|
548
557
|
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({
|
|
549
558
|
name: 'John Doe',
|
|
550
559
|
age: 30
|
|
551
560
|
}), expect.anything());
|
|
552
561
|
});
|
|
553
|
-
});
|
|
554
|
-
it('handles form submission with errors',
|
|
562
|
+
}));
|
|
563
|
+
it('handles form submission with errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
555
564
|
const fields = [
|
|
556
565
|
{
|
|
557
566
|
key: 'name',
|
|
@@ -561,35 +570,35 @@ describe('AkiformBuilder', () => {
|
|
|
561
570
|
}
|
|
562
571
|
];
|
|
563
572
|
const onSubmit = vi.fn();
|
|
564
|
-
|
|
573
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
565
574
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: onSubmit }));
|
|
566
|
-
});
|
|
567
|
-
|
|
575
|
+
}));
|
|
576
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
568
577
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
569
|
-
});
|
|
570
|
-
|
|
578
|
+
}));
|
|
579
|
+
yield waitFor(() => {
|
|
571
580
|
expect(screen.getByText('Name is required')).toBeInTheDocument();
|
|
572
581
|
expect(onSubmit).not.toHaveBeenCalled();
|
|
573
582
|
});
|
|
574
|
-
});
|
|
575
|
-
it('handles form with initial values',
|
|
583
|
+
}));
|
|
584
|
+
it('handles form with initial values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
576
585
|
const initialValues = { name: 'John Doe', age: 30 };
|
|
577
|
-
|
|
586
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
578
587
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, initialValues: initialValues }));
|
|
579
|
-
});
|
|
580
|
-
|
|
588
|
+
}));
|
|
589
|
+
yield waitFor(() => {
|
|
581
590
|
expect(screen.getByLabelText('Name')).toHaveValue('John Doe');
|
|
582
591
|
expect(screen.getByLabelText('Age')).toHaveValue('30');
|
|
583
592
|
});
|
|
584
|
-
});
|
|
585
|
-
it('handles form with custom layout',
|
|
586
|
-
|
|
593
|
+
}));
|
|
594
|
+
it('handles form with custom layout', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
595
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
587
596
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, layout: "vertical" }));
|
|
588
|
-
});
|
|
597
|
+
}));
|
|
589
598
|
const form = screen.getByTestId('akiform-builder');
|
|
590
599
|
expect(form).toHaveClass('akinon-form-vertical');
|
|
591
|
-
});
|
|
592
|
-
it('renders custom field correctly',
|
|
600
|
+
}));
|
|
601
|
+
it('renders custom field correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
593
602
|
const CustomComponent = ({ field }) => (React.createElement("div", { "data-testid": "custom-field" }, field.label));
|
|
594
603
|
const fields = [
|
|
595
604
|
{
|
|
@@ -601,30 +610,30 @@ describe('AkiformBuilder', () => {
|
|
|
601
610
|
render: ({ field }) => (React.createElement(CustomComponent, { field: field }))
|
|
602
611
|
}
|
|
603
612
|
];
|
|
604
|
-
|
|
613
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
605
614
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
606
|
-
});
|
|
615
|
+
}));
|
|
607
616
|
expect(screen.getByTestId('custom-field')).toHaveTextContent('Custom Field');
|
|
608
617
|
expect(screen.getByText('Help text')).toBeInTheDocument();
|
|
609
618
|
expect(screen.getByText('Label description text')).toBeInTheDocument();
|
|
610
|
-
});
|
|
611
|
-
it('cleans up throttle timeout on unmount',
|
|
619
|
+
}));
|
|
620
|
+
it('cleans up throttle timeout on unmount', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
612
621
|
vi.useFakeTimers();
|
|
613
622
|
const { unmount } = render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, onValueChange: mockOnValueChange }));
|
|
614
|
-
|
|
623
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
615
624
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
616
625
|
target: { value: 'John Doe' }
|
|
617
626
|
});
|
|
618
|
-
});
|
|
627
|
+
}));
|
|
619
628
|
unmount();
|
|
620
629
|
// Advance timers and ensure onValueChange is not called
|
|
621
|
-
|
|
630
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
622
631
|
vi.advanceTimersByTime(THROTTLE_DELAY + 100);
|
|
623
|
-
});
|
|
632
|
+
}));
|
|
624
633
|
expect(mockOnValueChange).not.toHaveBeenCalled();
|
|
625
634
|
vi.useRealTimers();
|
|
626
|
-
});
|
|
627
|
-
it('handles custom field with undefined render prop',
|
|
635
|
+
}));
|
|
636
|
+
it('handles custom field with undefined render prop', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
628
637
|
const fields = [
|
|
629
638
|
{
|
|
630
639
|
key: 'customField',
|
|
@@ -633,15 +642,15 @@ describe('AkiformBuilder', () => {
|
|
|
633
642
|
render: undefined
|
|
634
643
|
}
|
|
635
644
|
];
|
|
636
|
-
|
|
645
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
637
646
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
638
|
-
});
|
|
647
|
+
}));
|
|
639
648
|
// The custom field should not be rendered, but the form should not crash
|
|
640
649
|
expect(screen.queryByLabelText('Custom Field')).not.toBeInTheDocument();
|
|
641
650
|
// The form should still be rendered
|
|
642
651
|
expect(screen.getByTestId('akiform-builder')).toBeInTheDocument();
|
|
643
|
-
});
|
|
644
|
-
it('renders custom submit and reset button props',
|
|
652
|
+
}));
|
|
653
|
+
it('renders custom submit and reset button props', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
645
654
|
const submitButtonProps = {
|
|
646
655
|
className: 'custom-submit-btn',
|
|
647
656
|
children: 'submit button'
|
|
@@ -650,9 +659,9 @@ describe('AkiformBuilder', () => {
|
|
|
650
659
|
className: 'custom-reset-btn',
|
|
651
660
|
children: 'reset button'
|
|
652
661
|
};
|
|
653
|
-
|
|
662
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
654
663
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, showResetButton: true, onReset: mockOnReset, submitButtonProps: submitButtonProps, resetButtonProps: resetButtonProps }));
|
|
655
|
-
});
|
|
664
|
+
}));
|
|
656
665
|
const submitButton = screen
|
|
657
666
|
.getByText(submitButtonProps.children)
|
|
658
667
|
.closest('button');
|
|
@@ -663,51 +672,51 @@ describe('AkiformBuilder', () => {
|
|
|
663
672
|
expect(resetButton).toBeInTheDocument();
|
|
664
673
|
expect(submitButton).toHaveClass(submitButtonProps.className);
|
|
665
674
|
expect(resetButton).toHaveClass(resetButtonProps.className);
|
|
666
|
-
|
|
675
|
+
yield userEvent.click(resetButton);
|
|
667
676
|
expect(mockOnReset).toHaveBeenCalled();
|
|
668
|
-
|
|
677
|
+
yield userEvent.click(submitButton);
|
|
669
678
|
expect(mockOnSubmit).toHaveBeenCalled();
|
|
670
|
-
});
|
|
679
|
+
}));
|
|
671
680
|
});
|
|
672
681
|
describe('AkiformBuilder in controlled mode', () => {
|
|
673
|
-
it('uses provided values in controlled mode',
|
|
682
|
+
it('uses provided values in controlled mode', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
674
683
|
const fields = [
|
|
675
684
|
{ key: 'name', label: 'Name', type: 'text' },
|
|
676
685
|
{ key: 'age', label: 'Age', type: 'number' }
|
|
677
686
|
];
|
|
678
687
|
const controlledValues = { name: 'John Doe', age: 30 };
|
|
679
688
|
const onChangeMock = vi.fn();
|
|
680
|
-
|
|
689
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
681
690
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn(), controlled: true, values: controlledValues, onValueChange: onChangeMock }));
|
|
682
|
-
});
|
|
691
|
+
}));
|
|
683
692
|
expect(screen.getByLabelText('Name')).toHaveValue('John Doe');
|
|
684
693
|
expect(screen.getByLabelText('Age')).toHaveValue('30');
|
|
685
|
-
});
|
|
686
|
-
it('calls onValueChange when form values change in controlled mode',
|
|
694
|
+
}));
|
|
695
|
+
it('calls onValueChange when form values change in controlled mode', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
687
696
|
const fields = [
|
|
688
697
|
{ key: 'name', label: 'Name', type: 'text' }
|
|
689
698
|
];
|
|
690
699
|
const onChangeMock = vi.fn();
|
|
691
|
-
|
|
700
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
692
701
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn(), controlled: true, values: { name: '' }, onValueChange: onChangeMock }));
|
|
693
|
-
});
|
|
694
|
-
|
|
702
|
+
}));
|
|
703
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
695
704
|
fireEvent.change(screen.getByLabelText('Name'), {
|
|
696
705
|
target: { value: 'Jane Doe' }
|
|
697
706
|
});
|
|
698
|
-
});
|
|
699
|
-
|
|
707
|
+
}));
|
|
708
|
+
yield waitFor(() => {
|
|
700
709
|
expect(onChangeMock).toHaveBeenCalledWith(expect.objectContaining({ name: 'Jane Doe' }));
|
|
701
710
|
});
|
|
702
|
-
});
|
|
703
|
-
it('calls onValueChange immediately in controlled mode',
|
|
711
|
+
}));
|
|
712
|
+
it('calls onValueChange immediately in controlled mode', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
704
713
|
const onValueChangeMock = vi.fn();
|
|
705
|
-
|
|
714
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
706
715
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: mockOnSubmit, controlled: true, values: { name: 'John Doe', age: 30 }, onValueChange: onValueChangeMock }));
|
|
707
|
-
});
|
|
716
|
+
}));
|
|
708
717
|
expect(onValueChangeMock).toHaveBeenCalledWith(expect.objectContaining({ name: 'John Doe', age: 30 }));
|
|
709
|
-
});
|
|
710
|
-
it('handles conditional rendering and disabling of fields',
|
|
718
|
+
}));
|
|
719
|
+
it('handles conditional rendering and disabling of fields', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
711
720
|
const fields = [
|
|
712
721
|
{ key: 'showField', label: 'Show Field', type: 'checkbox' },
|
|
713
722
|
{
|
|
@@ -725,25 +734,25 @@ describe('AkiformBuilder', () => {
|
|
|
725
734
|
}
|
|
726
735
|
];
|
|
727
736
|
const onValueChangeMock = vi.fn();
|
|
728
|
-
|
|
737
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
729
738
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn(), controlled: true, values: { showField: false, enableField: false }, onValueChange: onValueChangeMock }));
|
|
730
|
-
});
|
|
739
|
+
}));
|
|
731
740
|
expect(screen.queryByLabelText('Conditional Field')).not.toBeInTheDocument();
|
|
732
741
|
expect(screen.getByLabelText('Disableable Field')).toBeDisabled();
|
|
733
|
-
|
|
742
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
734
743
|
fireEvent.click(screen.getByLabelText('Show Field'));
|
|
735
744
|
fireEvent.click(screen.getByLabelText('Enable Field'));
|
|
736
|
-
});
|
|
745
|
+
}));
|
|
737
746
|
expect(screen.getByLabelText('Conditional Field')).toBeInTheDocument();
|
|
738
747
|
expect(screen.getByLabelText('Disableable Field')).not.toBeDisabled();
|
|
739
748
|
expect(onValueChangeMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
740
749
|
showField: true,
|
|
741
750
|
enableField: true
|
|
742
751
|
}));
|
|
743
|
-
});
|
|
752
|
+
}));
|
|
744
753
|
});
|
|
745
754
|
describe('FieldArrayComponent', () => {
|
|
746
|
-
it('renders field array with initial values',
|
|
755
|
+
it('renders field array with initial values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
747
756
|
const fields = [
|
|
748
757
|
{
|
|
749
758
|
key: 'items',
|
|
@@ -761,14 +770,14 @@ describe('AkiformBuilder', () => {
|
|
|
761
770
|
{ name: 'Item 2', quantity: 2 }
|
|
762
771
|
]
|
|
763
772
|
};
|
|
764
|
-
|
|
773
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
765
774
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn(), initialValues: initialValues }));
|
|
766
|
-
});
|
|
767
|
-
|
|
775
|
+
}));
|
|
776
|
+
yield expandCollapsable();
|
|
768
777
|
expect(screen.getAllByLabelText('Item Name')).toHaveLength(2);
|
|
769
778
|
expect(screen.getAllByLabelText('Quantity')).toHaveLength(2);
|
|
770
|
-
});
|
|
771
|
-
it('adds and removes field array items',
|
|
779
|
+
}));
|
|
780
|
+
it('adds and removes field array items', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
772
781
|
const user = userEvent.setup();
|
|
773
782
|
const fields = [
|
|
774
783
|
{
|
|
@@ -778,23 +787,23 @@ describe('AkiformBuilder', () => {
|
|
|
778
787
|
fields: [{ key: 'name', label: 'Item Name', type: 'text' }]
|
|
779
788
|
}
|
|
780
789
|
];
|
|
781
|
-
|
|
790
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
782
791
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
783
|
-
});
|
|
792
|
+
}));
|
|
784
793
|
// Add an item
|
|
785
|
-
|
|
786
|
-
|
|
794
|
+
yield user.click(screen.getByTestId('items-add-button'));
|
|
795
|
+
yield expandCollapsable();
|
|
787
796
|
expect(screen.getByLabelText('Item Name')).toBeInTheDocument();
|
|
788
797
|
// Add another item
|
|
789
|
-
|
|
790
|
-
|
|
798
|
+
yield user.click(screen.getByLabelText('Add Items'));
|
|
799
|
+
yield expandCollapsable();
|
|
791
800
|
expect(screen.getAllByLabelText('Item Name')).toHaveLength(2);
|
|
792
801
|
// Remove an item
|
|
793
|
-
|
|
794
|
-
|
|
802
|
+
yield user.click(screen.getAllByLabelText('Remove Items')[0]);
|
|
803
|
+
yield expandCollapsable();
|
|
795
804
|
expect(screen.getAllByLabelText('Item Name')).toHaveLength(1);
|
|
796
|
-
});
|
|
797
|
-
it('handles field array with conditional fields',
|
|
805
|
+
}));
|
|
806
|
+
it('handles field array with conditional fields', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
798
807
|
const user = userEvent.setup();
|
|
799
808
|
const fields = [
|
|
800
809
|
{
|
|
@@ -815,28 +824,28 @@ describe('AkiformBuilder', () => {
|
|
|
815
824
|
}
|
|
816
825
|
];
|
|
817
826
|
const { rerender } = render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
818
|
-
|
|
827
|
+
yield expandCollapsable();
|
|
819
828
|
// Add an item
|
|
820
|
-
|
|
821
|
-
|
|
829
|
+
yield user.click(screen.getByLabelText('Add Items'));
|
|
830
|
+
yield expandCollapsable();
|
|
822
831
|
// Description should not be visible initially
|
|
823
832
|
expect(screen.queryByLabelText('Description')).not.toBeInTheDocument();
|
|
824
833
|
// Enter a name longer than 5 characters
|
|
825
|
-
|
|
834
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
826
835
|
fireEvent.change(screen.getByLabelText('Item Name'), {
|
|
827
836
|
target: { value: 'Long Name' }
|
|
828
837
|
});
|
|
829
|
-
});
|
|
838
|
+
}));
|
|
830
839
|
// Force a re-render to trigger the conditional rendering
|
|
831
840
|
rerender(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
832
841
|
// Description should now be visible
|
|
833
|
-
|
|
842
|
+
yield waitFor(() => {
|
|
834
843
|
expect(screen.getByLabelText('Description')).toBeInTheDocument();
|
|
835
844
|
});
|
|
836
|
-
});
|
|
845
|
+
}));
|
|
837
846
|
});
|
|
838
847
|
describe('Edge cases and uncovered scenarios', () => {
|
|
839
|
-
it('handles field array with no fields',
|
|
848
|
+
it('handles field array with no fields', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
840
849
|
const fields = [
|
|
841
850
|
{
|
|
842
851
|
key: 'emptyFieldArray',
|
|
@@ -845,13 +854,13 @@ describe('AkiformBuilder', () => {
|
|
|
845
854
|
fields: []
|
|
846
855
|
}
|
|
847
856
|
];
|
|
848
|
-
|
|
857
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
849
858
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
850
|
-
});
|
|
859
|
+
}));
|
|
851
860
|
// The field array should be rendered with an "Add" button
|
|
852
861
|
expect(screen.getByTestId('emptyFieldArray-add-button')).toBeInTheDocument();
|
|
853
|
-
});
|
|
854
|
-
it('handles form submission with field array',
|
|
862
|
+
}));
|
|
863
|
+
it('handles form submission with field array', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
855
864
|
const user = userEvent.setup();
|
|
856
865
|
const fields = [
|
|
857
866
|
{
|
|
@@ -865,27 +874,27 @@ describe('AkiformBuilder', () => {
|
|
|
865
874
|
}
|
|
866
875
|
];
|
|
867
876
|
const onSubmitMock = vi.fn();
|
|
868
|
-
|
|
877
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
869
878
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: onSubmitMock }));
|
|
870
|
-
});
|
|
879
|
+
}));
|
|
871
880
|
// Add two items
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
881
|
+
yield user.click(screen.getByTestId('items-add-button'));
|
|
882
|
+
yield user.click(screen.getByLabelText('Add Items'));
|
|
883
|
+
yield expandCollapsable();
|
|
875
884
|
// Fill in the fields
|
|
876
885
|
const itemNames = screen.getAllByLabelText('Item Name');
|
|
877
886
|
const quantities = screen.getAllByLabelText('Quantity');
|
|
878
|
-
|
|
887
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
879
888
|
fireEvent.change(itemNames[0], { target: { value: 'Item 1' } });
|
|
880
889
|
fireEvent.change(quantities[0], { target: { value: '5' } });
|
|
881
890
|
fireEvent.change(itemNames[1], { target: { value: 'Item 2' } });
|
|
882
891
|
fireEvent.change(quantities[1], { target: { value: '10' } });
|
|
883
|
-
});
|
|
892
|
+
}));
|
|
884
893
|
// Submit the form
|
|
885
|
-
|
|
894
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
886
895
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
887
|
-
});
|
|
888
|
-
|
|
896
|
+
}));
|
|
897
|
+
yield waitFor(() => {
|
|
889
898
|
expect(onSubmitMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
890
899
|
items: [
|
|
891
900
|
{ name: 'Item 1', quantity: 5 },
|
|
@@ -893,8 +902,8 @@ describe('AkiformBuilder', () => {
|
|
|
893
902
|
]
|
|
894
903
|
}), expect.anything());
|
|
895
904
|
});
|
|
896
|
-
});
|
|
897
|
-
it('handles form with all field types',
|
|
905
|
+
}));
|
|
906
|
+
it('handles form with all field types', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
898
907
|
const fields = [
|
|
899
908
|
{ key: 'text', label: 'Text', type: 'text' },
|
|
900
909
|
{ key: 'number', label: 'Number', type: 'number' },
|
|
@@ -920,9 +929,9 @@ describe('AkiformBuilder', () => {
|
|
|
920
929
|
render: () => React.createElement("div", { "data-testid": "custom-field" }, "Custom Field")
|
|
921
930
|
}
|
|
922
931
|
];
|
|
923
|
-
|
|
932
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
924
933
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
925
|
-
});
|
|
934
|
+
}));
|
|
926
935
|
expect(screen.getByLabelText('Text')).toBeInTheDocument();
|
|
927
936
|
expect(screen.getByLabelText('Number')).toBeInTheDocument();
|
|
928
937
|
expect(screen.getByLabelText('Select')).toBeInTheDocument();
|
|
@@ -931,27 +940,27 @@ describe('AkiformBuilder', () => {
|
|
|
931
940
|
expect(screen.getByLabelText('Textarea')).toBeInTheDocument();
|
|
932
941
|
expect(screen.getByTestId('fieldArray-add-button')).toBeInTheDocument(); // For field array
|
|
933
942
|
expect(screen.getByTestId('custom-field')).toBeInTheDocument();
|
|
934
|
-
});
|
|
935
|
-
it('handles form with inline layout',
|
|
936
|
-
|
|
943
|
+
}));
|
|
944
|
+
it('handles form with inline layout', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
945
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
937
946
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: vi.fn(), layout: "inline" }));
|
|
938
|
-
});
|
|
947
|
+
}));
|
|
939
948
|
const form = screen.getByTestId('akiform-builder');
|
|
940
949
|
expect(form).toHaveClass('akinon-form-inline');
|
|
941
|
-
});
|
|
942
|
-
it('handles form reset with custom reset handler',
|
|
950
|
+
}));
|
|
951
|
+
it('handles form reset with custom reset handler', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
943
952
|
const onResetMock = vi.fn();
|
|
944
|
-
|
|
953
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
945
954
|
render(React.createElement(AkiformBuilder, { fields: defaultFields, onSubmit: vi.fn(), onReset: onResetMock, showResetButton: true }));
|
|
946
|
-
});
|
|
947
|
-
|
|
955
|
+
}));
|
|
956
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
948
957
|
fireEvent.click(screen.getByText('RESET'));
|
|
949
|
-
});
|
|
958
|
+
}));
|
|
950
959
|
expect(onResetMock).toHaveBeenCalled();
|
|
951
|
-
});
|
|
960
|
+
}));
|
|
952
961
|
});
|
|
953
962
|
describe('AkiformBuilder with FieldBuilder', () => {
|
|
954
|
-
it('renders form fields created with FieldBuilder',
|
|
963
|
+
it('renders form fields created with FieldBuilder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
955
964
|
const fields = [
|
|
956
965
|
field()
|
|
957
966
|
.key('name')
|
|
@@ -984,9 +993,9 @@ describe('AkiformBuilder', () => {
|
|
|
984
993
|
field().key('birthdate').label('Birth Date').type('date').build(),
|
|
985
994
|
field().key('description').label('Description').type('textarea').build()
|
|
986
995
|
];
|
|
987
|
-
|
|
996
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
988
997
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
989
|
-
});
|
|
998
|
+
}));
|
|
990
999
|
expect(screen.getByText('Name')).toBeInTheDocument();
|
|
991
1000
|
expect(screen.getByText('Label description text')).toBeInTheDocument();
|
|
992
1001
|
expect(screen.getByText('Help text')).toBeInTheDocument();
|
|
@@ -995,8 +1004,8 @@ describe('AkiformBuilder', () => {
|
|
|
995
1004
|
expect(screen.getByLabelText('Subscribe to newsletter')).toBeInTheDocument();
|
|
996
1005
|
expect(screen.getByLabelText('Birth Date')).toBeInTheDocument();
|
|
997
1006
|
expect(screen.getByLabelText('Description')).toBeInTheDocument();
|
|
998
|
-
});
|
|
999
|
-
it('handles form submission with fields created by FieldBuilder',
|
|
1007
|
+
}));
|
|
1008
|
+
it('handles form submission with fields created by FieldBuilder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1000
1009
|
const fields = [
|
|
1001
1010
|
field()
|
|
1002
1011
|
.key('name')
|
|
@@ -1012,10 +1021,10 @@ describe('AkiformBuilder', () => {
|
|
|
1012
1021
|
.build()
|
|
1013
1022
|
];
|
|
1014
1023
|
const onSubmitMock = vi.fn();
|
|
1015
|
-
|
|
1024
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1016
1025
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: onSubmitMock }));
|
|
1017
|
-
});
|
|
1018
|
-
|
|
1026
|
+
}));
|
|
1027
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1019
1028
|
fireEvent.change(screen.getByRole('textbox', { name: /name/i }), {
|
|
1020
1029
|
target: { value: 'John Doe' }
|
|
1021
1030
|
});
|
|
@@ -1023,15 +1032,15 @@ describe('AkiformBuilder', () => {
|
|
|
1023
1032
|
target: { value: '25' }
|
|
1024
1033
|
});
|
|
1025
1034
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
1026
|
-
});
|
|
1027
|
-
|
|
1035
|
+
}));
|
|
1036
|
+
yield waitFor(() => {
|
|
1028
1037
|
expect(onSubmitMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
1029
1038
|
name: 'John Doe',
|
|
1030
1039
|
age: 25
|
|
1031
1040
|
}), expect.anything());
|
|
1032
1041
|
});
|
|
1033
|
-
});
|
|
1034
|
-
it('handles form with custom field created by FieldBuilder',
|
|
1042
|
+
}));
|
|
1043
|
+
it('handles form with custom field created by FieldBuilder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1035
1044
|
const CustomComponent = ({ field }) => (React.createElement("div", { "data-testid": "custom-field" }, field.label));
|
|
1036
1045
|
const fields = [
|
|
1037
1046
|
field()
|
|
@@ -1043,14 +1052,14 @@ describe('AkiformBuilder', () => {
|
|
|
1043
1052
|
.render(({ field }) => React.createElement(CustomComponent, { field: field }))
|
|
1044
1053
|
.build()
|
|
1045
1054
|
];
|
|
1046
|
-
|
|
1055
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1047
1056
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1048
|
-
});
|
|
1057
|
+
}));
|
|
1049
1058
|
expect(screen.getByTestId('custom-field')).toHaveTextContent('Custom Field');
|
|
1050
1059
|
expect(screen.getByText('Help text')).toBeInTheDocument();
|
|
1051
1060
|
expect(screen.getByText('Label description text')).toBeInTheDocument();
|
|
1052
|
-
});
|
|
1053
|
-
it('handles form with field array created by FieldBuilder',
|
|
1061
|
+
}));
|
|
1062
|
+
it('handles form with field array created by FieldBuilder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1054
1063
|
const user = userEvent.setup();
|
|
1055
1064
|
const fields = [
|
|
1056
1065
|
field()
|
|
@@ -1071,37 +1080,37 @@ describe('AkiformBuilder', () => {
|
|
|
1071
1080
|
.build()
|
|
1072
1081
|
];
|
|
1073
1082
|
const onSubmitMock = vi.fn();
|
|
1074
|
-
|
|
1083
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1075
1084
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: onSubmitMock }));
|
|
1076
|
-
});
|
|
1085
|
+
}));
|
|
1077
1086
|
// Add an address
|
|
1078
|
-
|
|
1079
|
-
|
|
1087
|
+
yield user.click(screen.getByTestId('addresses-add-button'));
|
|
1088
|
+
yield expandCollapsable();
|
|
1080
1089
|
//Check rendered fields
|
|
1081
1090
|
expect(screen.getByText('Street')).toBeInTheDocument();
|
|
1082
1091
|
expect(screen.getByText('Help text')).toBeInTheDocument();
|
|
1083
1092
|
expect(screen.getByText('Label description text')).toBeInTheDocument();
|
|
1084
1093
|
expect(screen.getByLabelText('City')).toBeInTheDocument();
|
|
1085
1094
|
// Fill in the fields
|
|
1086
|
-
|
|
1095
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1087
1096
|
fireEvent.change(screen.getByPlaceholderText('Enter your street'), {
|
|
1088
1097
|
target: { value: '123 Main St' }
|
|
1089
1098
|
});
|
|
1090
1099
|
fireEvent.change(screen.getByLabelText('City'), {
|
|
1091
1100
|
target: { value: 'Anytown' }
|
|
1092
1101
|
});
|
|
1093
|
-
});
|
|
1102
|
+
}));
|
|
1094
1103
|
// Submit the form
|
|
1095
|
-
|
|
1104
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1096
1105
|
fireEvent.submit(screen.getByTestId('akiform-builder'));
|
|
1097
|
-
});
|
|
1098
|
-
|
|
1106
|
+
}));
|
|
1107
|
+
yield waitFor(() => {
|
|
1099
1108
|
expect(onSubmitMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
1100
1109
|
addresses: [{ street: '123 Main St', city: 'Anytown' }]
|
|
1101
1110
|
}), expect.anything());
|
|
1102
1111
|
});
|
|
1103
|
-
});
|
|
1104
|
-
it('handles conditional rendering with FieldBuilder',
|
|
1112
|
+
}));
|
|
1113
|
+
it('handles conditional rendering with FieldBuilder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1105
1114
|
const fields = [
|
|
1106
1115
|
field().key('showField').label('Show Field').type('checkbox').build(),
|
|
1107
1116
|
field()
|
|
@@ -1111,16 +1120,16 @@ describe('AkiformBuilder', () => {
|
|
|
1111
1120
|
.config({ visible: (values) => values.showField })
|
|
1112
1121
|
.build()
|
|
1113
1122
|
];
|
|
1114
|
-
|
|
1123
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1115
1124
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1116
|
-
});
|
|
1125
|
+
}));
|
|
1117
1126
|
expect(screen.queryByLabelText('Conditional Field')).not.toBeInTheDocument();
|
|
1118
|
-
|
|
1127
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1119
1128
|
fireEvent.click(screen.getByLabelText('Show Field'));
|
|
1120
|
-
});
|
|
1129
|
+
}));
|
|
1121
1130
|
expect(screen.getByLabelText('Conditional Field')).toBeInTheDocument();
|
|
1122
|
-
});
|
|
1123
|
-
it('handles disabled fields with FieldBuilder',
|
|
1131
|
+
}));
|
|
1132
|
+
it('handles disabled fields with FieldBuilder', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1124
1133
|
const fields = [
|
|
1125
1134
|
field()
|
|
1126
1135
|
.key('disabledField')
|
|
@@ -1129,14 +1138,14 @@ describe('AkiformBuilder', () => {
|
|
|
1129
1138
|
.config({ disabled: true })
|
|
1130
1139
|
.build()
|
|
1131
1140
|
];
|
|
1132
|
-
|
|
1141
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1133
1142
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1134
|
-
});
|
|
1143
|
+
}));
|
|
1135
1144
|
expect(screen.getByLabelText('Disabled Field')).toBeDisabled();
|
|
1136
|
-
});
|
|
1145
|
+
}));
|
|
1137
1146
|
});
|
|
1138
1147
|
describe('Accessibility features', () => {
|
|
1139
|
-
it('renders form with proper ARIA attributes',
|
|
1148
|
+
it('renders form with proper ARIA attributes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1140
1149
|
const fields = [
|
|
1141
1150
|
{
|
|
1142
1151
|
key: 'name',
|
|
@@ -1146,9 +1155,9 @@ describe('AkiformBuilder', () => {
|
|
|
1146
1155
|
},
|
|
1147
1156
|
{ key: 'age', label: 'Age', type: 'number' }
|
|
1148
1157
|
];
|
|
1149
|
-
|
|
1158
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1150
1159
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1151
|
-
});
|
|
1160
|
+
}));
|
|
1152
1161
|
const form = screen.getByRole('form');
|
|
1153
1162
|
expect(form).toHaveAttribute('aria-label', 'Form');
|
|
1154
1163
|
const nameInput = screen.getByRole('textbox', { name: /name/i });
|
|
@@ -1157,8 +1166,8 @@ describe('AkiformBuilder', () => {
|
|
|
1157
1166
|
const ageInput = screen.getByRole('spinbutton', { name: /age/i });
|
|
1158
1167
|
expect(ageInput).toHaveAttribute('aria-required', 'false');
|
|
1159
1168
|
expect(ageInput).toHaveAttribute('aria-invalid', 'false');
|
|
1160
|
-
});
|
|
1161
|
-
it('updates aria-invalid attribute when form is submitted with errors',
|
|
1169
|
+
}));
|
|
1170
|
+
it('updates aria-invalid attribute when form is submitted with errors', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1162
1171
|
const fields = [
|
|
1163
1172
|
{
|
|
1164
1173
|
key: 'name',
|
|
@@ -1167,20 +1176,20 @@ describe('AkiformBuilder', () => {
|
|
|
1167
1176
|
validation: akival.string().required('Name is required')
|
|
1168
1177
|
}
|
|
1169
1178
|
];
|
|
1170
|
-
|
|
1179
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1171
1180
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1172
|
-
});
|
|
1181
|
+
}));
|
|
1173
1182
|
const nameInput = screen.getByRole('textbox', { name: /name/i });
|
|
1174
1183
|
expect(nameInput).toHaveAttribute('aria-invalid', 'false');
|
|
1175
|
-
|
|
1184
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1176
1185
|
fireEvent.submit(screen.getByRole('form'));
|
|
1177
|
-
});
|
|
1178
|
-
|
|
1186
|
+
}));
|
|
1187
|
+
yield waitFor(() => {
|
|
1179
1188
|
expect(nameInput).toHaveAttribute('aria-invalid', 'true');
|
|
1180
1189
|
expect(screen.getByText('Name is required')).toBeInTheDocument();
|
|
1181
1190
|
});
|
|
1182
|
-
});
|
|
1183
|
-
it('renders field array with proper ARIA attributes',
|
|
1191
|
+
}));
|
|
1192
|
+
it('renders field array with proper ARIA attributes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1184
1193
|
const user = userEvent.setup();
|
|
1185
1194
|
const fields = [
|
|
1186
1195
|
{
|
|
@@ -1193,45 +1202,45 @@ describe('AkiformBuilder', () => {
|
|
|
1193
1202
|
]
|
|
1194
1203
|
}
|
|
1195
1204
|
];
|
|
1196
|
-
|
|
1205
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1197
1206
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1198
|
-
});
|
|
1199
|
-
|
|
1200
|
-
|
|
1207
|
+
}));
|
|
1208
|
+
yield user.click(screen.getByTestId('addresses-add-button'));
|
|
1209
|
+
yield expandCollapsable();
|
|
1201
1210
|
const fieldArrayGroup = screen.getByRole('group', { name: 'Addresses' });
|
|
1202
1211
|
expect(fieldArrayGroup).toBeInTheDocument();
|
|
1203
1212
|
const addButton = screen.getByLabelText('Add Addresses');
|
|
1204
1213
|
expect(addButton).toBeInTheDocument();
|
|
1205
|
-
|
|
1206
|
-
|
|
1214
|
+
yield user.click(addButton);
|
|
1215
|
+
yield expandCollapsable();
|
|
1207
1216
|
const removeButton = screen.getAllByLabelText('Remove Addresses')[1];
|
|
1208
1217
|
expect(removeButton).toBeInTheDocument();
|
|
1209
|
-
});
|
|
1210
|
-
it('supports keyboard navigation',
|
|
1218
|
+
}));
|
|
1219
|
+
it('supports keyboard navigation', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1211
1220
|
const user = userEvent.setup();
|
|
1212
1221
|
const fields = [
|
|
1213
1222
|
{ key: 'name', label: 'Name', type: 'text' },
|
|
1214
1223
|
{ key: 'age', label: 'Age', type: 'number' }
|
|
1215
1224
|
];
|
|
1216
|
-
|
|
1225
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1217
1226
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn(), showResetButton: true }));
|
|
1218
|
-
});
|
|
1227
|
+
}));
|
|
1219
1228
|
const nameInput = screen.getByLabelText('Name');
|
|
1220
1229
|
const ageInput = screen.getByLabelText('Age');
|
|
1221
1230
|
const submitButton = screen.getByRole('button', { name: 'SUBMIT' });
|
|
1222
1231
|
const resetButton = screen.getByRole('button', { name: 'RESET' });
|
|
1223
|
-
|
|
1232
|
+
yield user.tab();
|
|
1224
1233
|
expect(document.activeElement).toBe(nameInput);
|
|
1225
|
-
|
|
1234
|
+
yield user.tab();
|
|
1226
1235
|
expect(document.activeElement).toBe(ageInput);
|
|
1227
|
-
|
|
1236
|
+
yield user.tab();
|
|
1228
1237
|
expect(document.activeElement).toBe(submitButton);
|
|
1229
|
-
|
|
1238
|
+
yield user.tab();
|
|
1230
1239
|
expect(document.activeElement).toBe(resetButton);
|
|
1231
|
-
});
|
|
1240
|
+
}));
|
|
1232
1241
|
});
|
|
1233
1242
|
describe('AkiformBuilder with sections', () => {
|
|
1234
|
-
it('renders form with sections',
|
|
1243
|
+
it('renders form with sections', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1235
1244
|
const fields = [
|
|
1236
1245
|
field()
|
|
1237
1246
|
.key('personalInfo')
|
|
@@ -1262,9 +1271,9 @@ describe('AkiformBuilder', () => {
|
|
|
1262
1271
|
])
|
|
1263
1272
|
.build()
|
|
1264
1273
|
];
|
|
1265
|
-
|
|
1274
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1266
1275
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1267
|
-
});
|
|
1276
|
+
}));
|
|
1268
1277
|
expect(screen.getByText('Personal Information')).toBeInTheDocument();
|
|
1269
1278
|
expect(screen.getByText('Contact Information')).toBeInTheDocument();
|
|
1270
1279
|
expect(screen.getByText('Name')).toBeInTheDocument();
|
|
@@ -1277,9 +1286,9 @@ describe('AkiformBuilder', () => {
|
|
|
1277
1286
|
expect(screen.queryByLabelText('Email')).not.toBeInTheDocument();
|
|
1278
1287
|
// Expand the second section
|
|
1279
1288
|
const contactInfoSection = screen.getByText('Contact Information');
|
|
1280
|
-
|
|
1289
|
+
yield userEvent.click(contactInfoSection);
|
|
1281
1290
|
// Wait for the section to expand
|
|
1282
|
-
|
|
1291
|
+
yield waitFor(() => {
|
|
1283
1292
|
expect(screen.getByLabelText('Email')).toBeInTheDocument();
|
|
1284
1293
|
});
|
|
1285
1294
|
// Check if the Email field is now visible
|
|
@@ -1293,8 +1302,8 @@ describe('AkiformBuilder', () => {
|
|
|
1293
1302
|
// 'Email input visibility:',
|
|
1294
1303
|
// window.getComputedStyle(emailInput).display
|
|
1295
1304
|
// );
|
|
1296
|
-
});
|
|
1297
|
-
it('handles form submission with sections',
|
|
1305
|
+
}));
|
|
1306
|
+
it('handles form submission with sections', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1298
1307
|
const onSubmitMock = vi.fn();
|
|
1299
1308
|
const fields = [
|
|
1300
1309
|
field()
|
|
@@ -1313,35 +1322,35 @@ describe('AkiformBuilder', () => {
|
|
|
1313
1322
|
.fields([field().key('email').label('Email').type('text').build()])
|
|
1314
1323
|
.build()
|
|
1315
1324
|
];
|
|
1316
|
-
|
|
1325
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1317
1326
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: onSubmitMock }));
|
|
1318
|
-
});
|
|
1327
|
+
}));
|
|
1319
1328
|
// Expand both sections
|
|
1320
|
-
|
|
1321
|
-
|
|
1329
|
+
yield userEvent.click(screen.getByText('Personal Information'));
|
|
1330
|
+
yield userEvent.click(screen.getByText('Contact Information'));
|
|
1322
1331
|
// Fill in the form
|
|
1323
|
-
|
|
1332
|
+
yield userEvent.type(screen.getByLabelText('Name'), 'John Doe', {
|
|
1324
1333
|
delay: 1
|
|
1325
1334
|
});
|
|
1326
|
-
|
|
1327
|
-
|
|
1335
|
+
yield userEvent.type(screen.getByLabelText('Age'), '30', { delay: 1 });
|
|
1336
|
+
yield userEvent.type(screen.getByLabelText('Email'), 'john@example.com', {
|
|
1328
1337
|
delay: 1
|
|
1329
1338
|
});
|
|
1330
1339
|
// Wait for submit button to become interactable
|
|
1331
1340
|
const submitButton = screen.getByRole('button', { name: /submit/i });
|
|
1332
|
-
|
|
1341
|
+
yield waitFor(() => {
|
|
1333
1342
|
expect(submitButton).toBeEnabled();
|
|
1334
1343
|
});
|
|
1335
1344
|
// Submit the form
|
|
1336
|
-
|
|
1345
|
+
yield userEvent.click(submitButton);
|
|
1337
1346
|
// Validate submission
|
|
1338
1347
|
expect(onSubmitMock).toHaveBeenCalledWith({
|
|
1339
1348
|
name: 'John Doe',
|
|
1340
1349
|
age: 30,
|
|
1341
1350
|
email: 'john@example.com'
|
|
1342
1351
|
}, expect.anything());
|
|
1343
|
-
});
|
|
1344
|
-
it('handles conditional rendering within sections',
|
|
1352
|
+
}));
|
|
1353
|
+
it('handles conditional rendering within sections', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1345
1354
|
const fields = [
|
|
1346
1355
|
field()
|
|
1347
1356
|
.key('personalInfo')
|
|
@@ -1360,18 +1369,18 @@ describe('AkiformBuilder', () => {
|
|
|
1360
1369
|
.defaultExpanded(true)
|
|
1361
1370
|
.build()
|
|
1362
1371
|
];
|
|
1363
|
-
|
|
1372
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1364
1373
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1365
|
-
});
|
|
1374
|
+
}));
|
|
1366
1375
|
expect(screen.getByLabelText('Name')).toBeInTheDocument();
|
|
1367
1376
|
expect(screen.getByLabelText('Show Age')).toBeInTheDocument();
|
|
1368
1377
|
expect(screen.queryByLabelText('Age')).not.toBeInTheDocument();
|
|
1369
|
-
|
|
1370
|
-
expect(
|
|
1371
|
-
});
|
|
1378
|
+
yield userEvent.click(screen.getByLabelText('Show Age'));
|
|
1379
|
+
expect(yield screen.findByLabelText('Age')).toBeInTheDocument();
|
|
1380
|
+
}));
|
|
1372
1381
|
});
|
|
1373
1382
|
describe('AkiformBuilder with tooltip', () => {
|
|
1374
|
-
it('renders form field with tooltip as TooltipProps',
|
|
1383
|
+
it('renders form field with tooltip as TooltipProps', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1375
1384
|
const fields = [
|
|
1376
1385
|
field()
|
|
1377
1386
|
.key('name')
|
|
@@ -1380,21 +1389,21 @@ describe('AkiformBuilder', () => {
|
|
|
1380
1389
|
.tooltip({ title: 'Enter your full name', defaultOpen: true })
|
|
1381
1390
|
.build()
|
|
1382
1391
|
];
|
|
1383
|
-
|
|
1392
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1384
1393
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1385
|
-
});
|
|
1394
|
+
}));
|
|
1386
1395
|
const tooltipTrigger = screen.getByLabelText('Name');
|
|
1387
1396
|
expect(tooltipTrigger).toBeInTheDocument();
|
|
1388
1397
|
// Simulate hovering over the field to show the tooltip
|
|
1389
|
-
|
|
1398
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1390
1399
|
fireEvent.mouseEnter(tooltipTrigger);
|
|
1391
|
-
});
|
|
1400
|
+
}));
|
|
1392
1401
|
// Wait for the tooltip to appear
|
|
1393
|
-
|
|
1402
|
+
yield waitFor(() => {
|
|
1394
1403
|
expect(screen.getByText('Enter your full name')).toBeInTheDocument();
|
|
1395
1404
|
});
|
|
1396
|
-
});
|
|
1397
|
-
it('renders form field with tooltip as string',
|
|
1405
|
+
}));
|
|
1406
|
+
it('renders form field with tooltip as string', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1398
1407
|
const fields = [
|
|
1399
1408
|
field()
|
|
1400
1409
|
.key('email')
|
|
@@ -1403,19 +1412,19 @@ describe('AkiformBuilder', () => {
|
|
|
1403
1412
|
.tooltip({ title: 'Enter your full name', defaultOpen: true })
|
|
1404
1413
|
.build()
|
|
1405
1414
|
];
|
|
1406
|
-
|
|
1415
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1407
1416
|
render(React.createElement(AkiformBuilder, { fields: fields, onSubmit: vi.fn() }));
|
|
1408
|
-
});
|
|
1417
|
+
}));
|
|
1409
1418
|
const tooltipTrigger = screen.getByLabelText('Email');
|
|
1410
1419
|
expect(tooltipTrigger).toBeInTheDocument();
|
|
1411
1420
|
// Simulate hovering over the field to show the tooltip
|
|
1412
|
-
|
|
1421
|
+
yield act(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1413
1422
|
fireEvent.mouseEnter(tooltipTrigger);
|
|
1414
|
-
});
|
|
1423
|
+
}));
|
|
1415
1424
|
// Wait for the tooltip to appear
|
|
1416
|
-
|
|
1425
|
+
yield waitFor(() => {
|
|
1417
1426
|
expect(screen.getByText('Enter your full name')).toBeInTheDocument();
|
|
1418
1427
|
});
|
|
1419
|
-
});
|
|
1428
|
+
}));
|
|
1420
1429
|
});
|
|
1421
1430
|
});
|