Merge "Wait for loader on each Selenium's ulitimateWait"
[vid.git] / vid-webpack-master / cypress / integration / iFrames / instantiation-templates.e2e.ts
1 import * as _ from "lodash";
2 import {PropertyPath} from "lodash";
3
4 describe('Drawing Board: Instantiation Templates', function () {
5
6   describe('Instantiation templates ', () => {
7
8     beforeEach(() => {
9       cy.clearSessionStorage();
10       cy.setTestApiParamToGR();
11       cy.initAAIMock();
12       cy.initGetAAISubDetails();
13       cy.initVidMock();
14       cy.initDrawingBoardUserPermission();
15       cy.login();
16
17       mockAsyncBulkResponse();
18     });
19
20     afterEach(() => {
21       cy.screenshot();
22     });
23
24     describe('Load Page and Deploy', () => {
25
26       it(`Given a stored template - when click "deploy" - then a coherent request should be sent upon deploy`, () => {
27
28         loadDrawingBoardWithRecreateMode();
29
30         // Then...
31         cy.getElementByDataTestsId("node-vProbe_NC_VNF 0").should('be.visible');
32         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd();
33       });
34
35       it('Given a template - User can remove existing VNF', () => {
36
37         loadDrawingBoardWithRecreateMode();
38
39         removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
40
41         cy.getDrawingBoardDeployBtn().click();
42         cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
43           cy.deepCompare(bodyOf(xhr).vnfs, {});
44         });
45
46       });
47
48       it('Given a template - User can add new VNF', () => {
49         loadDrawingBoardWithRecreateMode();
50         // add new node
51         addNewNode('node-vProbe_NC_VNF 0-add-btn')
52           .fillVnfPopup()
53           .getDrawingBoardDeployBtn().click()
54           .wait('@expectedPostAsyncInstantiation').then(xhr => {
55             const vnfRequest = bodyOf(xhr).vnfs['vProbe_NC_VNF 0_1'];
56
57             expect(vnfRequest.action).equals("Create");
58             expect(vnfRequest.rollbackOnFailure).equals("true");
59             expect(vnfRequest.originalName).equals("vProbe_NC_VNF 0");
60             expect(vnfRequest.productFamilyId).equals("a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
61             expect(vnfRequest.lcpCloudRegionId).equals("hvf6");
62             expect(vnfRequest.lineOfBusiness).equals("zzz1");
63             expect(vnfRequest.platformName).equals("xxx1");
64             expect(vnfRequest.tenantId).equals("229bcdc6eaeb4ca59d55221141d01f8e");
65         });
66       });
67
68       it('Given a template - User can Duplicate VNF', () => {
69         const numberOfDuplicate: number = 4;
70         loadDrawingBoardWithRecreateMode();
71         nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
72           .getElementByDataTestsId('duplicate-amount-vfmodules').select(numberOfDuplicate.toString())
73           .getTagElementContainsText('button', 'Duplicate').click()
74           .getDrawingBoardDeployBtn().click()
75           .wait('@expectedPostAsyncInstantiation').then(xhr => {
76             expect(Object.keys(bodyOf(xhr).vnfs).length).equals(numberOfDuplicate + 1);
77         });
78       });
79
80       it('Given a stored template - when "edit" vnf and vfmodules are opened - then template’s details are visible as expected and deploy without changes', () => {
81
82         loadDrawingBoardWithRecreateMode();
83
84         // Then...
85         editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
86           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007')
87           .getElementByDataTestsId("productFamily").should('contain', 'Emanuel')
88           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
89           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
90           .getElementByDataTestsId("lineOfBusiness").should('contain', 'zzz1')
91           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
92           .checkPlatformValue('xxx1')
93           .getElementByDataTestsId("cancelButton").click();
94
95         editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
96           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007_lba_Base_01')
97           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
98           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
99           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
100           .getElementByDataTestsId("cancelButton").click();
101
102         editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
103           .getElementByDataTestsId("instanceName").should('have.value', 'my_hvf6arlba007_lba_dj_01')
104           .getElementByDataTestsId("volumeGroupName").should('have.value', 'my_special_hvf6arlba007_lba_dj_01_vol')
105           .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
106           .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
107           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
108           .getElementByDataTestsId("sdncPreLoad").should('have.value', 'on')
109           .getElementByDataTestsId("cancelButton").click();
110
111         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
112           {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
113         ]);
114       });
115
116       it(`Given a stored template - when "edit" service is opened - then template’s details are visible as expected`, function () {
117
118         loadDrawingBoardWithRecreateMode();
119
120         cy.openServiceContextMenu()
121           .getElementByDataTestsId("context-menu-header-edit-item").click()
122           .getElementByDataTestsId("instanceName").should('have.value', 'vProbe_NC_Service_DG_new_SI')
123           .getElementByDataTestsId("subscriberName").should('contain', 'SILVIA ROBBINS')
124           .getElementByDataTestsId("serviceType").should('contain', 'TYLER SILVIA')
125           .getElementByDataTestsId("owningEntity").should('contain', 'WayneHolland')
126           .getElementByDataTestsId("project").should('contain', 'WATKINS')
127           .getElementByDataTestsId("rollback").should('contain', 'Rollback');
128
129       });
130
131       it(`Given a stored template - add one VfModule, edit its details, and deploy - deploy is added with the vfModule details`, () => {
132         loadDrawingBoardWithRecreateMode();
133
134         let newVfModuleName = "new.vfmodule.name";
135         let module1ModelId = "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1";
136         let module1CustomizationId = `vprobe_nc_vnf0..${module1ModelId}`;
137
138         // Click target VNF on right tree
139         cy.getElementByDataTestsId('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0').click();
140
141         // Click [+] vfModule on left tree
142         cy.drawingBoardPressAddButtonByElementName(`node-${module1CustomizationId}`)
143           .click({force: true});
144
145         editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
146           cy.clearInput("instanceName");
147           cy.typeToInput("instanceName", newVfModuleName);
148           cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
149           cy.selectDropdownOptionByText('tenant', 'DN5242-Nov21-T1');
150           cy.getElementByDataTestsId('form-set').click();
151
152         // Then...
153         cy.getReduxState().then((state) => {
154           let vfModules_1Path = [
155             ...vnfPath, "vfModules", module1CustomizationId,
156           ];
157
158           let serviceInstanceElementOnRedux = state.service.serviceInstance[(templateWithVnfSetup.serviceModelId)];
159           let latestVfModule_1Path = findPathOfLatestVfModule(serviceInstanceElementOnRedux, vfModules_1Path);
160
161           // This is a funny merge, as values are already there, but that way ensures
162           // the values that selected are really deployed, while limiting the cost of
163           // maintenance, by taking other vfModule's fields as granted.
164           let latestVfModule_1ExpectedValue = _.merge(
165             _.get(serviceInstanceElementOnRedux, latestVfModule_1Path),
166             {
167               instanceName: newVfModuleName,
168               volumeGroupName: `${newVfModuleName}_vol`,
169               lcpCloudRegionId: "hvf6",
170               tenantId: "4914ab0ab3a743e58f0eefdacc1dde77",
171             }
172           );
173
174           assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
175             {path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"},   // side-effect
176             {path: ["existingNames", newVfModuleName], value: ""},
177             {path: ["existingNames", `${newVfModuleName}_vol`], value: ""},
178             {path: latestVfModule_1Path, value: latestVfModule_1ExpectedValue},
179             {path: ["validationCounter"], value: null},  // side-effect
180           ]);
181         });
182
183       });
184
185       [
186         {desc: "with changes", modifySomeValues: true},
187         {desc: "without changes", modifySomeValues: false},
188       ].forEach((testCase) => {
189
190         it(`Given a stored template - edit service vnf and vfmodule ${testCase.desc} - deploy request should be ${testCase.desc}`, function () {
191
192           loadDrawingBoardWithRecreateMode();
193
194           //edit service
195           cy.openServiceContextMenu();
196           cy.getElementByDataTestsId("context-menu-header-edit-item").click();
197           if (testCase.modifySomeValues) {
198             cy.clearInput("instanceName");
199             cy.typeToInput("instanceName", "different.instance.name");
200           }
201           cy.getElementByDataTestsId('form-set').click();
202
203           // edit vnf
204           editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
205           if (testCase.modifySomeValues) {
206             cy.selectPlatformValue('platform');
207             cy.selectDropdownOptionByText("tenant", "CESAR-100-D-spjg61909");
208           }
209           cy.getElementByDataTestsId('form-set').click();
210
211           //edit vf module
212           editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
213           if (testCase.modifySomeValues) {
214             cy.getElementByDataTestsId('sdncPreLoad').click();
215           }
216           cy.getElementByDataTestsId('form-set').click();
217
218           // Then...
219           let vfModule_0Path = [
220             ...vnfPath, "vfModules",
221             "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0",
222             "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0ahubg",
223           ];
224
225           assertThatBodyFromDeployRequestEqualsToFile(testCase.modifySomeValues ? [
226             {path: ["instanceName"], value: "different.instance.name"},
227             {path: ["existingNames", "vprobe_nc_service_dg_new_si"], value: undefined},
228             {path: ["existingNames", "different.instance.name"], value: ""},
229
230             {path: [...vnfPath, "platformName"], value: "xxx1,platform"},
231             {path: [...vnfPath, "tenantId"], value: "f2f3830e4c984d45bcd00e1a04158a79"},
232
233             {path: [...vfModule_0Path, "sdncPreLoad"], value: true},
234           ] : []);
235         })
236
237       });
238
239       it(`Given a stored template of Network - - it is loaded`,  () => {
240
241         loadDrawingBoardWithRecreateModeNetwork();
242
243         // Then...
244         cy.getElementByDataTestsId("node-SR-IOV Provider 2-1").should('be.visible');
245         cy.getElementByDataTestsId("node-SR-IOV Provider 2-2").should('be.visible');
246         assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network();
247       });
248
249
250     });
251   });
252 });
253
254 let apiTestResources = '../vid-automation/src/test/resources/asyncInstantiation/';
255
256 const templateWithVnfSetup = {
257   serviceModelId: '6cfeeb18-c2b0-49df-987a-da47493c8e38',
258   instanceTemplateFile: apiTestResources + 'templates__instance_template.json',
259   instanceTemplateSetWithoutModifyFile: apiTestResources + 'templates__instance_from_template__set_without_modify1.json',
260   serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model.json',
261 };
262
263 const templateWithNetworkSetup = {
264   serviceModelId: 'a1a14610-ee40-4049-8007-0608a20dd1fa',
265   instanceTemplateFile: apiTestResources + 'templates__instance_template_network.json',
266   serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model_network.json',
267 };
268
269 const vnfPath = [
270   "vnfs", "vProbe_NC_VNF 0"
271 ];
272
273 function loadDrawingBoardWithRecreateMode() {
274   loadDrawingBoardWithRecreateModeInternal(
275     '../../' + templateWithVnfSetup.instanceTemplateFile,
276     templateWithVnfSetup.serviceModelId,
277     templateWithVnfSetup.serviceModelFile);
278 }
279
280 function loadDrawingBoardWithRecreateModeNetwork() {
281   loadDrawingBoardWithRecreateModeInternal(
282     '../../' + templateWithNetworkSetup.instanceTemplateFile,
283     templateWithNetworkSetup.serviceModelId,
284     templateWithNetworkSetup.serviceModelFile);
285 }
286
287 function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
288   const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
289
290   const drawingBoardAction = `RECREATE`;
291   const templateTopologyEndpoint = "templateTopology";
292   cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
293     'fixture:' + serviceModel)
294     .as('serviceModel');
295
296   cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
297     'fixture:' + instanceTemplate)
298     .as('templateTopology');
299
300   // When...
301
302   cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
303     `?jobId=${templateUuid}` +
304     `&serviceModelId=${serviceModelIdToLoad}`);
305
306   cy.wait('@serviceModel');
307   cy.wait('@templateTopology');
308 }
309
310 function nodeAction(dataTestId: string, action: string, index ?: number) {
311   return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
312     .drawingBoardTreeClickOnContextMenuOptionByName(action)
313 }
314
315 function editNode(dataTestId: string, index ?: number) {
316   return nodeAction(dataTestId, 'Edit', index);
317 }
318
319 function addNewNode(dataTestId: string) {
320   return cy.getElementByDataTestsId(dataTestId).click({force: true})
321 }
322
323 function removeVNFWithVFModules(dataTestId: string) {
324   return nodeAction(dataTestId, 'Remove')
325     .getTagElementContainsText('button', 'Remove VNF').click()
326 }
327
328 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
329   assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(templateWithVnfSetup.instanceTemplateFile, deviationFromExpected);
330 }
331
332 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
333   assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(templateWithNetworkSetup.instanceTemplateFile, deviationFromExpected);
334 }
335
336 function assertThatBodyFromDeployRequestEqualsToTemplateFromBackEndInternal(filePathOfExpected: string, deviationFromExpected: { path: PropertyPath; value: any }[]) {
337   cy.getDrawingBoardDeployBtn().click();
338   cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
339     cy.readFile(filePathOfExpected).then((expectedResult) => {
340       convertRollbackOnFailureValueFromStringToBoolean(expectedResult);
341
342       let xhrBodyWithoutIsDirtyField = removeIsDirtyFieldFromXhrRequestBody(xhr);
343       setDeviationInExpected(expectedResult, deviationFromExpected);
344       cy.deepCompare(xhrBodyWithoutIsDirtyField, expectedResult);
345     });
346   });
347 }
348
349
350 function assertThatBodyFromDeployRequestEqualsToFile(deviationFromExpected: { path: PropertyPath, value: any }[] = []) {
351   cy.getDrawingBoardDeployBtn().click();
352   cy.wait('@expectedPostAsyncInstantiation').then(xhr => {
353
354     cy.readFile(templateWithVnfSetup.instanceTemplateSetWithoutModifyFile).then((expectedResult) => {
355       setDeviationInExpected(expectedResult, deviationFromExpected);
356       cy.deepCompare(xhr.request.body, expectedResult);
357     });
358
359   });
360 }
361
362 function bodyOf(xhr: Cypress.WaitXHR) {
363   return JSON.parse(JSON.stringify(xhr.request.body));
364 }
365
366 function setDeviationInExpected(expectedResult: any, deviations: { path: PropertyPath; value: any }[]) {
367   for (const deviation of deviations) {
368     _.set(expectedResult, deviation.path, deviation.value);
369   }
370 }
371
372 function findPathOfLatestVfModule(serviceInstanceElementFromRedux: any, vfModulesContainerPath: string[]) {
373   let latestVfModuleRandomlySelectedKey: string = _.last(_.keys(
374     _.get(serviceInstanceElementFromRedux, vfModulesContainerPath)
375   )) as string;
376
377   return [...vfModulesContainerPath, latestVfModuleRandomlySelectedKey];
378 }
379
380 //We use this function because the deployService() on drawing-board-header.component class
381 // changes rollbackOnFailure value from string type to boolean.
382 function convertRollbackOnFailureValueFromStringToBoolean(expectedResult: any) {
383   expectedResult.rollbackOnFailure = Boolean(expectedResult.rollbackOnFailure);
384 }
385
386 function removeIsDirtyFieldFromXhrRequestBody(xhr: any) {
387   let xhrTempBody = bodyOf(xhr);
388   delete xhrTempBody.isDirty;
389   return xhrTempBody;
390 }
391
392 function mockAsyncBulkResponse() {
393   cy.server().route({
394     url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
395     method: 'POST',
396     status: 200,
397     response: "[]",
398   }).as("expectedPostAsyncInstantiation");
399 }