Skip to content

Commit 2663fe4

Browse files
Added automated tests with cypress for Zone form
1 parent 5008352 commit 2663fe4

File tree

1 file changed

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

1 file changed

+310
-0
lines changed
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
/* eslint-disable no-undef */
2+
import { flashClassMap } from '../../../../support/assertions/assertion_constants';
3+
4+
// Component route url
5+
const COMPONENT_ROUTE_URL = '/ops/explorer#/';
6+
7+
// Menu options
8+
const SETTINGS_OPTION = 'Settings';
9+
const APP_SETTINGS_OPTION = 'Application Settings';
10+
11+
// Accordion items
12+
const MANAGEIQ_REGION_ACCORDION_ITEM = /^ManageIQ Region:/;
13+
const ZONES_ACCORDION_ITEM = 'Zones';
14+
15+
// Config options
16+
const CONFIG_TOOLBAR_BUTTON = 'Configuration';
17+
const ADD_ZONE_CONFIG_OPTION = 'Add a new Zone';
18+
const EDIT_ZONE_CONFIG_OPTION = 'Edit this Zone';
19+
const DELETE_ZONE_CONFIG_OPTION = 'Delete this Zone';
20+
21+
// Field values
22+
const NAME_FIELD_LABEL = 'Name';
23+
const DESCRIPTION_FIELD_LABEL = 'Description';
24+
const SERVER_IP_FIELD_LABEL = 'Server IP';
25+
const MAX_SCAN_FIELD_LABEL = 'VM Scans';
26+
const FORM_HEADER_FRAGMENT = 'Zone';
27+
const INFO_SUB_HEADER = 'Info';
28+
const SETTINGS_SUB_HEADER = 'Settings';
29+
const ZONE_NAME = 'Test-Zone-Name';
30+
const INITIAL_ZONE_DESCRIPTION = 'Test-Zone-Description';
31+
const UPDATED_ZONE_DESCRIPTION = 'Test-Zone-Description-Updated';
32+
const INITIAL_SERVER_IP = '0.0.0.0';
33+
const UPDATED_SERVER_IP = '1.1.1.1';
34+
const INITIAL_MAX_SCAN_LIMIT = 5;
35+
const UPDATED_MAX_SCAN_LIMIT = 10;
36+
37+
// Buttons
38+
const SAVE_BUTTON_TEXT = 'Save';
39+
const CANCEL_BUTTON_TEXT = 'Cancel';
40+
const ADD_BUTTON_TEXT = 'Add';
41+
const RESET_BUTTON_TEXT = 'Reset';
42+
43+
// Flash message text snippets
44+
const FLASH_MESSAGE_OPERATION_CANCELED = 'cancel';
45+
const FLASH_MESSAGE_ZONE_UPDATED = 'queued';
46+
const FLASH_MESSAGE_OPERATION_RESET = 'reset';
47+
const DELETE_CONFIRM_TEXT = 'delete';
48+
49+
function addZone() {
50+
// Open add form
51+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_ZONE_CONFIG_OPTION);
52+
// Adding name, description, ip and scan limit
53+
cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(ZONE_NAME);
54+
cy.getFormInputFieldByIdAndType({ inputId: 'description' }).type(
55+
INITIAL_ZONE_DESCRIPTION
56+
);
57+
cy.getFormInputFieldByIdAndType({ inputId: 'settings.proxy_server_ip' }).type(
58+
INITIAL_SERVER_IP
59+
);
60+
cy.getFormSelectFieldById({
61+
selectId: 'settings.concurrent_vm_scans',
62+
}).select(INITIAL_MAX_SCAN_LIMIT);
63+
cy.interceptApi({
64+
alias: 'createZoneApi',
65+
urlPattern: '/api/zones',
66+
triggerFn: () =>
67+
cy
68+
.getFormFooterButtonByTypeWithText({
69+
buttonText: ADD_BUTTON_TEXT,
70+
buttonType: 'submit',
71+
})
72+
.should('be.enabled')
73+
.click(),
74+
});
75+
return cy.then(() => {
76+
return `Zone: ${INITIAL_ZONE_DESCRIPTION}`;
77+
});
78+
}
79+
80+
function validateFormElements(isEditForm = false) {
81+
// Assert form header is visible
82+
cy.expect_explorer_title(FORM_HEADER_FRAGMENT);
83+
// Assert Info sub header is visible
84+
cy.get('#main-content .bx--form h3').contains(INFO_SUB_HEADER);
85+
// Assert name field label is visible
86+
cy.getFormLabelByForAttribute({ forValue: 'name' })
87+
.should('be.visible')
88+
.and('contain.text', NAME_FIELD_LABEL);
89+
// Assert name field is visible and enabled
90+
cy.getFormInputFieldByIdAndType({ inputId: 'name' })
91+
.should('be.visible')
92+
.then((nameField) => {
93+
if (isEditForm) {
94+
expect(nameField).to.be.disabled;
95+
} else {
96+
expect(nameField).to.not.be.disabled;
97+
}
98+
});
99+
// Assert description field label is visible
100+
cy.getFormLabelByForAttribute({ forValue: 'description' })
101+
.should('be.visible')
102+
.and('contain.text', DESCRIPTION_FIELD_LABEL);
103+
// Assert description field is visible and enabled
104+
cy.getFormInputFieldByIdAndType({ inputId: 'description' })
105+
.should('be.visible')
106+
.and('be.enabled');
107+
// Assert IP field label is visible
108+
cy.getFormLabelByForAttribute({ forValue: 'settings.proxy_server_ip' })
109+
.should('be.visible')
110+
.and('contain.text', SERVER_IP_FIELD_LABEL);
111+
// Assert IP field is visible and enabled
112+
cy.getFormInputFieldByIdAndType({ inputId: 'settings.proxy_server_ip' })
113+
.should('be.visible')
114+
.and('be.enabled');
115+
// Assert Settings sub header is visible
116+
cy.get('#main-content .bx--form h3').contains(SETTINGS_SUB_HEADER);
117+
// Assert max scan field label is visible
118+
cy.getFormLabelByForAttribute({ forValue: 'settings.concurrent_vm_scans' })
119+
.should('be.visible')
120+
.and('contain.text', MAX_SCAN_FIELD_LABEL);
121+
// Assert max scan field is visible and enabled
122+
cy.getFormSelectFieldById({ selectId: 'settings.concurrent_vm_scans' })
123+
.should('be.visible')
124+
.and('be.enabled');
125+
// Assert cancel button is visible and enabled
126+
cy.getFormFooterButtonByTypeWithText({ buttonText: CANCEL_BUTTON_TEXT })
127+
.should('be.visible')
128+
.and('be.enabled');
129+
if (isEditForm) {
130+
// Assert reset button is visible and disabled
131+
cy.getFormFooterButtonByTypeWithText({ buttonText: RESET_BUTTON_TEXT })
132+
.should('be.visible')
133+
.and('be.disabled');
134+
}
135+
// Assert add/save button is visible and disabled
136+
cy.getFormFooterButtonByTypeWithText({
137+
buttonText: isEditForm ? SAVE_BUTTON_TEXT : ADD_BUTTON_TEXT,
138+
buttonType: 'submit',
139+
})
140+
.should('be.visible')
141+
.and('be.disabled');
142+
}
143+
144+
function cleanUp() {
145+
cy.get('li.list-group-item').each((item) => {
146+
const text = item?.text()?.trim();
147+
if (text.includes(INITIAL_ZONE_DESCRIPTION)) {
148+
// Select the zone node if it hasn't been selected yet
149+
if (!item.hasClass('node-selected')) {
150+
cy.wrap(item).click();
151+
}
152+
// Deleting the zone
153+
cy.expect_browser_confirm_with_text({
154+
confirmTriggerFn: () =>
155+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, DELETE_ZONE_CONFIG_OPTION),
156+
});
157+
return false; // exit the iteration
158+
}
159+
return null; // has no impact - just to get rid of eslint warning
160+
});
161+
}
162+
163+
function selectZoneAccordionItem(childZoneNode) {
164+
cy.selectAccordionItem([
165+
MANAGEIQ_REGION_ACCORDION_ITEM,
166+
ZONES_ACCORDION_ITEM,
167+
...(childZoneNode ? [childZoneNode] : []),
168+
]);
169+
}
170+
171+
describe('Automate Zone form operations: Settings > Application Settings > Settings > Zones > Configuration > Add a new Zone', () => {
172+
beforeEach(() => {
173+
cy.login();
174+
// Navigate to Application-Settings
175+
cy.menu(SETTINGS_OPTION, APP_SETTINGS_OPTION);
176+
// Expand Settings accordion panel if not already expanded
177+
cy.accordion(SETTINGS_OPTION);
178+
// Select "Zones" accordion item
179+
selectZoneAccordionItem();
180+
});
181+
182+
it('Validate the visibility and state of add form elements', () => {
183+
// Open add form
184+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_ZONE_CONFIG_OPTION);
185+
// Validate fields
186+
validateFormElements();
187+
});
188+
189+
it('Checking whether cancel button works on the add form', () => {
190+
// Open add form
191+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_ZONE_CONFIG_OPTION);
192+
// Cancelling the form
193+
cy.getFormFooterButtonByTypeWithText({
194+
buttonText: CANCEL_BUTTON_TEXT,
195+
}).click();
196+
cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_OPERATION_CANCELED);
197+
});
198+
199+
it('Checking whether add, edit & delete zone works', () => {
200+
/* ===== Add ===== */
201+
// Adding zone
202+
addZone().then((createdZone) => {
203+
// Here the createdZone will have value "Zone: Test-Zone-Description",
204+
// which is the accordion item to be selected
205+
// Assert flash message
206+
cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_ZONE_UPDATED);
207+
// Select the created zone
208+
selectZoneAccordionItem(createdZone);
209+
});
210+
/* ===== Edit ===== */
211+
// Open edit form
212+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_ZONE_CONFIG_OPTION);
213+
// Update IP & scan limit
214+
cy.getFormInputFieldByIdAndType({ inputId: 'description' })
215+
.clear()
216+
.type(UPDATED_SERVER_IP);
217+
cy.getFormSelectFieldById({
218+
selectId: 'settings.concurrent_vm_scans',
219+
}).select(UPDATED_MAX_SCAN_LIMIT);
220+
// Save the form
221+
cy.getFormFooterButtonByTypeWithText({
222+
buttonText: SAVE_BUTTON_TEXT,
223+
buttonType: 'submit',
224+
})
225+
.should('be.enabled')
226+
.click();
227+
cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_ZONE_UPDATED);
228+
/* ===== Delete ===== */
229+
// Deleting the zone
230+
cy.expect_browser_confirm_with_text({
231+
confirmTriggerFn: () =>
232+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, DELETE_ZONE_CONFIG_OPTION),
233+
containsText: DELETE_CONFIRM_TEXT,
234+
});
235+
cy.expect_flash(flashClassMap.success, DELETE_CONFIRM_TEXT);
236+
});
237+
238+
it('Validate the visibility and state of edit form elements', () => {
239+
// Adding zone
240+
addZone().then((createdZone) => {
241+
// Here the createdZone will have value "Zone: Test-Zone-Description",
242+
// which is the accordion item to be selected
243+
// Select the created zone
244+
selectZoneAccordionItem(createdZone);
245+
});
246+
// Open edit form
247+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_ZONE_CONFIG_OPTION);
248+
// Validate fields
249+
validateFormElements(true);
250+
// Cancelling the form
251+
cy.getFormFooterButtonByTypeWithText({
252+
buttonText: CANCEL_BUTTON_TEXT,
253+
}).click();
254+
});
255+
256+
it('Checking whether cancel & reset buttons work on the edit form', () => {
257+
// Adding zone
258+
addZone().then((createdZone) => {
259+
// Here the createdZone will have value "Zone: Test-Zone-Description",
260+
// which is the accordion item to be selected
261+
// Select the created zone
262+
selectZoneAccordionItem(createdZone);
263+
});
264+
// Open edit form
265+
cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_ZONE_CONFIG_OPTION);
266+
/* ===== Reset ===== */
267+
// Update description & IP
268+
cy.getFormInputFieldByIdAndType({ inputId: 'description' })
269+
.clear()
270+
.type(UPDATED_ZONE_DESCRIPTION);
271+
cy.getFormInputFieldByIdAndType({ inputId: 'settings.proxy_server_ip' })
272+
.clear()
273+
.type(UPDATED_SERVER_IP);
274+
// Resetting the form
275+
cy.getFormFooterButtonByTypeWithText({ buttonText: RESET_BUTTON_TEXT })
276+
.should('be.enabled')
277+
.click();
278+
cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_OPERATION_RESET);
279+
// Confirming the edited fields contain the old values after resetting
280+
cy.getFormInputFieldByIdAndType({ inputId: 'description' }).should(
281+
'have.value',
282+
INITIAL_ZONE_DESCRIPTION
283+
);
284+
cy.getFormInputFieldByIdAndType({
285+
inputId: 'settings.proxy_server_ip',
286+
}).should('have.value', INITIAL_SERVER_IP);
287+
/* ===== Cancel ===== */
288+
// Cancelling the form
289+
cy.getFormFooterButtonByTypeWithText({
290+
buttonText: CANCEL_BUTTON_TEXT,
291+
}).click();
292+
cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_OPERATION_CANCELED);
293+
});
294+
295+
afterEach(() => {
296+
cy.url()
297+
?.then((url) => {
298+
// Ensures navigation to Settings -> Application-Settings in the UI
299+
if (!url.endsWith(COMPONENT_ROUTE_URL)) {
300+
// Navigate to Settings -> Application-Settings before cleanup
301+
cy.visit(COMPONENT_ROUTE_URL);
302+
}
303+
// Expand Settings accordion panel
304+
cy.accordion(SETTINGS_OPTION);
305+
})
306+
.then(() => {
307+
cleanUp();
308+
});
309+
});
310+
});

0 commit comments

Comments
 (0)