@onehat/ui 0.4.23 → 0.4.25

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.4.23",
3
+ "version": "0.4.25",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -10,7 +10,7 @@ import {
10
10
  Text,
11
11
  TextNative,
12
12
  Tooltip,
13
- VStack,
13
+ VStackNative,
14
14
  } from '@project-components/Gluestack';
15
15
  import {
16
16
  UI_MODE_NATIVE,
@@ -180,7 +180,7 @@ export function ComboComponent(props) {
180
180
  displayValue = _.each(value, (id) => {
181
181
  const entity = Repository.getById(id);
182
182
  if (entity) {
183
- displayValue.push(entity.displayValue)
183
+ displayValue.push(entity.displayValue);
184
184
  }
185
185
  });
186
186
  } else {
@@ -202,6 +202,9 @@ export function ComboComponent(props) {
202
202
  await Repository.waitUntilDoneLoading();
203
203
  }
204
204
  entity = Repository.getById(value);
205
+ if (!entity) {
206
+ entity = await Repository.getSingleEntityFromServer(value);
207
+ }
205
208
  }
206
209
  displayValue = entity?.displayValue || '';
207
210
  } else {
@@ -243,10 +246,12 @@ export function ComboComponent(props) {
243
246
  }
244
247
 
245
248
  let id = null;
246
- if (gridSelection.length && gridSelection[0].id) {
247
- id = gridSelection[0].id;
249
+ if (gridSelection.length) {
250
+ id = Repository ? gridSelection[0].id : gridSelection[0][idIx];
251
+ }
252
+ if (id !== value) {
253
+ setValue(id);
248
254
  }
249
- setValue(id);
250
255
  hideMenu();
251
256
  break;
252
257
  case 'ArrowDown':
@@ -444,11 +449,12 @@ export function ComboComponent(props) {
444
449
  });
445
450
  }
446
451
 
