@onehat/ui 0.4.33 → 0.4.35
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/package.json +1 -1
- package/src/Components/Editor/Editor.js +4 -2
- package/src/Components/Form/Form.js +11 -16
- package/src/Components/Grid/Grid.js +3 -2
- package/src/Components/Grid/GridRow.js +1 -1
- package/src/Components/Hoc/Secondary/withSecondaryEditor.js +51 -19
- package/src/Components/Hoc/Secondary/withSecondarySelection.js +29 -23
- package/src/Components/Hoc/withEditor.js +48 -15
- package/src/Components/Hoc/withPdfButtons.js +4 -0
- package/src/Components/Hoc/withSelection.js +24 -19
- package/src/Functions/Cypress/button_functions.js +8 -8
- package/src/Functions/Cypress/crud_functions.js +52 -3
- package/src/Functions/Cypress/dom_functions.js +53 -2
- package/src/Functions/Cypress/form_functions.js +179 -173
- package/src/Functions/Cypress/grid_functions.js +18 -9
- package/src/Functions/Cypress/utilities.js +8 -1
|
@@ -167,7 +167,7 @@ export function setTagValue(selectors, value) {
|
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
169
|
cy.get(selector).eq(0)
|
|
170
|
-
.click()
|
|
170
|
+
.click({ force: true })
|
|
171
171
|
.then(() => {
|
|
172
172
|
clickButtonsWithRemove(selector); // Recursive call for the next element
|
|
173
173
|
});
|
|
@@ -274,100 +274,100 @@ export function setInputValue(selectors, value) {
|
|
|
274
274
|
setTextValue(selectors, value);
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Given a form,
|
|
279
|
+
* return a url-encoded string representing all keys and values
|
|
280
|
+
*
|
|
281
|
+
* @param {jQuery} form
|
|
282
|
+
* @return {String}
|
|
283
|
+
* /
|
|
284
|
+
export function formSerialize(form) {
|
|
285
|
+
'use strict';
|
|
286
|
+
var i, j, len, jLen, formElement,
|
|
287
|
+
q = [],
|
|
288
|
+
theForm = form[0],
|
|
289
|
+
varCounters = {};
|
|
290
|
+
|
|
291
|
+
function addNameValue(name, value) { // create this function so I can use varCounters for
|
|
292
|
+
var matches = name.match(/([\w\d]+)\[\]/i),
|
|
293
|
+
varName,
|
|
294
|
+
ix = 0;
|
|
295
|
+
if (matches && matches[1]) {
|
|
296
|
+
varName = matches[1];
|
|
297
|
+
if (typeof varCounters[varName] === 'undefined') {
|
|
298
|
+
varCounters[varName] = ix;
|
|
299
|
+
} else {
|
|
300
|
+
ix = ++varCounters[varName];
|
|
301
|
+
}
|
|
302
|
+
name = varName + '[' + ix + ']';
|
|
303
|
+
}
|
|
304
|
+
q.push(urlencode(name) + '=' + urlencode(value));
|
|
305
|
+
}
|
|
277
306
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
//
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
//
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
//
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
// addNameValue(formElement.name, formElement.value);
|
|
343
|
-
// break;
|
|
344
|
-
// case 'select':
|
|
345
|
-
// switch (formElement.type) {
|
|
346
|
-
// case 'select-one':
|
|
347
|
-
// addNameValue(formElement.name, formElement.value);
|
|
348
|
-
// break;
|
|
349
|
-
// case 'select-multiple':
|
|
350
|
-
// for (j = 0, jLen = formElement.options.length; j < jLen; j++) {
|
|
351
|
-
// if (formElement.options[j].selected) {
|
|
352
|
-
// addNameValue(formElement.name, formElement.options[j].value);
|
|
353
|
-
// }
|
|
354
|
-
// }
|
|
355
|
-
// break;
|
|
356
|
-
// }
|
|
357
|
-
// break;
|
|
358
|
-
// case 'button': // jQuery does not submit these, though it is an HTML4 successful control
|
|
359
|
-
// switch (formElement.type) {
|
|
360
|
-
// case 'reset':
|
|
361
|
-
// case 'submit':
|
|
362
|
-
// case 'button':
|
|
363
|
-
// addNameValue(formElement.name, formElement.value);
|
|
364
|
-
// break;
|
|
365
|
-
// }
|
|
366
|
-
// break;
|
|
367
|
-
// }
|
|
368
|
-
// }
|
|
369
|
-
// return q.join('&');
|
|
370
|
-
// }
|
|
307
|
+
if (!theForm || !theForm.nodeName || theForm.nodeName.toLowerCase() !== 'form') {
|
|
308
|
+
throw 'You must supply a form element';
|
|
309
|
+
}
|
|
310
|
+
for (i = 0, len = theForm.elements.length; i < len; i++) {
|
|
311
|
+
formElement = theForm.elements[i];
|
|
312
|
+
if (formElement.name === '' || formElement.disabled) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
switch (formElement.nodeName.toLowerCase()) {
|
|
316
|
+
case 'input':
|
|
317
|
+
switch (formElement.type) {
|
|
318
|
+
case 'text':
|
|
319
|
+
case 'hidden':
|
|
320
|
+
case 'password':
|
|
321
|
+
case 'button': // Not submitted when submitting form manually, though jQuery does serialize this and it can be an HTML4 successful control
|
|
322
|
+
case 'submit':
|
|
323
|
+
addNameValue(formElement.name, formElement.value);
|
|
324
|
+
break;
|
|
325
|
+
case 'checkbox':
|
|
326
|
+
case 'radio':
|
|
327
|
+
if (formElement.checked) {
|
|
328
|
+
addNameValue(formElement.name, formElement.value);
|
|
329
|
+
} else if (formElement.value === '1') {
|
|
330
|
+
addNameValue(formElement.name, '0'); // Submit actual value of zero for booleans, instead of no value at all
|
|
331
|
+
}
|
|
332
|
+
break;
|
|
333
|
+
case 'file':
|
|
334
|
+
// addNameValue(formElement.name, formElement.value); // Will work and part of HTML4 "successful controls", but not used in jQuery
|
|
335
|
+
break;
|
|
336
|
+
case 'reset':
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
break;
|
|
340
|
+
case 'textarea':
|
|
341
|
+
addNameValue(formElement.name, formElement.value);
|
|
342
|
+
break;
|
|
343
|
+
case 'select':
|
|
344
|
+
switch (formElement.type) {
|
|
345
|
+
case 'select-one':
|
|
346
|
+
addNameValue(formElement.name, formElement.value);
|
|
347
|
+
break;
|
|
348
|
+
case 'select-multiple':
|
|
349
|
+
for (j = 0, jLen = formElement.options.length; j < jLen; j++) {
|
|
350
|
+
if (formElement.options[j].selected) {
|
|
351
|
+
addNameValue(formElement.name, formElement.options[j].value);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
case 'button': // jQuery does not submit these, though it is an HTML4 successful control
|
|
358
|
+
switch (formElement.type) {
|
|
359
|
+
case 'reset':
|
|
360
|
+
case 'submit':
|
|
361
|
+
case 'button':
|
|
362
|
+
addNameValue(formElement.name, formElement.value);
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return q.join('&');
|
|
369
|
+
}
|
|
370
|
+
*/
|
|
371
371
|
|
|
372
372
|
|
|
373
373
|
|
|
@@ -377,94 +377,100 @@ export function setInputValue(selectors, value) {
|
|
|
377
377
|
// / /_/ / __/ /_/ /_/ __/ / (__ )
|
|
378
378
|
// \____/\___/\__/\__/\___/_/ /____/
|
|
379
379
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
380
|
+
/**
|
|
381
|
+
* Get data from a form
|
|
382
|
+
* @param {object} schema - fieldName/fieldType pairs
|
|
383
|
+
* @returns {object} formValues - object of fieldName/value pairs
|
|
384
|
+
* /
|
|
385
|
+
export function getFormValues(editor, schema) {
|
|
386
|
+
const fields = editor.find('.x-form-field'),
|
|
387
|
+
formValues = {};
|
|
388
|
+
|
|
389
|
+
_.each(fields, (field) => {
|
|
390
|
+
const fieldType = schema[field.name];
|
|
391
|
+
switch(fieldType) {
|
|
392
|
+
case 'checkbox':
|
|
393
|
+
formValues[fieldName] = getCheckboxValue(fieldName);
|
|
394
|
+
break;
|
|
395
|
+
case 'combo':
|
|
396
|
+
formValues[fieldName] = getComboValue(fieldName);
|
|
397
|
+
break;
|
|
398
|
+
case 'date':
|
|
399
|
+
formValues[fieldName] = getDateValue(fieldName);
|
|
400
|
+
break;
|
|
401
|
+
case 'datetime':
|
|
402
|
+
formValues[fieldName] = getDatetimeValue(fieldName);
|
|
403
|
+
break;
|
|
404
|
+
case 'file':
|
|
405
|
+
formValues[fieldName] = getFileValue(fieldName);
|
|
406
|
+
break;
|
|
407
|
+
case 'number':
|
|
408
|
+
formValues[fieldName] = getNumberValue(fieldName);
|
|
409
|
+
break;
|
|
410
|
+
case 'radio':
|
|
411
|
+
formValues[fieldName] = getRadioValue(fieldName);
|
|
412
|
+
break;
|
|
413
|
+
case 'tag':
|
|
414
|
+
formValues[fieldName] = getTagValue(fieldName);
|
|
415
|
+
break;
|
|
416
|
+
case 'text':
|
|
417
|
+
case 'textarea':
|
|
418
|
+
formValues[fieldName] = getTextValue(fieldName);
|
|
419
|
+
break;
|
|
420
|
+
case 'time':
|
|
421
|
+
formValues[fieldName] = getTimeValue(fieldName);
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
return formValues;
|
|
426
|
+
}
|
|
427
|
+
*/
|
|
427
428
|
|
|
428
429
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Validate that form values match what they're supposed to
|
|
432
|
+
* /
|
|
433
|
+
export function validateFormValues(data, schema) {
|
|
434
|
+
cy.wrap().then(() => { // Wrap this in a Cypress promise, so it executes in correct order, relative to other Cypress promises
|
|
435
|
+
|
|
436
|
+
const formValues = getFormValues(schema);
|
|
437
|
+
let diff = deepDiffObj(formValues, data);
|
|
438
|
+
|
|
439
|
+
// SPECIAL CASE: Omit password fields from diff
|
|
440
|
+
const omitFields = [];
|
|
441
|
+
_.each(diff, (value, key) => {
|
|
442
|
+
if (key.match(/^password/i)) {
|
|
443
|
+
omitFields.push(key);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
if (omitFields.length) {
|
|
447
|
+
diff = _.omit(diff, omitFields);
|
|
448
|
+
}
|
|
448
449
|
|
|
449
|
-
//
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
450
|
+
// If there are still any differences, log them
|
|
451
|
+
if (_.keys(diff).length > 0) {
|
|
452
|
+
console.log('data', data);
|
|
453
|
+
console.log('formValues', formValues);
|
|
454
|
+
console.log('diff', diff);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
expect(diff).to.deep.equal({});
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
*/
|
|
459
461
|
|
|
460
462
|
|
|
461
463
|
|
|
462
464
|
// export function getCheckboxValue(fieldName) {
|
|
463
465
|
|
|
464
466
|
// }
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
467
|
+
export function getComboValue(selectors, fieldName) {
|
|
468
|
+
cy.log('getComboValue ' + fieldName);
|
|
469
|
+
return getDomNode([...selectors, 'field-' + fieldName, 'input']).then((field) => {
|
|
470
|
+
return cy.wrap(field)
|
|
471
|
+
.invoke('val');
|
|
472
|
+
});
|
|
473
|
+
}
|
|
468
474
|
// export function getDateValue(fieldName) {
|
|
469
475
|
|
|
470
476
|
// }
|
|
@@ -11,6 +11,15 @@ import _ from 'lodash';
|
|
|
11
11
|
const $ = Cypress.$;
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
// Get cells
|
|
15
|
+
export function getGridCellValue(gridSelector, rowId, field) {
|
|
16
|
+
cy.log('getGridCellValue ' + gridSelector + ' ' + rowId + ' ' + field);
|
|
17
|
+
const rowSelector = getGridRowSelectorById(gridSelector, rowId);
|
|
18
|
+
return getDomNode([gridSelector, rowSelector, 'cell-' + field])
|
|
19
|
+
.invoke('text');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
14
23
|
|
|
15
24
|
// Get rows
|
|
16
25
|
export function hasRowWithFieldValue(gridSelector, field, value) {
|
|
@@ -56,12 +65,16 @@ export function selectGridRowIfNotAlreadySelectedById(gridSelector, id) {
|
|
|
56
65
|
}
|
|
57
66
|
})
|
|
58
67
|
}
|
|
68
|
+
export function selectGridRowByIx(gridSelector, ix) {
|
|
69
|
+
cy.log('selectGridRowByIx ' + gridSelector + ' ' + ix);
|
|
70
|
+
|
|
71
|
+
ix++; // compensate for header row
|
|
72
|
+
getDomNode([gridSelector, '[data-ix=' + ix + ']'])
|
|
73
|
+
.click();
|
|
74
|
+
}
|
|
59
75
|
// export function selectRowWithText(grid, text) {
|
|
60
76
|
// getRowWithText(grid, text).click(5, 5);
|
|
61
77
|
// }
|
|
62
|
-
// export function selectRowWithIx(grid, ix) {
|
|
63
|
-
// getRowWithIx(grid, ix).click(5, 5);
|
|
64
|
-
// }
|
|
65
78
|
// export function cmdClickRowWithId(grid, id) {
|
|
66
79
|
// getRowWithId(grid, id).click('left', { metaKey: true });
|
|
67
80
|
// }
|
|
@@ -234,12 +247,8 @@ export function getModelFromGridSelector(gridSelector) {
|
|
|
234
247
|
}
|
|
235
248
|
export function getGridRowSelectorById(gridSelector, id) {
|
|
236
249
|
const
|
|
237
|
-
model = getModelFromGridSelector(gridSelector)
|
|
238
|
-
|
|
239
|
-
if (!model) {
|
|
240
|
-
debugger;
|
|
241
|
-
}
|
|
242
|
-
const inflected = fixInflector(Inflector.camelize(Inflector.pluralize(model)));
|
|
250
|
+
model = getModelFromGridSelector(gridSelector),
|
|
251
|
+
inflected = fixInflector(Inflector.camelize(Inflector.pluralize(model)));
|
|
243
252
|
return inflected + '-' + id;
|
|
244
253
|
}
|
|
245
254
|
|
|
@@ -12,7 +12,14 @@ export function bootstrapRouteWaiters() {
|
|
|
12
12
|
cy.intercept('POST', '**/add**').as('addWaiter');
|
|
13
13
|
cy.intercept('POST', '**/edit**').as('editWaiter');
|
|
14
14
|
cy.intercept('POST', '**/delete**').as('deleteWaiter');
|
|
15
|
-
cy.intercept('
|
|
15
|
+
cy.intercept('GET', '**/getReport**').as('getReportWaiter');
|
|
16
|
+
cy.intercept('POST', '**/getReport**').as('postReportWaiter');
|
|
17
|
+
cy.intercept('POST', '**/emailModelPdf**').as('emailModelPdf');
|
|
18
|
+
}
|
|
19
|
+
export function stubWindowOpen() { // This needs to be called after the page in question has loaded. See https://docs.cypress.io/api/commands/stub#Replace-built-in-window-methods-like-prompt
|
|
20
|
+
cy.window().then((win) => {
|
|
21
|
+
cy.stub(win, 'open').as('windowOpen');
|
|
22
|
+
});
|
|
16
23
|
}
|
|
17
24
|
export function fixInflector(str) {
|
|
18
25
|
// inflector-js doesn't handle pluralization of 'equipment' correctly
|