Skip to content

Commit 432ecf8

Browse files
Added automated tests with cypress for Zone form
1 parent 66865b8 commit 432ecf8

File tree

1 file changed

+338
-0
lines changed
  • cypress/e2e/ui/Settings/Application-Settings

1 file changed

+338
-0
lines changed
Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
/* eslint-disable no-undef */
2+
3+
const textConstants = {
4+
// Component route url
5+
componentRouteUrl: '/ops/explorer',
6+
7+
// Menu options
8+
settingsOption: 'Settings',
9+
appSettingsMenuOption: 'Application Settings',
10+
11+
// Accordion items
12+
manageIQRegionAccordItem: /^ManageIQ Region:/,
13+
zonesAccordItem: 'Zones',
14+
15+
// Config options
16+
configToolbarButton: 'Configuration',
17+
addZoneConfigOption: 'Add a new Zone',
18+
editZoneConfigOption: 'Edit this Zone',
19+
deleteZoneConfigOption: 'Delete this Zone',
20+
21+
// Field values
22+
formHeaderFragment: 'Zone',
23+
infoSubHeader: 'Info',
24+
settingsSubHeader: 'Settings',
25+
zoneName: 'Test-Zone-Name',
26+
initialZoneDescription: 'Test-Zone-Description',
27+
updatedZoneDescription: 'Test-Zone-Description-Updated',
28+
initialServerIp: '0.0.0.0',
29+
updatedServerIp: '1.1.1.1',
30+
initialMaxScanLimit: 5,
31+
updatedMaxScanLimit: 10,
32+
33+
// Element ids
34+
nameInputFieldId: 'name',
35+
descriptionInputFieldId: 'description',
36+
ipInputFieldId: 'settings\\.proxy_server_ip',
37+
maxScanSelectFieldId: 'settings\\.concurrent_vm_scans',
38+
39+
// Common selectors
40+
inputFieldLabelSelector: (forValue) =>
41+
`#main-content .bx--form label[for="${forValue}"]`,
42+
inputFieldSelector: (inputId) => `#main-content .bx--form input#${inputId}`,
43+
selectFieldSelector: (selectId) => `#main-content .bx--form select#${selectId}`,
44+
buttonSelector: (type) => `#main-content .bx--btn-set button[type="${type}"]`,
45+
46+
// Buttons
47+
saveButton: 'Save',
48+
cancelButton: 'Cancel',
49+
addButton: 'Add',
50+
resetButton: 'Reset',
51+
52+
// Button types
53+
submitButtonType: 'submit',
54+
normalButtonType: 'button',
55+
56+
// Flash message types
57+
flashTypeSuccess: 'success',
58+
flashTypeWarning: 'warning',
59+
60+
// Flash message text snippets
61+
flashMessageOperationCanceled: 'cancel',
62+
flashMessageZoneUpdated: 'queued',
63+
flashMessageOperationReset: 'reset',
64+
deleteConfirmText: 'delete',
65+
};
66+
67+
const {
68+
componentRouteUrl,
69+
settingsOption,
70+
appSettingsMenuOption,
71+
manageIQRegionAccordItem,
72+
zonesAccordItem,
73+
configToolbarButton,
74+
addZoneConfigOption,
75+
editZoneConfigOption,
76+
deleteZoneConfigOption,
77+
selectFieldSelector,
78+
buttonSelector,
79+
inputFieldSelector,
80+
inputFieldLabelSelector,
81+
cancelButton,
82+
addButton,
83+
saveButton,
84+
resetButton,
85+
flashTypeSuccess,
86+
flashTypeWarning,
87+
deleteConfirmText,
88+
flashMessageOperationCanceled,
89+
flashMessageOperationReset,
90+
flashMessageZoneUpdated,
91+
submitButtonType,
92+
normalButtonType,
93+
formHeaderFragment,
94+
infoSubHeader,
95+
settingsSubHeader,
96+
zoneName,
97+
initialZoneDescription,
98+
updatedZoneDescription,
99+
initialServerIp,
100+
updatedServerIp,
101+
initialMaxScanLimit,
102+
updatedMaxScanLimit,
103+
nameInputFieldId,
104+
descriptionInputFieldId,
105+
ipInputFieldId,
106+
maxScanSelectFieldId,
107+
} = textConstants;
108+
109+
function addZone() {
110+
// Open add form
111+
cy.toolbar(configToolbarButton, addZoneConfigOption);
112+
// Adding name, description, ip and scan limit
113+
cy.get(inputFieldSelector(nameInputFieldId)).type(zoneName);
114+
cy.get(inputFieldSelector(descriptionInputFieldId)).type(
115+
initialZoneDescription
116+
);
117+
cy.get(inputFieldSelector(ipInputFieldId)).type(initialServerIp);
118+
cy.get(selectFieldSelector(maxScanSelectFieldId)).select(initialMaxScanLimit);
119+
cy.intercept('POST', '/api/zones').as('createZone');
120+
cy.contains(buttonSelector(submitButtonType), addButton)
121+
.should('be.enabled')
122+
.click();
123+
cy.wait('@createZone');
124+
}
125+
126+
function validateFormElements(isEditForm = false) {
127+
// Assert form header is visible
128+
cy.expect_explorer_title(formHeaderFragment);
129+
// Assert Info sub header is visible
130+
cy.get('#main-content .bx--form h3').contains(infoSubHeader);
131+
// Assert name field label is visible
132+
cy.get(inputFieldLabelSelector(nameInputFieldId)).should('be.visible');
133+
// Assert name field is visible and enabled
134+
cy.get(inputFieldSelector(nameInputFieldId))
135+
.should('be.visible')
136+
.then((nameField) => {
137+
if (isEditForm) {
138+
expect(nameField).to.be.disabled;
139+
} else {
140+
expect(nameField).to.not.be.disabled;
141+
}
142+
});
143+
// Assert description field label is visible
144+
cy.get(inputFieldLabelSelector(descriptionInputFieldId)).should('be.visible');
145+
// Assert description field is visible and enabled
146+
cy.get(inputFieldSelector(descriptionInputFieldId))
147+
.should('be.visible')
148+
.and('be.enabled');
149+
// Assert IP field label is visible
150+
cy.get(inputFieldLabelSelector(ipInputFieldId)).should('be.visible');
151+
// Assert IP field is visible and enabled
152+
cy.get(inputFieldSelector(ipInputFieldId))
153+
.should('be.visible')
154+
.and('be.enabled');
155+
// Assert Settings sub header is visible
156+
cy.get('#main-content .bx--form h3').contains(settingsSubHeader);
157+
// Assert max scan field label is visible
158+
cy.get(inputFieldLabelSelector(maxScanSelectFieldId)).should('be.visible');
159+
// Assert max scan field is visible and enabled
160+
cy.get(selectFieldSelector(maxScanSelectFieldId))
161+
.should('be.visible')
162+
.and('be.enabled');
163+
// Assert cancel button is visible and enabled
164+
cy.contains(buttonSelector(normalButtonType), cancelButton)
165+
.should('be.visible')
166+
.and('be.enabled');
167+
if (isEditForm) {
168+
// Assert reset button is visible and disabled
169+
cy.contains(buttonSelector(normalButtonType), resetButton)
170+
.should('be.visible')
171+
.and('be.disabled');
172+
}
173+
// Assert add/save button is visible and disabled
174+
cy.contains(
175+
buttonSelector(submitButtonType),
176+
isEditForm ? saveButton : addButton
177+
)
178+
.should('be.visible')
179+
.and('be.disabled');
180+
}
181+
182+
function cleanUp() {
183+
cy.get('li.list-group-item').each((item) => {
184+
const text = item?.text()?.trim();
185+
if (text.includes(initialZoneDescription)) {
186+
// Select the zone node if it hasn’t been selected yet
187+
if (!item.hasClass('node-selected')) {
188+
cy.wrap(item).click();
189+
cy.wait('@treeSelectApi');
190+
}
191+
// Deleting the zone
192+
cy.expect_browser_confirm_with_text({
193+
confirmTriggerFn: () =>
194+
cy.toolbar(configToolbarButton, deleteZoneConfigOption),
195+
});
196+
return false; // exit the iteration
197+
}
198+
return null; // has no impact - just to get rid of eslint warning
199+
});
200+
}
201+
202+
describe('Automate Schedule form operations: Settings > Application Settings > Settings > Zones > Configuration > Add a new Zone', () => {
203+
beforeEach(() => {
204+
cy.login();
205+
// Navigate to Application-Settings
206+
cy.menu(settingsOption, appSettingsMenuOption);
207+
// Expand Settings accordion panel
208+
cy.accordion(settingsOption);
209+
// Select "Zones" accordion item
210+
cy.intercept('POST', /\/ops\/tree_select\?id=.*&text=.*/).as(
211+
'treeSelectApi'
212+
);
213+
cy.selectAccordionItem([manageIQRegionAccordItem, zonesAccordItem]);
214+
cy.wait('@treeSelectApi');
215+
});
216+
217+
it('Validate the visibility and state of add form elements', () => {
218+
// Open add form
219+
cy.toolbar(configToolbarButton, addZoneConfigOption);
220+
// Validate fields
221+
validateFormElements();
222+
});
223+
224+
it('Checking whether cancel button works on the add form', () => {
225+
// Open add form
226+
cy.toolbar(configToolbarButton, addZoneConfigOption);
227+
// Cancelling the form
228+
cy.contains(buttonSelector(normalButtonType), cancelButton).click();
229+
cy.expect_flash(flashTypeWarning, flashMessageOperationCanceled);
230+
});
231+
232+
it('Checking whether add, edit & delete zone works', () => {
233+
/* ===== Add ===== */
234+
// Adding zone
235+
addZone();
236+
cy.expect_flash(flashTypeSuccess, flashMessageZoneUpdated);
237+
/* ===== Edit ===== */
238+
// Select the created zone
239+
cy.selectAccordionItem([
240+
manageIQRegionAccordItem,
241+
zonesAccordItem,
242+
`Zone: ${initialZoneDescription}`,
243+
]);
244+
cy.wait('@treeSelectApi');
245+
// Open edit form
246+
cy.toolbar(configToolbarButton, editZoneConfigOption);
247+
// Update IP & scan limit
248+
cy.get(inputFieldSelector(descriptionInputFieldId))
249+
.clear()
250+
.type(updatedServerIp);
251+
cy.get(selectFieldSelector(maxScanSelectFieldId)).select(
252+
updatedMaxScanLimit
253+
);
254+
// Save the form
255+
cy.contains(buttonSelector(submitButtonType), saveButton)
256+
.should('be.enabled')
257+
.click();
258+
cy.expect_flash(flashTypeSuccess, flashMessageZoneUpdated);
259+
/* ===== Delete ===== */
260+
// Deleting the zone
261+
cy.expect_browser_confirm_with_text({
262+
confirmTriggerFn: () =>
263+
cy.toolbar(configToolbarButton, deleteZoneConfigOption),
264+
containsText: deleteConfirmText,
265+
});
266+
cy.expect_flash(flashTypeSuccess, deleteConfirmText);
267+
});
268+
269+
it('Validate the visibility and state of edit form elements', () => {
270+
// Adding zone
271+
addZone();
272+
// Select the created zone
273+
cy.selectAccordionItem([
274+
manageIQRegionAccordItem,
275+
zonesAccordItem,
276+
`Zone: ${initialZoneDescription}`,
277+
]);
278+
cy.wait('@treeSelectApi');
279+
// Open edit form
280+
cy.toolbar(configToolbarButton, editZoneConfigOption);
281+
// Validate fields
282+
validateFormElements(true);
283+
// Cancelling the form
284+
cy.contains(buttonSelector(normalButtonType), cancelButton).click();
285+
});
286+
287+
it('Checking whether cancel & reset buttons work on the edit form', () => {
288+
// Adding zone
289+
addZone();
290+
// Select the created zone
291+
cy.selectAccordionItem([
292+
manageIQRegionAccordItem,
293+
zonesAccordItem,
294+
`Zone: ${initialZoneDescription}`,
295+
]);
296+
cy.wait('@treeSelectApi');
297+
// Open edit form
298+
cy.toolbar(configToolbarButton, editZoneConfigOption);
299+
/* ===== Reset ===== */
300+
// Update description & IP
301+
cy.get(inputFieldSelector(descriptionInputFieldId))
302+
.clear()
303+
.type(updatedZoneDescription);
304+
cy.get(inputFieldSelector(ipInputFieldId)).clear().type(updatedServerIp);
305+
// Resetting the form
306+
cy.contains(buttonSelector(normalButtonType), resetButton)
307+
.should('be.enabled')
308+
.click();
309+
cy.expect_flash(flashTypeWarning, flashMessageOperationReset);
310+
// Confirming the edited fields contain the old values after resetting
311+
cy.get(inputFieldSelector(descriptionInputFieldId)).should(
312+
'have.value',
313+
initialZoneDescription
314+
);
315+
cy.get(inputFieldSelector(ipInputFieldId)).should(
316+
'have.value',
317+
initialServerIp
318+
);
319+
/* ===== Cancel ===== */
320+
// Cancelling the form
321+
cy.contains(buttonSelector(normalButtonType), cancelButton).click();
322+
cy.expect_flash(flashTypeWarning, flashMessageOperationCanceled);
323+
});
324+
325+
afterEach(() => {
326+
cy.url()
327+
?.then((url) => {
328+
// Ensures navigation to Settings -> Application-Settings in the UI
329+
if (!url?.includes(componentRouteUrl)) {
330+
// Navigate to Settings -> Application-Settings before cleanup
331+
cy.menu(settingsMenuOption, appSettingsMenuOption);
332+
}
333+
})
334+
.then(() => {
335+
cleanUp();
336+
});
337+
});
338+
});

0 commit comments

Comments
 (0)