447
- setNewEntityDisplayValue(value); // capture the search query so we can tell Grid what to use for a new entity's displayValue
448
-
452
+ if (!isId) {
453
+ setNewEntityDisplayValue(value); // capture the search query so we can tell Grid what to use for a new entity's displayValue
454
+ }
449
455
  } else {
450
456
  // Search through data
451
- const regex = new RegExp('^' + value);
457
+ const regex = new RegExp('^' + value, 'i'); // case-insensitive
452
458
  found = _.filter(data, (item) => {
453
459
  if (_.isString(item[displayIx]) && _.isString(value)) {
454
460
  return item[displayIx].match(regex);
@@ -1021,7 +1027,7 @@ export function ComboComponent(props) {
1021
1027
  if (isRendered && additionalButtons?.length && containerWidth < 500) {
1022
1028
  // be responsive for small screen sizes and bump additionalButtons to the next line
1023
1029
  assembledComponents =
1024
- <VStack
1030
+ <VStackNative
1025
1031
  testID={testID}
1026
1032
  className="Combo-VStack"
1027
1033
  >
@@ -1038,11 +1044,12 @@ export function ComboComponent(props) {
1038
1044
  <HStack className="mt-1">
1039
1045
  {additionalButtons}
1040
1046
  </HStack>
1041
- </VStack>;
1047
+ </VStackNative>;
1042
1048
  } else {
1043
1049
  assembledComponents =
1044
1050
  <HStackNative
1045
1051
  {...refProps}
1052
+ testID={testID}
1046
1053
  onLayout={onLayout}
1047
1054
  className={className}
1048
1055
  >
@@ -14,7 +14,6 @@ import _ from 'lodash';
14
14
 
15
15
  const InputElement = forwardRef((props, ref) => {
16
16
  let { // so localValue can be changed, if needed
17
- testID,
18
17
  value,
19
18
  setValue,
20
19
  maxLength,
@@ -1,7 +1,7 @@
1
1
  import { useRef, } from 'react';
2
2
  import {
3
3
  HStack,
4
- VStack,
4
+ VStackNative,
5
5
  } from '@project-components/Gluestack';
6
6
  import {
7
7
  EDITOR_TYPE__WINDOWED,
@@ -27,6 +27,7 @@ function TagComponent(props) {
27
27
  Editor,
28
28
  _combo = {},
29
29
  tooltip,
30
+ testID,
30
31
 
31
32
  // parent Form
32
33
  onChangeValue,
@@ -301,7 +302,8 @@ function TagComponent(props) {
301
302
  }
302
303
  }
303
304
 
304
- return <VStack
305
+ return <VStackNative
306
+ testID={testID}
305
307
  className={className}
306
308
  style={style}
307
309
  >
@@ -322,7 +324,7 @@ function TagComponent(props) {
322
324
  {..._combo}
323
325
  className={comboClassName}
324
326
  />}
325
- </VStack>;
327
+ </VStackNative>;
326
328
 
327
329
  }
328
330
 
@@ -17,6 +17,7 @@ const
17
17
  onChangeText,
18
18
  placeholder,
19
19
  minimizeForRow = false,
20
+ testID,
20
21
  } = props,
21
22
  value = _.isNil(props.value) ? '' : props.value, // null value may not actually reset this TextArea, so set it explicitly to empty string
22
23
  styles = UiGlobals.styles,
@@ -95,6 +96,7 @@ const
95
96
 
96
97
  return <Textarea className={textareaClassName}>
97
98
  <TextareaInput
99
+ testID={testID}
98
100
  ref={props.outerRef}
99
101
  onChangeText={onChangeTextLocal}
100
102
  value={localValue}
@@ -97,6 +97,7 @@ function withAlert(WrappedComponent) {
97
97
  }
98
98
  }
99
99
  showModal({
100
+ testID: 'AlertModal',
100
101
  title,
101
102
  body: getBody({
102
103
  icon: TriangleExclamation,
@@ -119,6 +120,7 @@ function withAlert(WrappedComponent) {
119
120
  onConfirm = (message, onYes, includeCancel = false, onNo) => {
120
121
  hideModal();
121
122
  showModal({
123
+ testID: 'ConfirmModal',
122
124
  title: 'Confirm',
123
125
  body: getBody({
124
126
  icon: CircleQuestion,
@@ -142,6 +144,7 @@ function withAlert(WrappedComponent) {
142
144
  onInfo = (message) => {
143
145
  hideModal();
144
146
  showModal({
147
+ testID: 'InfoModal',
145
148
  title: 'Info',
146
149
  body: getBody({
147
150
  icon: CircleInfo,
@@ -36,6 +36,7 @@ export default function withModal(WrappedComponent) {
36
36
  [customButtons, setCustomButtons] = useState(),
37
37
  [body, setBody] = useState(),
38
38
  [whichModal, setWhichModal] = useState(),
39
+ [testID, setTestID] = useState('Modal'),
39
40
  autoFocusRef = useRef(null),
40
41
  cancelRef = useRef(null),
41
42
  [windowWidth, windowHeight] = useAdjustedWindowSize(w, h),
@@ -59,6 +60,7 @@ export default function withModal(WrappedComponent) {
59
60
  h = null,
60
61
  w = null,
61
62
  whichModal = null,
63
+ testID = null,
62
64
  formProps = null, // deprecated
63
65
  } = args;
64
66
 
@@ -83,6 +85,9 @@ export default function withModal(WrappedComponent) {
83
85
  setWidth(w); // || 400
84
86
  setWhichModal(whichModal);
85
87
  setIsModalShown(true);
88
+ if (testID) {
89
+ setTestID(testID);
90
+ }
86
91
  },
87
92
  updateModalBody = (newBody) => {
88
93
  setBody(newBody);
@@ -185,6 +190,7 @@ export default function withModal(WrappedComponent) {
185
190
  isOpen={true}
186
191
  onClose={onCancel}
187
192
  className="withModal-Modal"
193
+ {...testProps(testID)}
188
194
  >
189
195
  <ModalBackdrop className="withModal-ModalBackdrop" />
190
196
  {modalBody}
@@ -1,11 +1,14 @@
1
1
  import {
2
2
  Box,
3
- ButtonText,
3
+ HStack,
4
4
  Icon,
5
5
  Modal, ModalBackdrop, ModalHeader, ModalContent, ModalCloseButton, ModalBody, ModalFooter,
6
6
  Text,
7
7
  } from '@project-components/Gluestack';
8
- import Button from '../Buttons/Button';
8
+ import useAdjustedWindowSize from '../../Hooks/useAdjustedWindowSize.js';
9
+ import Button from '../Buttons/Button.js';
10
+ import Panel from '../Panel/Panel.js';
11
+ import Footer from '../Layout/Footer.js';
9
12
  import testProps from '../../Functions/testProps.js';
10
13
  import TriangleExclamation from '../Icons/TriangleExclamation.js';
11
14
 
@@ -14,33 +17,75 @@ export default function ErrorMessage(props) {
14
17
  text = 'Error',
15
18
  color = 'red-500',
16
19
  onOk,
17
- } = props;
20
+ } = props,
21
+ [width, height] = useAdjustedWindowSize(500, 250);
18
22
 
19
23
  return <Modal isOpen={true} {...props} {...testProps('ErrorMessage')}>
20
24
  <ModalBackdrop />
21
- <ModalContent>
22
- <ModalHeader>Alert</ModalHeader>
23
- <ModalBody
24
- className={`
25
- flex-row
26
- align-center
25
+
26
+ <Panel
27
+ title="Alert"
28
+ isCollapsible={false}
29
+ className="bg-white overflow-auto"
30
+ h={height}
31
+ w={width}
32
+ isWindow={true}
33
+ disableAutoFlex={true}
34
+ onClose={onOk}
35
+ footer={<Footer
36
+ className={`
37
+ justify-end
38
+ py-2
39
+ px-4
40
+ bg-grey-100
41
+ `}
42
+ >
43
+ <Button
44
+ {...testProps('okBtn')}
45
+ key="okBtn"
46
+ onPress={onOk}
47
+ text="OK"
48
+ className="text-white"
49
+ />
50
+ </Footer>}
51
+ >
52
+ <HStack className="ErrorMessage-HStack flex-1 w-full p-4">
53
+ <Box className={`
54
+ ErrorMessage-Box1
55
+ h-full
56
+ w-[100px]
57
+ flex
58
+ items-center
59
+ justify-center
60
+ pr-3
61
+ `}>
62
+ <Icon as={TriangleExclamation} className={`
63
+ ErrorMessage-Icon
64
+ h-[40px]
65
+ w-[40px]
66
+ text-${color}
67
+ `} />
68
+ </Box>
69
+ <Box className={`
70
+ ErrorMessage-Box2
71
+ h-full
72
+ flex
73
+ flex-1
74
+ items-start
27
75
  justify-center
28
- p-3
29
- bg-white
30
- border-t-0
31
- rounded-md
32
- `}
33
- >
34
- <Box className="w-[50px] mx-1">
35
- <Icon as={TriangleExclamation} size="10" className="text-red-500" />
76
+ overflow-hidden
77
+ `}>
78
+ <Text className={`
79
+ ErrorMessage-Text
80
+ text-${color}
81
+ text-[18px]
82
+ break-words
83
+ whitespace-normal
84
+ w-full
85
+ overflow-auto
86
+ `}>{text}</Text>
36
87
  </Box>
37
- <Text className={` text-${color} flex-1 text-[18px] `}>{text}</Text>
38
- </ModalBody>
39
- <ModalFooter className="py-2 pr-4">
40
- <Button onPress={onOk} className="text-primary-800">
41
- <ButtonText>OK</ButtonText>
42
- </Button>
43
- </ModalFooter>
44
- </ModalContent>
88
+ </HStack>
89
+ </Panel>
45
90
  </Modal>;
46
91
  }
@@ -1,4 +1,4 @@
1
-
1
+ import 'cypress-if'; // for clickButtonIfExists only!
2
2
  import {
3
3
  getDomNode,
4
4
  getDomNodes,
@@ -8,78 +8,110 @@ const $ = Cypress.$;
8
8
 
9
9
 
10
10
  export function clickAddButton(parentSelectors) {
11
+ cy.log('clickAddButton');
11
12
  return clickButton(parentSelectors, 'addBtn');
12
13
  }
13
14
  export function clickSaveButton(parentSelectors) {
15
+ cy.log('clickSaveButton');
14
16
  return clickButton(parentSelectors, 'saveBtn');
15
17
  }
16
18
  export function clickEditButton(parentSelectors) {
19
+ cy.log('clickEditButton');
17
20
  return clickButton(parentSelectors, 'editBtn');
18
21
  }
19
22
  export function clickDeleteButton(parentSelectors) {
23
+ cy.log('clickDeleteButton');
20
24
  return clickButton(parentSelectors, 'deleteBtn');
21
25
  }
22
26
  export function clickDuplicateButton(parentSelectors) {
27
+ cy.log('clickDuplicateButton');
23
28
  return clickButton(parentSelectors, 'duplicateBtn');
24
29
  }
25
30
  export function clickReloadButton(parentSelectors) {
31
+ cy.log('clickReloadButton');
26
32
  return clickButton(parentSelectors, 'reloadBtn');
27
33
  }
28
34
  export function clickCloseButton(parentSelectors) {
35
+ cy.log('clickCloseButton');
29
36
  return clickButton(parentSelectors, 'closeBtn');
30
37
  }
31
38
  export function clickCancelButton(parentSelectors) {
39
+ cy.log('clickCancelButton');
32
40
  return clickButton(parentSelectors, 'cancelBtn');
33
41
  }
34
42
  export function clickOkButton(parentSelectors) {
43
+ cy.log('clickOkButton');
35
44
  return clickButton(parentSelectors, 'okBtn');
36
45
  }
37
46
  export function clickYesButton(parentSelectors) {
47
+ cy.log('clickYesButton');
38
48
  return clickButton(parentSelectors, 'yesBtn');
39
49
  }
40
50
  export function clickNoButton(parentSelectors) {
51
+ cy.log('clickNoButton');
41
52
  return clickButton(parentSelectors, 'noBtn');
42
53
  }
43
54
  export function clickExpandButton(parentSelectors) {
55
+ cy.log('clickExpandButton');
44
56
  return clickButton(parentSelectors, 'expandBtn');
45
57
  }
46
58
  export function clickXButton(parentSelectors) {
59
+ cy.log('clickXButton');
47
60
  return clickButton(parentSelectors, 'xBtn');
48
61
  }
62
+ export function clickXButtonIfEnabled(parentSelectors) {
63
+ cy.log('clickXButtonIfEnabled');
64
+ return clickButtonIfEnabled(parentSelectors, 'xBtn', true);
65
+ }
49
66
  export function clickTrigger(parentSelectors) {
67
+ cy.log('clickTrigger');
50
68
  return clickButton(parentSelectors, 'trigger');
51
69
  }
52
70
  export function clickToEditButton(parentSelectors) {
71
+ cy.log('clickToEditButton');
53
72
  return clickButton(parentSelectors, 'toEditBtn');
54
73
  }
55
74
  export function clickToEditButtonIfExists(parentSelectors) {
75
+ cy.log('clickToEditButtonIfExists');
56
76
  return clickButtonIfExists(parentSelectors, 'toEditBtn');
57
77
  }
58
78
  export function clickToViewButton(parentSelectors) {
79
+ cy.log('clickToViewButton');
59
80
  return clickButton(parentSelectors, 'toViewBtn');
60
81
  }
61
82
  export function clickToViewButtonIfExists(parentSelectors) {
83
+ cy.log('clickToViewButtonIfExists');
62
84
  return clickButtonIfExists(parentSelectors, 'toViewBtn');
63
85
  }
64
86
  export function toFullMode(parentSelectors) {
65
- return clickButton(parentSelectors, 'fullModeBtn');
87
+ cy.log('toFullMode');
88
+ return clickButtonIfEnabled(parentSelectors, 'fullModeBtn');
66
89
  }
67
90
  export function toSideMode(parentSelectors) {
68
- return clickButton(parentSelectors, 'sideModeBtn');
91
+ cy.log('toSideMode');
92
+ return clickButtonIfEnabled(parentSelectors, 'sideModeBtn');
93
+ }
94
+ export function clickButton(parentSelectors, name) { // requires the button to be enabled
95
+ if (_.isString(parentSelectors)) {
96
+ parentSelectors = [parentSelectors];
97
+ }
98
+ cy.log('clickButton ' + name);
99
+ return getDomNode([...parentSelectors, name])
100
+ .should('not.have.attr', 'data-disabled', 'true') // Check that the element is not disabled
101
+ .click({ force: true });
69
102
  }
70
- export function clickButton(parentSelectors, name) {
103
+ export function clickButtonIfEnabled(parentSelectors, name) { // allows button to be disabled
71
104
  if (_.isString(parentSelectors)) {
72
105
  parentSelectors = [parentSelectors];
73
106
  }
74
107
  return getDomNode([...parentSelectors, name])
75
- // .scrollIntoView()
76
108
  .click({ force: true });
77
109
  }
78
110
  export function clickButtonIfExists(parentSelectors, name) {
79
111
  if (_.isString(parentSelectors)) {
80
112
  parentSelectors = [parentSelectors];
81
113
  }
82
- return getDomNode([...parentSelectors, name]).then((node) => {
114
+ return getDomNode([...parentSelectors, name]).if().then((node) => { // NOTE if() is a cypress-if function
83
115
  if (node) {
84
116
  node.click();
85
117
  }
@@ -5,6 +5,7 @@ import {
5
5
 
6
6
 
7
7
  export function markForPageReload() {
8
+ cy.log('markForPageReload');
8
9
  // See https://github.com/cypress-io/cypress/issues/1805#issuecomment-525482440
9
10
  cy.window()
10
11
  .then((win) => {
@@ -12,11 +13,13 @@ export function markForPageReload() {
12
13
  });
13
14
  }
14
15
  export function waitForPageReload() {
16
+ cy.log('waitForPageReload');
15
17
  // See https://github.com/cypress-io/cypress/issues/1805#issuecomment-525482440
16
18
  cy.window({ timeout: 30000 })
17
19
  .should('not.have.prop', 'beforeReload');
18
20
  }
19
21
  export function waitForNavigationTo(url) {
22
+ cy.log('waitForNavigationTo ' + url);
20
23
  return cy.location('pathname', { timeout: 30000 })
21
24
  .should('include', url);
22
25
  }
@@ -30,10 +33,12 @@ export function waitForNavigationTo(url) {
30
33
  // /_/ /_/\___/____/____/\__,_/\__, /\___/_____/\____/_/|_|
31
34
  // /____/
32
35
  export function clickMessageBoxDefaultButton() {
33
- getDomNode(['AlertDialogue', 'okBtn'])
36
+ cy.log('clickMessageBoxDefaultButton');
37
+ getDomNode(['AlertModal', 'okBtn'])
34
38
  .click();
35
39
  }
36
40
  export function verifyNoErrorBox() {
41
+ cy.log('verifyNoErrorBox');
37
42
  getDomNode('ErrorMessage', { timeout: 1000 })
38
43
  .should('not.exist', 'Error dialogue popped up.');
39
44
  }
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  fixInflector,
3
3
  getLastPartOfPath,
4
+ bootstrapRouteWaiters,
4
5
  } from './utilities.js';
5
6
  import {
6
7
  login,
@@ -81,9 +82,7 @@ export const FULL = 'FULL';
81
82
 
82
83
  // Form fields
83
84
  export function crudCombo(selector, newData, editData, schema, ancillaryData, level = 0) {
84
- cy.then(() => {
85
- Cypress.log({ name: 'crudCombo' });
86
- });
85
+ cy.log('crudCombo');
87
86
 
88
87
  const
89
88
  fieldName = selector[1].match(/^field-(.*)$/)[1],
@@ -96,9 +95,7 @@ export function crudCombo(selector, newData, editData, schema, ancillaryData, le
96
95
  clickTrigger(selector);
97
96
  }
98
97
  export function crudTag(selector, newData, editData, schema, ancillaryData, level = 0) {
99
- cy.then(() => {
100
- Cypress.log({ name: 'crudTag' });
101
- });
98
+ cy.log('crudTag');
102
99
 
103
100
  const
104
101
  fieldName = selector[1].match(/^field-(.*)$/)[1],
@@ -114,9 +111,7 @@ export function crudTag(selector, newData, editData, schema, ancillaryData, leve
114
111
  clickTrigger(selector);
115
112
  }
116
113
  export function crudJson(selector, newData, editData, schema, ancillaryData, level = 0) {
117
- cy.then(() => {
118
- Cypress.log({ name: 'crudJson' });
119
- });
114
+ cy.log('crudJson');
120
115
 
121
116
  // do nothing for now
122
117
  }
@@ -125,9 +120,7 @@ export function crudJson(selector, newData, editData, schema, ancillaryData, lev
125
120
  // Grid
126
121
  export function crudWindowedGridRecord(gridSelector, newData, editData, schema, ancillaryData, level = 0) {
127
122
 
128
- cy.then(() => {
129
- Cypress.log({ name: 'crudWindowedGridRecord ' + gridSelector });
130
- });
123
+ cy.log('crudWindowedGridRecord ' + gridSelector);
131
124
 
132
125
  getDomNode(gridSelector).scrollIntoView();
133
126
 
@@ -136,9 +129,7 @@ export function crudWindowedGridRecord(gridSelector, newData, editData, schema,
136
129
 
137
130
  cy.get('@id' + level).then((id) => {
138
131
 
139
- cy.then(() => {
140
- Cypress.log({ name: 'crudWindowedGridRecord: continue thru CRUD ' + gridSelector });
141
- });
132
+ cy.log('crudWindowedGridRecord: continue thru CRUD ' + gridSelector);
142
133
 
143
134
  // read
144
135
  clickReloadButton(gridSelector);
@@ -156,9 +147,7 @@ export function crudWindowedGridRecord(gridSelector, newData, editData, schema,
156
147
  }
157
148
  export function crudInlineGridRecord(gridSelector, newData, editData, schema, ancillaryData, level = 0) {
158
149
 
159
- cy.then(() => {
160
- Cypress.log({ name: 'crudInlineGridRecord ' + gridSelector });
161
- });
150
+ cy.log('crudInlineGridRecord ' + gridSelector);
162
151
 
163
152
  getDomNode(gridSelector).scrollIntoView();
164
153
 
@@ -167,9 +156,7 @@ export function crudInlineGridRecord(gridSelector, newData, editData, schema, an
167
156
 
168
157
  cy.get('@id' + level).then((id) => {
169
158
 
170
- cy.then(() => {
171
- Cypress.log({ name: 'crudWindowedGridRecord: continue thru CRUD ' + gridSelector });
172
- });
159
+ cy.log('crudWindowedGridRecord: continue thru CRUD ' + gridSelector);
173
160
 
174
161
  // read
175
162
  clickReloadButton(gridSelector);
@@ -189,9 +176,7 @@ export function crudSideGridRecord(gridSelector, newData, editData, schema, anci
189
176
  // NOTE: the 'level' arg allows this fn to be called recursively
190
177
  // and to use the @id alias correctly, keeping track of the level of recursion
191
178
  // so the CRUD operations don't step on each other at different levels.
192
- cy.then(() => {
193
- Cypress.log({ name: 'crudSideGridRecord ' + gridSelector });
194
- });
179
+ cy.log('crudSideGridRecord ' + gridSelector);
195
180
 
196
181
  getDomNode(gridSelector).scrollIntoView();
197
182
 
@@ -216,16 +201,18 @@ export function crudSideGridRecord(gridSelector, newData, editData, schema, anci
216
201
  }
217
202
  export function addGridRecord(gridSelector, fieldValues, schema, ancillaryData, level = 0) {
218
203
 
219
- cy.then(() => {
220
- Cypress.log({ name: 'addGridRecord ' + gridSelector });
221
- });
204
+ cy.log('addGridRecord ' + gridSelector);
222
205
 
223
206
  const
224
207
  editorSelector = gridSelector + '/editor',
225
208
  viewerSelector = editorSelector + '/viewer',
226
- formSelector = editorSelector + '/form';
209
+ formSelector = editorSelector + '/form',
210
+ isRemotePhantomMode = schema.repository.isRemotePhantomMode;
227
211
 
228
212
  clickAddButton(gridSelector);
213
+ if (isRemotePhantomMode) {
214
+ cy.wait('@addWaiter');
215
+ }
229
216
  getDomNode(formSelector).should('exist');
230
217
 
231
218
  fillForm(formSelector, fieldValues, schema, level +1);
@@ -233,12 +220,11 @@ export function addGridRecord(gridSelector, fieldValues, schema, ancillaryData,
233
220
  // TODO: Change this to wait until save button is enabled
234
221
 
235
222
  let method = 'add';
236
- if (schema.repository.isRemotePhantomMode) {
223
+ if (isRemotePhantomMode) {
237
224
  method = 'edit';
238
225
  }
239
- cy.intercept('POST', '**/' + method + '**').as('waiter');
240
226
  clickSaveButton(formSelector); // it's labeled 'Add' in the form, but is really the save button
241
- cy.wait('@waiter');
227
+ cy.wait('@' + method + 'Waiter');
242
228
 
243
229
  verifyNoErrorBox();
244
230
 
@@ -262,8 +248,11 @@ export function addGridRecord(gridSelector, fieldValues, schema, ancillaryData,
262
248
  schema = data.schema,
263
249
  newData = data.newData,
264
250
  editData = data.editData,
265
- ancillaryData = data.ancillaryData,
266
- ancillaryGridSelector = formSelector + '/' + (gridType || Models + 'GridEditor');
251
+ ancillaryData = data.ancillaryData;
252
+ let ancillaryGridSelector = formSelector + '/' + (gridType || Models + 'GridEditor');
253
+ if (ancillaryGridSelector.match(/^(.*)Side(A|B)(.*)$/)) {
254
+ ancillaryGridSelector = ancillaryGridSelector.replace(/^(.*)Side(A|B)(.*)$/, '$1$3Side$2');
255
+ }
267
256
  crudWindowedGridRecord(ancillaryGridSelector, newData, editData, schema, ancillaryData, level+1);
268
257
  });
269
258
  }
@@ -271,15 +260,11 @@ export function addGridRecord(gridSelector, fieldValues, schema, ancillaryData,
271
260
  export function addWindowedGridRecord(gridSelector, fieldValues, schema, ancillaryData, level = 0) {
272
261
  // adds the record as normal, then closes the editor window
273
262
 
274
- cy.then(() => {
275
- Cypress.log({ name: 'addWindowedGridRecord ' + gridSelector });
276
- });
263
+ cy.log('addWindowedGridRecord ' + gridSelector);
277
264
 
278
265
  addGridRecord(gridSelector, fieldValues, schema, ancillaryData, level);
279
266
 
280
- cy.then(() => {
281
- Cypress.log({ name: 'addWindowedGridRecord: close window ' + gridSelector });
282
- });
267
+ cy.log('addWindowedGridRecord: close window ' + gridSelector);
283
268
  const formSelector = gridSelector + '/editor/form';
284
269
  clickCloseButton(formSelector);
285
270
  cy.wait(500); // allow window to close
@@ -288,25 +273,18 @@ export function addWindowedGridRecord(gridSelector, fieldValues, schema, ancilla
288
273
  export function addInlineGridRecord(gridSelector, fieldValues, schema, ancillaryData, level = 0) {
289
274
  // adds the record as normal, then closes the editor window
290
275
 
291
- cy.then(() => {
292
- Cypress.log({ name: 'addInlineGridRecord ' + gridSelector });
293
- });
276
+ cy.log('addInlineGridRecord ' + gridSelector);
294
277
 
295
- addGridRecord(gridSelector, fieldValues, schema, ancillaryData, level);
278
+ addGridRecord(gridSelector, fieldValues, schema, [], level); // NOTE: ancillaryData is not passed to addGridRecord because can't edit ancillary data in an inline editor
296
279
 
297
- cy.then(() => {
298
- Cypress.log({ name: 'addWindowedGridRecord: close window ' + gridSelector });
299
- });
280
+ cy.log('addWindowedGridRecord: close window ' + gridSelector);
300
281
  const formSelector = gridSelector + '/editor/form';
301
282
  clickCloseButton(formSelector);
302
283
  cy.wait(500); // allow window to close
303
284
  // TODO: Change this to wait until window is closed
304
285
  }
305
286
  export function editGridRecord(gridSelector, fieldValues, schema, id, level = 0, whichEditor = WINDOWED) {
306
-
307
- cy.then(() => {
308
- Cypress.log({ name: 'editGridRecord ' + gridSelector + ' ' + id});
309
- });
287
+ cy.log('editGridRecord ' + gridSelector + ' ' + id);
310
288
 
311
289
  selectGridRowIfNotAlreadySelectedById(gridSelector, id);
312
290
 
@@ -316,11 +294,11 @@ export function editGridRecord(gridSelector, fieldValues, schema, id, level = 0,
316
294
  formSelector = editorSelector + '/form';
317
295
 
318
296
  if (whichEditor === SIDE) {
319
- Cypress.log({ name: 'switch to Edit mode if necessary ' + viewerSelector});
297
+ cy.log('switch to Edit mode if necessary ' + viewerSelector);
320
298
  clickToEditButtonIfExists(viewerSelector);
321
299
  } else {
322
300
  // windowed or inline editor
323
- Cypress.log({ name: 'click editBtn ' + gridSelector});
301
+ cy.log('click editBtn ' + gridSelector);
324
302
  clickEditButton(gridSelector);
325
303
  }
326
304
  cy.wait(1500); // allow form to build
@@ -329,10 +307,9 @@ export function editGridRecord(gridSelector, fieldValues, schema, id, level = 0,
329
307
  fillForm(formSelector, fieldValues, schema, level +1);
330
308
  cy.wait(500); // allow validator to enable save button
331
309
  // TODO: Change this to wait until save button is enabled
332
-
333
- cy.intercept('POST', '**/edit**').as('waiter');
310
+
334
311
  clickSaveButton(formSelector);
335
- cy.wait('@waiter');
312
+ cy.wait('@editWaiter');
336
313
 
337
314
  verifyNoErrorBox();
338
315
  // cy.wait(1000);
@@ -341,9 +318,7 @@ export function editGridRecord(gridSelector, fieldValues, schema, id, level = 0,
341
318
  export function editWindowedGridRecord(gridSelector, fieldValues, schema, id, level = 0) {
342
319
  // edits the record as normal, then closes the editor window
343
320
 
344
- cy.then(() => {
345
- Cypress.log({ name: 'editWindowedGridRecord ' + gridSelector + ' ' + id});
346
- });
321
+ cy.log('editWindowedGridRecord ' + gridSelector + ' ' + id);
347
322
 
348
323
  editGridRecord(gridSelector, fieldValues, schema, id, level, WINDOWED);
349
324
 
@@ -355,9 +330,7 @@ export function editWindowedGridRecord(gridSelector, fieldValues, schema, id, le
355
330
  export function editInlineGridRecord(gridSelector, fieldValues, schema, id, level = 0) {
356
331
  // edits the record as normal, then closes the editor window
357
332
 
358
- cy.then(() => {
359
- Cypress.log({ name: 'editWindowedGridRecord ' + gridSelector + ' ' + id});
360
- });
333
+ cy.log('editWindowedGridRecord ' + gridSelector + ' ' + id);
361
334
 
362
335
  editGridRecord(gridSelector, fieldValues, schema, id, level, INLINE);
363
336
 
@@ -367,27 +340,21 @@ export function editInlineGridRecord(gridSelector, fieldValues, schema, id, leve
367
340
  // TODO: Change this to wait until window is closed
368
341
  }
369
342
  export function deleteGridRecord(gridSelector, id) {
370
-
371
- cy.then(() => {
372
- Cypress.log({ name: 'deleteGridRecord ' + gridSelector + ' ' + id });
373
- });
343
+ cy.log('deleteGridRecord ' + gridSelector + ' ' + id);
374
344
 
375
345
  selectGridRowIfNotAlreadySelectedById(gridSelector, id);
376
346
  clickDeleteButton(gridSelector);
377
347
  cy.wait(500); // allow confirmation box to appear
378
348
 
379
349
  // Click OK on confirmation box
380
- cy.intercept('POST', '**/delete**').as('waiter');
381
- clickYesButton('AlertDialog');
382
- cy.wait('@waiter');
350
+ clickYesButton('ConfirmModal');
351
+ cy.wait('@deleteWaiter');
383
352
 
384
353
  verifyNoErrorBox();
385
354
  // cy.wait(1000);
386
355
  }
387
356
  export function switchToEditModeIfNecessary(editorSelector) {
388
- cy.then(() => {
389
- Cypress.log({ name: 'switchToEditModeIfNecessary ' + editorSelector });
390
- });
357
+ cy.log('switchToEditModeIfNecessary ' + editorSelector);
391
358
 
392
359
  getDomNode(editorSelector).then((editor) => {
393
360
  const btn = editor.find('.toEditBtn');
@@ -399,9 +366,7 @@ export function switchToEditModeIfNecessary(editorSelector) {
399
366
  });
400
367
  }
401
368
  export function switchToViewModeIfNecessary(editorSelector) {
402
- cy.then(() => {
403
- Cypress.log({ name: 'switchToViewModeIfNecessary ' + editorSelector });
404
- });
369
+ cy.log('switchToViewModeIfNecessary ' + editorSelector);
405
370
 
406
371
  getDomNode(editorSelector).then((editor) => {
407
372
  const btn = editor.find('.toViewBtn');
@@ -417,9 +382,7 @@ export function switchToViewModeIfNecessary(editorSelector) {
417
382
  // Tree
418
383
  export function crudWindowedTreeRecord(treeSelector, newData, editData, schema, ancillaryData, level = 0) {
419
384
 
420
- cy.then(() => {
421
- Cypress.log({ name: 'crudWindowedTreeRecord ' + treeSelector });
422
- });
385
+ cy.log('crudWindowedTreeRecord ' + treeSelector);
423
386
 
424
387
  getDomNode(treeSelector).scrollIntoView();
425
388
 
@@ -428,9 +391,7 @@ export function crudWindowedTreeRecord(treeSelector, newData, editData, schema,
428
391
 
429
392
  cy.get('@id' + level).then((id) => {
430
393
 
431
- cy.then(() => {
432
- Cypress.log({ name: 'crudWindowedTreeRecord: continue thru CRUD ' + treeSelector });
433
- });
394
+ cy.log('crudWindowedTreeRecord: continue thru CRUD ' + treeSelector);
434
395
 
435
396
  // read
436
397
  clickReloadButton(treeSelector);
@@ -450,9 +411,7 @@ export function crudSideTreeRecord(treeSelector, newData, editData, schema, anci
450
411
  // NOTE: the 'level' arg allows this fn to be called recursively
451
412
  // and to use the @id alias correctly, keeping track of the level of recursion
452
413
  // so the CRUD operations don't step on each other at different levels.
453
- cy.then(() => {
454
- Cypress.log({ name: 'crudSideTreeRecord ' + treeSelector });
455
- });
414
+ cy.log('crudSideTreeRecord ' + treeSelector);
456
415
 
457
416
  getDomNode(treeSelector).scrollIntoView();
458
417
 
@@ -477,9 +436,7 @@ export function crudSideTreeRecord(treeSelector, newData, editData, schema, anci
477
436
  }
478
437
  export function addTreeRecord(treeSelector, fieldValues, schema, ancillaryData, level = 0) {
479
438
 
480
- cy.then(() => {
481
- Cypress.log({ name: 'addTreeRecord ' + treeSelector });
482
- });
439
+ cy.log('addTreeRecord ' + treeSelector);
483
440
 
484
441
  const
485
442
  editorSelector = treeSelector + '/editor',
@@ -508,9 +465,8 @@ export function addTreeRecord(treeSelector, fieldValues, schema, ancillaryData,
508
465
  if (schema.repository.isRemotePhantomMode) {
509
466
  method = 'edit';
510
467
  }
511
- cy.intercept('POST', '**/' + method + '**').as('waiter');
512
468
  clickSaveButton(formSelector); // it's labeled 'Add' in the form, but is really the save button
513
- cy.wait('@waiter');
469
+ cy.wait('@' + method + 'Waiter');
514
470
 
515
471
  verifyNoErrorBox();
516
472
 
@@ -534,8 +490,11 @@ export function addTreeRecord(treeSelector, fieldValues, schema, ancillaryData,
534
490
  schema = data.schema,
535
491
  newData = data.newData,
536
492
  editData = data.editData,
537
- ancillaryData = data.ancillaryData,
538
- ancillaryGridSelector = formSelector + '/' + (gridType || Models + 'GridEditor');
493
+ ancillaryData = data.ancillaryData;
494
+ let ancillaryGridSelector = formSelector + '/' + (gridType || Models + 'GridEditor');
495
+ if (ancillaryGridSelector.match(/^(.*)Side(A|B)(.*)$/)) {
496
+ ancillaryGridSelector = ancillaryGridSelector.replace(/^(.*)Side(A|B)(.*)$/, '$1$3Side$2');
497
+ }
539
498
  crudWindowedGridRecord(ancillaryGridSelector, newData, editData, schema, ancillaryData, level+1);
540
499
  });
541
500
  }
@@ -543,15 +502,11 @@ export function addTreeRecord(treeSelector, fieldValues, schema, ancillaryData,
543
502
  export function addWindowedTreeRecord(treeSelector, fieldValues, schema, ancillaryData, level = 0) {
544
503
  // adds the record as normal, then closes the editor window
545
504
 
546
- cy.then(() => {
547
- Cypress.log({ name: 'addWindowedTreeRecord ' + treeSelector });
548
- });
505
+ cy.log('addWindowedTreeRecord ' + treeSelector);
549
506
 
550
507
  addTreeRecord(treeSelector, fieldValues, schema, ancillaryData, level);
551
508
 
552
- cy.then(() => {
553
- Cypress.log({ name: 'addWindowedTreeRecord: close window ' + treeSelector });
554
- });
509
+ cy.log('addWindowedTreeRecord: close window ' + treeSelector);
555
510
  const formSelector = treeSelector + '/editor/form';
556
511
  clickCloseButton(formSelector);
557
512
  cy.wait(500); // allow window to close
@@ -559,9 +514,7 @@ export function addWindowedTreeRecord(treeSelector, fieldValues, schema, ancilla
559
514
  }
560
515
  export function editTreeRecord(treeSelector, fieldValues, schema, id, level = 0, whichEditor = WINDOWED) {
561
516
 
562
- cy.then(() => {
563
- Cypress.log({ name: 'editTreeRecord ' + treeSelector + ' ' + id});
564
- });
517
+ cy.log('editTreeRecord ' + treeSelector + ' ' + id);
565
518
 
566
519
  selectTreeNodeIfNotAlreadySelectedById(treeSelector, id);
567
520
 
@@ -571,10 +524,10 @@ export function editTreeRecord(treeSelector, fieldValues, schema, id, level = 0,
571
524
  formSelector = editorSelector + '/form';
572
525
 
573
526
  if (whichEditor === SIDE) {
574
- Cypress.log({ name: 'switch to Edit mode if necessary ' + viewerSelector});
527
+ cy.log('switch to Edit mode if necessary ' + viewerSelector);
575
528
  clickToEditButtonIfExists(viewerSelector);
576
529
  } else {
577
- Cypress.log({ name: 'click editBtn ' + treeSelector});
530
+ cy.log('click editBtn ' + treeSelector);
578
531
  clickEditButton(treeSelector);
579
532
  }
580
533
  cy.wait(1500); // allow form to build
@@ -584,9 +537,8 @@ export function editTreeRecord(treeSelector, fieldValues, schema, id, level = 0,
584
537
  cy.wait(500); // allow validator to enable save button
585
538
  // TODO: Change this to wait until save button is enabled
586
539
 
587
- cy.intercept('POST', '**/edit**').as('waiter');
588
540
  clickSaveButton(formSelector);
589
- cy.wait('@waiter');
541
+ cy.wait('@editWaiter');
590
542
 
591
543
  verifyNoErrorBox();
592
544
  // cy.wait(1000);
@@ -595,9 +547,7 @@ export function editTreeRecord(treeSelector, fieldValues, schema, id, level = 0,
595
547
  export function editWindowedTreeRecord(treeSelector, fieldValues, schema, id, level = 0) {
596
548
  // edits the record as normal, then closes the editor window
597
549
 
598
- cy.then(() => {
599
- Cypress.log({ name: 'editWindowedTreeRecord ' + treeSelector + ' ' + id});
600
- });
550
+ cy.log('editWindowedTreeRecord ' + treeSelector + ' ' + id);
601
551
 
602
552
  editTreeRecord(treeSelector, fieldValues, schema, id, level, WINDOWED);
603
553
 
@@ -608,18 +558,15 @@ export function editWindowedTreeRecord(treeSelector, fieldValues, schema, id, le
608
558
  }
609
559
  export function deleteTreeRecord(treeSelector, id) {
610
560
 
611
- cy.then(() => {
612
- Cypress.log({ name: 'deleteTreeRecord ' + treeSelector + ' ' + id });
613
- });
561
+ cy.log('deleteTreeRecord ' + treeSelector + ' ' + id);
614
562
 
615
563
  selectTreeNodeIfNotAlreadySelectedById(treeSelector, id);
616
564
  clickDeleteButton(treeSelector);
617
565
  cy.wait(500); // allow confirmation box to appear
618
566
 
619
567
  // Click OK on confirmation box
620
- cy.intercept('POST', '**/delete**').as('waiter');
621
- clickYesButton('AlertDialog');
622
- cy.wait('@waiter');
568
+ clickYesButton('ConfirmModal');
569
+ cy.wait('@deleteWaiter');
623
570
 
624
571
  verifyNoErrorBox();
625
572
  // cy.wait(1000);
@@ -636,6 +583,7 @@ export function runClosureTreeControlledManagerScreenCrudTests(model, schema, ne
636
583
  describe(Models + 'Manager', () => {
637
584
 
638
585
  beforeEach(function () {
586
+ bootstrapRouteWaiters();
639
587
  login();
640
588
  cy.restoreLocalStorage();
641
589
  cy.url().then((currentUrl) => {
@@ -732,6 +680,7 @@ export function runClosureTreeManagerScreenCrudTests(args) {
732
680
  describe(Models + 'Manager', () => {
733
681
 
734
682
  beforeEach(function () {
683
+ bootstrapRouteWaiters();
735
684
  login();
736
685
  cy.restoreLocalStorage();
737
686
  cy.url().then((currentUrl) => {
@@ -796,6 +745,7 @@ export function runManagerScreenCrudTests(args) {
796
745
  describe(Models + 'Manager', () => {
797
746
 
798
747
  beforeEach(function () {
748
+ bootstrapRouteWaiters();
799
749
  login();
800
750
  cy.restoreLocalStorage();
801
751
  cy.url().then((currentUrl) => {
@@ -854,6 +804,7 @@ export function runReportsManagerTests(reportData) {
854
804
  describe('ReportsManager', () => {
855
805
 
856
806
  beforeEach(function () {
807
+ bootstrapRouteWaiters();
857
808
  login();
858
809
  cy.url().then((currentUrl) => {
859
810
  if (!currentUrl.endsWith(url)) {
@@ -866,9 +817,7 @@ export function runReportsManagerTests(reportData) {
866
817
 
867
818
  it('Report ' + report.id, function() {
868
819
 
869
- cy.then(() => {
870
- Cypress.log({ name: 'report ' + report.id });
871
- });
820
+ cy.log('report ' + report.id);
872
821
 
873
822
  const selector = 'Report-' + report.id;
874
823
 
@@ -878,17 +827,15 @@ export function runReportsManagerTests(reportData) {
878
827
 
879
828
 
880
829
  // Press Excel button
881
- cy.intercept('GET', '**/getReport**').as('waiter');
882
830
  clickButton(selector, 'excelBtn');
883
- cy.wait('@waiter', { timeout: 10000 }).then((interception) => {
831
+ cy.wait('@getWaiter', { timeout: 10000 }).then((interception) => {
884
832
  expect(interception.response.headers['content-type']).to.include('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
885
833
  });
886
834
 
887
835
 
888
836
  // Press PDF button
889
- cy.intercept('POST', '**/getReport**').as('waiter');
890
837
  clickButton(selector, 'pdfBtn');
891
- cy.wait('@waiter', { timeout: 10000 }).then((interception) => {
838
+ cy.wait('@getReportWaiter', { timeout: 10000 }).then((interception) => {
892
839
  expect(interception.response.headers['content-type']).to.include('pdf');
893
840
  });
894
841
 
@@ -12,6 +12,9 @@ import {
12
12
  crudTag,
13
13
  crudJson,
14
14
  } from './crud_functions.js';
15
+ import {
16
+ clickXButtonIfEnabled
17
+ } from './button_functions.js';
15
18
  import natsort from 'natsort';
16
19
  import _ from 'lodash';
17
20
  const $ = Cypress.$;
@@ -29,6 +32,7 @@ export function setCustomFormFunctions(fns) {
29
32
  * @param {object} schema - fieldName/fieldType pairs
30
33
  */
31
34
  export function fillForm(selector, fieldValues, schema, level = 0) {
35
+ cy.log('fillForm');
32
36
  _.each(fieldValues, (value, fieldName) => {
33
37
 
34
38
  const selectors = [selector, 'field-' + fieldName];
@@ -116,6 +120,7 @@ export function fillForm(selector, fieldValues, schema, level = 0) {
116
120
  // export function setFileValue(field, value) {
117
121
  // }
118
122
  export function setArrayComboValue(selectors, value) {
123
+ cy.log('setArrayComboValue ' + value);
119
124
  getDomNode([...selectors, 'input']).then((field) => {
120
125
  cy.get(field).clear({ force: true });
121
126
  if (value) {
@@ -129,18 +134,20 @@ export function setArrayComboValue(selectors, value) {
129
134
  });
130
135
  }
131
136
  export function setComboValue(selectors, value) {
137
+ cy.log('setComboValue ' + value);
132
138
  getDomNode([...selectors, 'input']).then((field) => {
133
- cy.get(field).clear({ force: true });
139
+ // cy.get(field).clear({ force: true });
140
+ clickXButtonIfEnabled(selectors); // clear current value
134
141
  if (value) {
135
- cy.intercept('GET', '**/get**').as('getWaiter'); // set up waiter
136
142
  cy.get(field)
137
143
  .type(value, { delay: 40, force: true }) // slow it down a bit, so React has time to re-render
138
144
  .wait('@getWaiter'); // allow dropdown to load
139
145
 
140
146
  cy.get(field)
141
- .wait(2000) // render
147
+ .wait(1000) // render
148
+
142
149
  .type('{downarrow}')
143
- .wait(1000) // allow time for selection
150
+ .wait(500) // allow time for selection
144
151
 
145
152
  .type('{enter}')
146
153
  .wait(250); // allow time to register enter key
@@ -148,6 +155,7 @@ export function setComboValue(selectors, value) {
148
155
  });
149
156
  }
150
157
  export function setTagValue(selectors, value) {
158
+ cy.log('setTagValue ' + value);
151
159
  const values = !_.isEmpty(value) ? JSON.parse(value) : null;
152
160
 
153
161
  // Clear any previously selected tags
@@ -173,15 +181,14 @@ export function setTagValue(selectors, value) {
173
181
  if (!_.isEmpty(values)) {
174
182
  _.each(values, (value) => {
175
183
  const id = value.id;
176
- cy.intercept('GET', '**/get**').as('getWaiter'); // set up waiter
177
184
  cy.get(field)
178
185
  .type('id:' + id, { delay: 40, force: true }) // slow it down a bit, so React has time to re-render
179
186
  .wait('@getWaiter'); // allow dropdown to load
180
187
 
181
188
  cy.get(field)
182
- .wait(2000) // render
189
+ .wait(1000) // render
183
190
  .type('{downarrow}')
184
- .wait(1000); // allow time for selection
191
+ .wait(500); // allow time for selection
185
192
  });
186
193
 
187
194
  // press trigger to hide dropdown
@@ -190,6 +197,7 @@ export function setTagValue(selectors, value) {
190
197
  });
191
198
  }
192
199
  export function setDateValue(selectors, value) {
200
+ cy.log('setDateValue ' + value);
193
201
  getDomNode(selectors).then((field) => {
194
202
  cy.get(field).clear({ force: true });
195
203
  if (value) {
@@ -200,6 +208,7 @@ export function setDateValue(selectors, value) {
200
208
  });
201
209
  }
202
210
  export function setNumberValue(selectors, value) {
211
+ cy.log('setNumberValue ' + value);
203
212
  // setTextValue(selectors, value);
204
213
 
205
214
  getDomNode(selectors).clear({ force: true });
@@ -210,6 +219,7 @@ export function setNumberValue(selectors, value) {
210
219
  }
211
220
  }
212
221
  export function setToggleValue(selectors, value) {
222
+ cy.log('setToggleValue ' + value);
213
223
  selectors.push('input[role="switch"]');
214
224
  if (value) {
215
225
  getToggleState(selectors).then((isYes) => {
@@ -228,6 +238,7 @@ export function setToggleValue(selectors, value) {
228
238
  }
229
239
  }
230
240
  export function getToggleState(selectors) {
241
+ cy.log('getToggleState');
231
242
  return getDomNode(selectors).then((node) => {
232
243
  if (!node.length) {
233
244
  return null;
@@ -236,9 +247,11 @@ export function getToggleState(selectors) {
236
247
  });
237
248
  }
238
249
  export function clickToggle(selectors, options = {}) {
250
+ cy.log('clickToggle');
239
251
  getDomNode(selectors).click(options);
240
252
  }
241
253
  export function setTextValue(selectors, value) {
254
+ cy.log('setTextValue ' + value);
242
255
  getDomNode(selectors).clear({ force: true });
243
256
  if (value !== null && value !== '') {
244
257
  getDomNode(selectors)
@@ -247,6 +260,7 @@ export function setTextValue(selectors, value) {
247
260
  }
248
261
  }
249
262
  export function setTextAreaValue(selectors, value) {
263
+ cy.log('setTextAreaValue ' + value);
250
264
  getDomNode(selectors).clear({ force: true });
251
265
  if (value !== null && value !== '') {
252
266
  getDomNode(selectors)
@@ -254,6 +268,7 @@ export function setTextAreaValue(selectors, value) {
254
268
  }
255
269
  }
256
270
  export function setInputValue(selectors, value) {
271
+ cy.log('setInputValue ' + value);
257
272
  setTextValue(selectors, value);
258
273
  }
259
274
 
@@ -14,9 +14,11 @@ const $ = Cypress.$;
14
14
 
15
15
  // Get rows
16
16
  export function hasRowWithFieldValue(gridSelector, field, value) {
17
+ cy.log('hasRowWithFieldValue ' + gridSelector + ' ' + field + ' ' + value);
17
18
  return getDomNodes([gridSelector, 'row', 'cell-' + field]).contains(value);
18
19
  }
19
20
  export function getRowWithFieldValue(gridSelector, field, value) {
21
+ cy.log('getRowWithFieldValue ' + gridSelector + ' ' + field + ' ' + value);
20
22
  return getDomNodes([gridSelector, 'row', 'cell-' + field]).contains(value).then((cells) => {
21
23
  if (!cells.length) {
22
24
  return null;
@@ -39,17 +41,13 @@ export function getRowWithFieldValue(gridSelector, field, value) {
39
41
 
40
42
  // Select rows
41
43
  export function selectGridRowById(gridSelector, id) {
42
- cy.then(() => {
43
- Cypress.log({ name: 'selectGridRowById ' + gridSelector + ' ' + id});
44
- });
44
+ cy.log('selectGridRowById ' + gridSelector + ' ' + id);
45
45
  const rowSelector = getGridRowSelectorById(gridSelector, id);
46
46
  getDomNode([gridSelector, rowSelector])
47
47
  .click();
48
48
  }
49
49
  export function selectGridRowIfNotAlreadySelectedById(gridSelector, id) {
50
- cy.then(() => {
51
- Cypress.log({ name: 'selectGridRowIfNotAlreadySelectedById ' + gridSelector + ' ' + id});
52
- });
50
+ cy.log('selectGridRowIfNotAlreadySelectedById ' + gridSelector + ' ' + id);
53
51
  const rowSelector = getGridRowSelectorById(gridSelector, id);
54
52
  getDomNode([gridSelector, rowSelector]).then((row) => {
55
53
  const found = row.find('[data-testid="row-selected"]')
@@ -86,6 +84,7 @@ export function verifyGridRecordDoesNotExistByValue(gridSelector, fieldValues, s
86
84
  field = schema.model.displayProperty,
87
85
  value = fieldValues[field];
88
86
 
87
+ cy.log('verifyGridRecordDoesNotExistByValue ' + gridSelector + ' ' + value);
89
88
  getDomNodes([gridSelector, 'row', 'cell-' + field])
90
89
  .contains(value, { timeout: 500 })
91
90
  .should('not.exist');
@@ -95,31 +94,26 @@ export function verifyGridRecordExistsByValue(gridSelector, fieldValues, schema)
95
94
  field = schema.model.displayProperty,
96
95
  value = fieldValues[field];
97
96
 
97
+ cy.log('verifyGridRecordExistsByValue ' + gridSelector + ' ' + value);
98
98
  getDomNodes([gridSelector, 'row', 'cell-' + field])
99
99
  .contains(value, { timeout: 500 })
100
100
  .should('exist');
101
101
  }
102
102
  export function verifyGridRecordExistsById(gridSelector, id) {
103
- cy.then(() => {
104
- Cypress.log({ name: 'verifyGridRecordExistsById ' + gridSelector + ' ' + id });
105
- });
103
+ cy.log('verifyGridRecordExistsById ' + gridSelector + ' ' + id);
106
104
 
107
105
  const rowSelector = getGridRowSelectorById(gridSelector, id);
108
106
  getDomNodes([gridSelector, rowSelector])
109
107
  .should('exist');
110
108
  }
111
109
  export function verifyGridRecordDoesNotExistById(gridSelector, id) {
112
- cy.then(() => {
113
- Cypress.log({ name: 'verifyGridRecordDoesNotExistById ' + gridSelector + ' ' + id });
114
- });
110
+ cy.log('verifyGridRecordDoesNotExistById ' + gridSelector + ' ' + id);
115
111
  const rowSelector = getGridRowSelectorById(gridSelector, id);
116
112
  getDomNodes([gridSelector, rowSelector])
117
113
  .should('not.exist');
118
114
  }
119
115
  export function verifyGridRowIsSelectedById(gridSelector, id) {
120
- cy.then(() => {
121
- Cypress.log({ name: 'verifyGridRowIsSelectedById ' + gridSelector + ' ' + id});
122
- });
116
+ cy.log('verifyGridRowIsSelectedById ' + gridSelector + ' ' + id);
123
117
  const rowSelector = getGridRowSelectorById(gridSelector, id);
124
118
  getDomNodes([gridSelector, rowSelector, 'row-selected'])
125
119
  .should('exist');
@@ -12,6 +12,7 @@ import {
12
12
  // /____/
13
13
 
14
14
  export function login(loginId = null, password = null) {
15
+ cy.log('login');
15
16
  if (!loginId) {
16
17
  loginId = Cypress.env('loginId');
17
18
  }
@@ -34,6 +35,7 @@ export function login(loginId = null, password = null) {
34
35
  });
35
36
  }
36
37
  export function logout() {
38
+ cy.log('logout');
37
39
  const baseDir = Cypress.env('baseDir');
38
40
  getDomNode(baseDir + 'logout').click({ force: true });
39
41
  }
@@ -47,6 +49,7 @@ export function logout() {
47
49
  // /____/
48
50
 
49
51
  export function navigateViaTabOrHomeButtonTo(url) {
52
+ cy.log('navigateViaTabOrHomeButtonTo ' + url);
50
53
  // i.e. If we're on home screen, press the button.
51
54
  // If we have a tab navigation, press the tab's button
52
55
  const baseDir = Cypress.env('baseDir');
@@ -54,9 +57,11 @@ export function navigateViaTabOrHomeButtonTo(url) {
54
57
  cy.url().should('include', url);
55
58
  }
56
59
  export function navigateToHome() {
60
+ cy.log('navigateToHome');
57
61
  navigateToScreen('home');
58
62
  }
59
63
  export function navigateToScreen(path) {
64
+ cy.log('navigateToScreen ' + path);
60
65
  const
61
66
  baseUrl = Cypress.env('baseUrl'),
62
67
  baseDir = Cypress.env('baseDir');
@@ -14,9 +14,11 @@ const $ = Cypress.$;
14
14
 
15
15
  // Get rows
16
16
  export function hasNodeWithFieldValue(treeSelector, field, value) {
17
+ cy.log('hasNodeWithFieldValue ' + treeSelector + ' ' + field + ' ' + value);
17
18
  return getDomNodes([treeSelector, 'row', 'cell-' + field]).contains(value);
18
19
  }
19
20
  export function getNodeWithFieldValue(treeSelector, field, value) {
21
+ cy.log('getNodeWithFieldValue ' + treeSelector + ' ' + field + ' ' + value);
20
22
  return getDomNodes([treeSelector, 'row', 'cell-' + field]).contains(value).then((cells) => {
21
23
  if (!cells.length) {
22
24
  return null;
@@ -27,6 +29,7 @@ export function getNodeWithFieldValue(treeSelector, field, value) {
27
29
  });
28
30
  }
29
31
  export function getFirstTreeRootNode(treeSelector) {
32
+ cy.log('getFirstTreeRootNode ' + treeSelector);
30
33
  return cy.get('[data-testid="' + treeSelector + '"]:first ' +
31
34
  '[data-testid="ScrollView"]:first > div > div:first'); // this is fragile!
32
35
  }
@@ -43,17 +46,13 @@ export function getFirstTreeRootNode(treeSelector) {
43
46
 
44
47
  // Select rows
45
48
  export function selectTreeNodeById(treeSelector, id) {
46
- cy.then(() => {
47
- Cypress.log({ name: 'selectTreeNodeById ' + treeSelector + ' ' + id});
48
- });
49
+ cy.log('selectTreeNodeById ' + treeSelector + ' ' + id);
49
50
  const rowSelector = getTreeNodeSelectorById(treeSelector, id);
50
51
  getDomNode([treeSelector, rowSelector])
51
52
  .click();
52
53
  }
53
54
  export function selectTreeNodeIfNotAlreadySelectedById(treeSelector, id) {
54
- cy.then(() => {
55
- Cypress.log({ name: 'selectTreeNodeIfNotAlreadySelectedById ' + treeSelector + ' ' + id});
56
- });
55
+ cy.log('selectTreeNodeIfNotAlreadySelectedById ' + treeSelector + ' ' + id);
57
56
  const rowSelector = getTreeNodeSelectorById(treeSelector, id);
58
57
  getDomNode([treeSelector, rowSelector]).then((row) => {
59
58
  const found = row.find('[data-testid="node-selected"]')
@@ -90,6 +89,7 @@ export function verifyTreeRecordDoesNotExistByValue(treeSelector, fieldValues, s
90
89
  field = schema.model.displayProperty,
91
90
  value = fieldValues[field];
92
91
 
92
+ cy.log('verifyTreeRecordDoesNotExistByValue ' + treeSelector + ' ' + value);
93
93
  getDomNodes([treeSelector, 'row', 'cell-' + field])
94
94
  .contains(value, { timeout: 500 })
95
95
  .should('not.exist');
@@ -99,31 +99,26 @@ export function verifyTreeRecordExistsByValue(treeSelector, fieldValues, schema)
99
99
  field = schema.model.displayProperty,
100
100
  value = fieldValues[field];
101
101
 
102
+ cy.log('verifyTreeRecordExistsByValue ' + treeSelector + ' ' + value);
102
103
  getDomNodes([treeSelector, 'row', 'cell-' + field])
103
104
  .contains(value, { timeout: 500 })
104
105
  .should('exist');
105
106
  }
106
107
  export function verifyTreeRecordExistsById(treeSelector, id) {
107
- cy.then(() => {
108
- Cypress.log({ name: 'verifyTreeRecordExistsById ' + treeSelector + ' ' + id });
109
- });
108
+ cy.log('verifyTreeRecordExistsById ' + treeSelector + ' ' + id);
110
109
 
111
110
  const rowSelector = getTreeNodeSelectorById(treeSelector, id);
112
111
  getDomNodes([treeSelector, rowSelector])
113
112
  .should('exist');
114
113
  }
115
114
  export function verifyTreeRecordDoesNotExistById(treeSelector, id) {
116
- cy.then(() => {
117
- Cypress.log({ name: 'verifyTreeRecordDoesNotExistById ' + treeSelector + ' ' + id });
118
- });
115
+ cy.log('verifyTreeRecordDoesNotExistById ' + treeSelector + ' ' + id);
119
116
  const rowSelector = getTreeNodeSelectorById(treeSelector, id);
120
117
  getDomNodes([treeSelector, rowSelector])
121
118
  .should('not.exist');
122
119
  }
123
120
  export function verifyTreeNodeIsSelectedById(treeSelector, id) {
124
- cy.then(() => {
125
- Cypress.log({ name: 'verifyTreeNodeIsSelectedById ' + treeSelector + ' ' + id});
126
- });
121
+ cy.log('verifyTreeNodeIsSelectedById ' + treeSelector + ' ' + id);
127
122
  const rowSelector = getTreeNodeSelectorById(treeSelector, id);
128
123
  getDomNodes([treeSelector, rowSelector, 'node-selected'])
129
124
  .should('exist');
@@ -6,10 +6,21 @@ import moment from 'moment';
6
6
  // / /_/ / /_/ / / / /_/ / __(__ )
7
7
  // \____/\__/_/_/_/\__/_/\___/____/
8
8
 
9
-
9
+ export function bootstrapRouteWaiters() {
10
+ cy.log('bootstrapRouteWaiters');
11
+ cy.intercept('GET', '**/get**').as('getWaiter');
12
+ cy.intercept('POST', '**/add**').as('addWaiter');
13
+ cy.intercept('POST', '**/edit**').as('editWaiter');
14
+ cy.intercept('POST', '**/delete**').as('deleteWaiter');
15
+ cy.intercept('POST', '**/getReport**').as('getReportWaiter');
16
+ }
10
17
  export function fixInflector(str) {
11
18
  // inflector-js doesn't handle pluralization of 'equipment' correctly
12
19
  str = str.replace(/quipments/, 'quipment');
20
+
21
+ // Don't pluralize 'SideA' or 'SideB'
22
+ str = str.replace(/SideAs/, 'SideA');
23
+ str = str.replace(/SideBs/, 'SideB');
13
24
  return str;
14
25
  }
15
26
  export function getPropertyDefinitionFromSchema(fieldName, schema) {