Skip to content

Commit 4139520

Browse files
Added automated tests with cypress for Namespace form
1 parent 893118b commit 4139520

File tree

1 file changed

+295
-0
lines changed

1 file changed

+295
-0
lines changed
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
/* eslint-disable no-undef */
2+
import { flashClassMap } from '../../../../../support/assertions/assertion_constants';
3+
4+
// Menu options
5+
const AUTOMATION_MENU_OPTION = 'Automation';
6+
const EMBEDDED_AUTOMATION_MENU_OPTION = 'Embedded Automate';
7+
const EXPLORER_MENU_OPTION = 'Explorer';
8+
9+
// Toolbar options
10+
const TOOLBAR_CONFIGURATION = 'Configuration';
11+
const TOOLBAR_ADD_NEW_DOMAIN = 'Add a New Domain';
12+
const TOOLBAR_ADD_NEW_NAMESPACE = 'Add a New Namespace';
13+
const TOOLBAR_EDIT_NAMESPACE = 'Edit this Namespace';
14+
const TOOLBAR_REMOVE_NAMESPACE = 'Remove this Namespace';
15+
16+
// Field values
17+
const DOMAIN_NAME = 'Test_Domain';
18+
const DESCRIPTION = 'Test description';
19+
const NAMESPACE_NAME = 'Test_Namespace';
20+
const EDITED_NAMESPACE_NAME = 'Test_Namespace_Edited';
21+
const EDITED_DESCRIPTION = 'Test description edited';
22+
const INVALID_NAMESPACE_NAME = 'Test Namespace';
23+
const NAMESPACE_FORM_HEADER = 'Automate Namespace';
24+
const NAMESPACE_FORM_SUB_HEADER = 'Info';
25+
26+
// List items
27+
const DATA_STORE_ACCORDION_LABEL = 'Datastore';
28+
29+
// Buttons
30+
const ADD_BUTTON_TEXT = 'Add';
31+
const CANCEL_BUTTON_TEXT = 'Cancel';
32+
const SAVE_BUTTON_TEXT = 'Save';
33+
const RESET_BUTTON_TEXT = 'Reset';
34+
35+
const FLASH_TYPE_ERROR = 'error';
36+
37+
// Flash message text snippets
38+
const FLASH_MESSAGE_ADD_SUCCESS = 'added';
39+
const FLASH_MESSAGE_SAVE_SUCCESS = 'saved';
40+
const FLASH_MESSAGE_CANCELLED = 'cancel';
41+
const FLASH_MESSAGE_INVALID_NAMESPACE = 'contain only alphanumeric';
42+
const FLASH_MESSAGE_NAMESPACE_REMOVED = 'delete successful';
43+
const FLASH_MESSAGE_NAME_ALREADY_EXISTS = 'taken';
44+
const FLASH_MESSAGE_RESET_NAMESPACE = 'reset';
45+
const BROWSER_CONFIRM_REMOVE_MESSAGE = 'remove';
46+
47+
function addNamespace(nameFieldValue) {
48+
// Navigating to the Add Namespace form
49+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_ADD_NEW_NAMESPACE);
50+
// Creating a new namespace
51+
cy.getFormInputFieldById('name').type(nameFieldValue);
52+
cy.getFormInputFieldById('description').type(DESCRIPTION);
53+
cy.getFormFooterButtonByType(ADD_BUTTON_TEXT, 'submit').click();
54+
cy.wait('@addNamespaceApi');
55+
}
56+
57+
function selectAccordionElement(accordionItemLabel) {
58+
const pathToTargetNode =
59+
accordionItemLabel === NAMESPACE_NAME
60+
? [DOMAIN_NAME, NAMESPACE_NAME]
61+
: [DOMAIN_NAME];
62+
cy.interceptApi({
63+
alias: 'treeSelectApi',
64+
urlPattern: /\/miq_ae_class\/tree_select\?id=.*&text=.*/,
65+
triggerFn: () =>
66+
cy.selectAccordionItem([DATA_STORE_ACCORDION_LABEL, ...pathToTargetNode]),
67+
});
68+
}
69+
70+
function validateNamespaceFormFields(isEditForm = false) {
71+
// Assert form header is visible
72+
cy.expect_explorer_title(NAMESPACE_FORM_HEADER);
73+
// Assert sub header is visible
74+
cy.get('#main-content #datastore-form-wrapper h3').contains(
75+
NAMESPACE_FORM_SUB_HEADER
76+
);
77+
// Assert name-space path field label is visible
78+
cy.getFormLabelByInputId('namespacePath').should('be.visible');
79+
// Assert name-space path field is visible and disabled
80+
cy.getFormInputFieldById('namespacePath')
81+
.should('be.visible')
82+
.and('be.disabled')
83+
.invoke('val')
84+
.should('include', DOMAIN_NAME);
85+
// Assert name field label is visible
86+
cy.getFormLabelByInputId('name').should('be.visible');
87+
// Assert name field is visible and enabled
88+
cy.getFormInputFieldById('name').should('be.visible').and('be.enabled');
89+
// Assert description field label is visible
90+
cy.getFormLabelByInputId('description').should('be.visible');
91+
// Assert description field is visible and enabled
92+
cy.getFormInputFieldById('description')
93+
.should('be.visible')
94+
.and('be.enabled');
95+
// Assert cancel button is visible and enabled
96+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT)
97+
.should('be.visible')
98+
.and('be.enabled');
99+
// Assert add/save button is visible and disabled
100+
cy.getFormFooterButtonByType(
101+
isEditForm ? SAVE_BUTTON_TEXT : ADD_BUTTON_TEXT,
102+
'submit'
103+
)
104+
.should('be.visible')
105+
.and('be.disabled');
106+
if (isEditForm) {
107+
// Assert reset button is visible and disabled
108+
cy.getFormFooterButtonByType(RESET_BUTTON_TEXT)
109+
.should('be.visible')
110+
.and('be.disabled');
111+
}
112+
}
113+
114+
function createNamespaceAndOpenEditForm() {
115+
// Adding a new namespace
116+
addNamespace(NAMESPACE_NAME);
117+
// Selecting the created namespace from the accordion list items
118+
selectAccordionElement(NAMESPACE_NAME);
119+
// Opening the edit form
120+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_EDIT_NAMESPACE);
121+
}
122+
123+
function extractDomainIdAndTokenFromResponse(interception) {
124+
const rawTreeObject = interception?.response?.body?.reloadTrees?.ae_tree;
125+
if (rawTreeObject) {
126+
const rawTreeParsed = JSON.parse(rawTreeObject);
127+
rawTreeParsed.every((treeObject) => {
128+
// Exit iteration once id is extracted from nodes array
129+
return treeObject?.nodes?.every((nodeObject) => {
130+
if (nodeObject?.text === DOMAIN_NAME) {
131+
const domainId = nodeObject?.key?.split('-')?.[1];
132+
const csrfToken = interception?.request?.headers?.['x-csrf-token'];
133+
const idAndToken = {
134+
domainId,
135+
csrfToken,
136+
};
137+
// Creating an aliased state to store id and token
138+
cy.wrap(idAndToken).as('idAndToken');
139+
140+
// Stop iterating once the domain id is found
141+
return false;
142+
}
143+
// Continue iterating
144+
return true;
145+
});
146+
});
147+
}
148+
}
149+
150+
describe('Automate operations on Namespaces: Automation -> Embedded Automate -> Explorer -> {Any-created-domain} -> Namespace form', () => {
151+
beforeEach(() => {
152+
cy.login();
153+
// Navigate to Explorer under Automation -> Embedded Automate
154+
cy.menu(
155+
AUTOMATION_MENU_OPTION,
156+
EMBEDDED_AUTOMATION_MENU_OPTION,
157+
EXPLORER_MENU_OPTION
158+
);
159+
// Expand "Datastore" accordion if not already expanded
160+
cy.accordion(DATA_STORE_ACCORDION_LABEL);
161+
/* TODO: DATA_SETUP - Refactor to use API for domain data setup */
162+
// Creating a domain to test namespace operations
163+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_ADD_NEW_DOMAIN);
164+
cy.getFormInputFieldById('name').type(DOMAIN_NAME);
165+
cy.getFormInputFieldById('description').type(DESCRIPTION);
166+
cy.intercept('POST', '/miq_ae_class/create_namespace/new?button=add').as(
167+
'addNamespaceApi'
168+
);
169+
cy.getFormFooterButtonByType(ADD_BUTTON_TEXT, 'submit').click();
170+
cy.wait('@addNamespaceApi').then((interception) => {
171+
extractDomainIdAndTokenFromResponse(interception);
172+
});
173+
cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_ADD_SUCCESS);
174+
// Selecting the created domain from the accordion list items
175+
selectAccordionElement(DOMAIN_NAME);
176+
});
177+
178+
it('Validate Add Namespace form fields', () => {
179+
// Navigating to the Add Namespace form
180+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_ADD_NEW_NAMESPACE);
181+
182+
// Validating the form fields
183+
validateNamespaceFormFields();
184+
185+
// Cancelling the form
186+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click();
187+
});
188+
189+
it('Validate Cancel button', () => {
190+
// Navigating to the Add Namespace form
191+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_ADD_NEW_NAMESPACE);
192+
193+
// Cancelling the form
194+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT)
195+
.should('be.enabled')
196+
.click();
197+
cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_CANCELLED);
198+
});
199+
200+
it('Validate Name field allows only alphanumeric and _ . - $ characters', () => {
201+
// Trying to add a namespace with invalid characters
202+
addNamespace(INVALID_NAMESPACE_NAME);
203+
cy.expect_flash(flashClassMap.error, FLASH_MESSAGE_INVALID_NAMESPACE);
204+
205+
// Cancelling the form
206+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click();
207+
});
208+
209+
it('Validate Edit Namespace form fields', () => {
210+
// Create a namespace and open the edit form
211+
createNamespaceAndOpenEditForm();
212+
213+
// Validating the form fields
214+
validateNamespaceFormFields(true);
215+
216+
// Cancelling the form
217+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click();
218+
});
219+
220+
it('Checking whether add, edit & delete namespace works', () => {
221+
// Adding a new namespace
222+
addNamespace(NAMESPACE_NAME);
223+
cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_ADD_SUCCESS);
224+
225+
// Selecting the created namespace from the accordion list items
226+
selectAccordionElement(NAMESPACE_NAME);
227+
// Editing the namespace
228+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_EDIT_NAMESPACE);
229+
// Checking if the Save button is disabled initially
230+
cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit').should(
231+
'be.disabled'
232+
);
233+
cy.getFormInputFieldById('description').clear().type(EDITED_DESCRIPTION);
234+
cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit')
235+
.should('be.enabled')
236+
.click();
237+
cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SAVE_SUCCESS);
238+
239+
// Deleting the namespace
240+
cy.expect_browser_confirm_with_text({
241+
confirmTriggerFn: () =>
242+
cy.toolbar(TOOLBAR_CONFIGURATION, TOOLBAR_REMOVE_NAMESPACE),
243+
containsText: BROWSER_CONFIRM_REMOVE_MESSAGE,
244+
});
245+
cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_NAMESPACE_REMOVED);
246+
});
247+
248+
it('Checking whether creating a duplicate namespace is restricted', () => {
249+
// Adding a new namespace
250+
addNamespace(NAMESPACE_NAME);
251+
// Trying to add duplicate namespace
252+
addNamespace(NAMESPACE_NAME);
253+
cy.expect_flash(flashClassMap.error, FLASH_MESSAGE_NAME_ALREADY_EXISTS);
254+
255+
// Cancelling the form
256+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click();
257+
});
258+
259+
it('Checking whether Cancel & Reset buttons work fine in the Edit form', () => {
260+
// Create a namespace and open the edit form
261+
createNamespaceAndOpenEditForm();
262+
263+
/* Validating Reset button */
264+
// Checking if the Reset button is disabled initially
265+
cy.getFormFooterButtonByType(RESET_BUTTON_TEXT).should('be.disabled');
266+
// Editing name and description fields
267+
cy.getFormInputFieldById('name').clear().type(EDITED_NAMESPACE_NAME);
268+
cy.getFormInputFieldById('description').clear().type(EDITED_DESCRIPTION);
269+
// Resetting
270+
cy.getFormFooterButtonByType(RESET_BUTTON_TEXT)
271+
.should('be.enabled')
272+
.click();
273+
cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_RESET_NAMESPACE);
274+
// Confirming the edited fields contain the old values after resetting
275+
cy.getFormInputFieldById('name').should('have.value', NAMESPACE_NAME);
276+
cy.getFormInputFieldById('description').should('have.value', DESCRIPTION);
277+
278+
/* Validating Cancel button */
279+
cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click();
280+
cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_CANCELLED);
281+
});
282+
283+
afterEach(() => {
284+
// Selecting the created domain(Test_Domain) from the accordion list items
285+
selectAccordionTree(dataStoreAccordionItem);
286+
cy.accordionItem(domainName);
287+
cy.wait('@getCreatedDomainInfo');
288+
// Removing the domain
289+
cy.expect_browser_confirm_with_text({
290+
confirmTriggerFn: () =>
291+
cy.toolbar(toolbarConfiguration, toolbarRemoveDomain),
292+
containsText: browserConfirmRemoveMessage,
293+
});
294+
});
295+
});

0 commit comments

Comments
 (0)