d3ab9d49a19a8fef337ef6f7a5da2e0e857d23cd
[sdc.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.sdc.frontend.ci.tests.execute.sanity;
21
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.hamcrest.Matchers.anEmptyMap;
24 import static org.hamcrest.Matchers.empty;
25 import static org.hamcrest.Matchers.emptyString;
26 import static org.hamcrest.Matchers.hasSize;
27 import static org.hamcrest.Matchers.is;
28 import static org.hamcrest.Matchers.not;
29 import static org.hamcrest.Matchers.notNullValue;
30 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertNotEquals;
32 import static org.junit.jupiter.api.Assertions.assertNotNull;
33 import static org.junit.jupiter.api.Assertions.assertTrue;
34 import static org.junit.jupiter.api.Assertions.fail;
35
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Map.Entry;
43 import java.util.Optional;
44 import java.util.stream.Collectors;
45
46 import org.onap.sdc.backend.ci.tests.data.providers.OnboardingDataProviders;
47 import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
48 import org.onap.sdc.backend.ci.tests.datatypes.enums.ResourceCategoryEnum;
49 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
50 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
51 import org.onap.sdc.frontend.ci.tests.datatypes.DirectiveType;
52 import org.onap.sdc.frontend.ci.tests.datatypes.LogicalOperator;
53 import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
54 import org.onap.sdc.frontend.ci.tests.datatypes.ServiceDependencyProperty;
55 import org.onap.sdc.frontend.ci.tests.datatypes.composition.RelationshipInformation;
56 import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
57 import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
58 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
59 import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
60 import org.onap.sdc.frontend.ci.tests.flow.AddComponentPropertyFlow;
61 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
62 import org.onap.sdc.frontend.ci.tests.flow.CreateDirectiveNodeFilterFlow;
63 import org.onap.sdc.frontend.ci.tests.flow.CreateSubstitutionFilterFlow;
64 import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
65 import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
66 import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
67 import org.onap.sdc.frontend.ci.tests.flow.DownloadToscaTemplateFlow;
68 import org.onap.sdc.frontend.ci.tests.flow.EditComponentPropertiesFlow;
69 import org.onap.sdc.frontend.ci.tests.flow.composition.CreateRelationshipFlow;
70 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
71 import org.onap.sdc.frontend.ci.tests.pages.AttributesOutputsPage;
72 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
73 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
74 import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesAssignmentPage;
75 import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesPage;
76 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
77 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
78 import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
79 import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
80 import org.openecomp.sdc.be.model.ComponentInstance;
81 import org.openqa.selenium.WebDriver;
82 import org.slf4j.Logger;
83 import org.slf4j.LoggerFactory;
84 import org.testng.annotations.BeforeMethod;
85 import org.testng.annotations.Test;
86 import org.yaml.snakeyaml.Yaml;
87
88 import com.aventstack.extentreports.Status;
89
90 public class ServiceTemplateDesignUiTests extends SetupCDTest {
91
92     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTemplateDesignUiTests.class);
93
94     private WebDriver webDriver;
95     private HomePage homePage;
96     private List<ResourceCreateData> vfcs = new ArrayList<>();
97     private ResourceCreateData vfResourceCreateData;
98     private ComponentInstance networkFunctionInstance;
99     private ComponentInstance networkServiceInstance;
100     private AddNodeToCompositionFlow addNodeToCompositionFlow;
101     private ComponentPage componentPage;
102     private Map<String, String> propertiesToBeAddedMap;
103     private final List<ServiceDependencyProperty> substitutionFilterProperties = new ArrayList<>();
104
105     @BeforeMethod
106     public void init() {
107         webDriver = DriverFactory.getDriver();
108         homePage = new HomePage(webDriver);
109     }
110
111     @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "vfcList")
112     public void importAndCertifyVfc(final String rootFolder, final String vfcFilename) {
113         setLog(vfcFilename);
114         final String resourceName = ElementFactory.addRandomSuffixToName(ElementFactory.getResourcePrefix());
115         final CreateVfcFlow createVfcFlow = createVFC(rootFolder + vfcFilename, resourceName);
116         vfcs.stream().filter(vfc -> vfc.getName().startsWith(resourceName)).findFirst().orElseThrow(
117             () -> new UiTestFlowRuntimeException(String.format("VFCs List should contain a VFC with the expected name %s", resourceName)));
118         final ResourceCreatePage vfcResourceCreatePage = createVfcFlow.getLandedPage()
119             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ResourceCreatePage"));
120         vfcResourceCreatePage.isLoaded();
121         vfcResourceCreatePage.certifyComponent();
122         ExtentTestActions.takeScreenshot(Status.INFO, "vfc-certified",
123             String.format("VFC '%s' was certified", resourceName));
124     }
125
126     @Test(dependsOnMethods = "importAndCertifyVfc")
127     public void createBaseService() throws UnzipException {
128         final CreateVfFlow createVfFlow = createVF();
129         addNodeToCompositionFlow = addNodeToCompositionAndCreateRelationship(createVfFlow);
130         final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
131             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
132         compositionPage.isLoaded();
133         componentPage = compositionPage.goToGeneral();
134         componentPage.isLoaded();
135         downloadAndVerifyCsarPackageAfterBaseServiceCreation(componentPage);
136     }
137
138     @Test(dependsOnMethods = "createBaseService")
139     public void addComponentProperty() throws UnzipException {
140         propertiesToBeAddedMap = loadPropertiesToAdd();
141         addProperty(propertiesToBeAddedMap);
142         componentPage = addValueToProperty(loadPropertiesToEdit());
143         componentPage.isLoaded();
144         downloadAndVerifyCsarPackageAfterAddProperty(componentPage);
145     }
146
147     @Test(dependsOnMethods = "createBaseService")
148     public void addOutputsToVF_test() throws UnzipException, IOException {
149         homePage.isLoaded();
150         final ComponentPage resourceCreatePage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
151         resourceCreatePage.isLoaded();
152
153         final AttributesOutputsPage attributesOutputsPage = resourceCreatePage.goToAttributesOutputs();
154         attributesOutputsPage.isLoaded();
155
156         final ComponentInstance createdComponentInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
157             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ComponentInstance"));
158
159         attributesOutputsPage.clickOnAttributeNavigation(createdComponentInstance.getName());
160         assertTrue(attributesOutputsPage.isAttributePresent("attr_1"));
161         attributesOutputsPage.declareOutput("attr_1");
162         attributesOutputsPage.clickOnOutputsTab();
163         assertTrue(attributesOutputsPage.isOutputPresent("attr_1"));
164
165         attributesOutputsPage.clickOnAttributesTab();
166         assertTrue(attributesOutputsPage.isAttributePresent("attr_2"));
167         attributesOutputsPage.declareOutput("attr_2");
168         attributesOutputsPage.clickOnOutputsTab();
169         assertTrue(attributesOutputsPage.isOutputPresent("attr_2"));
170
171         attributesOutputsPage.clickOnAttributesTab();
172         assertTrue(attributesOutputsPage.isAttributePresent("attr_3"));
173         attributesOutputsPage.declareOutput("attr_3");
174         attributesOutputsPage.clickOnOutputsTab();
175         assertTrue(attributesOutputsPage.isOutputPresent("attr_3"));
176
177         attributesOutputsPage.deleteOutput(createdComponentInstance.getName() + "_attr_2");
178         attributesOutputsPage.clickOnAttributesTab();
179         assertTrue(attributesOutputsPage.isAttributePresent("attr_2"));
180         attributesOutputsPage.clickOnOutputsTab();
181         assertTrue(attributesOutputsPage.isOutputDeleted("attr_2"));
182
183         attributesOutputsPage.clickOnAttributesTab();
184         ExtentTestActions.addScreenshot(Status.INFO, "AttributesTab", "The Attribute's list : ");
185
186         attributesOutputsPage.clickOnOutputsTab();
187         ExtentTestActions.addScreenshot(Status.INFO, "OutputsTab", "The Output's list : ");
188
189         Map<String, Object> yamlObject = downloadToscaArtifact(attributesOutputsPage);
190         checkMetadata(yamlObject, vfResourceCreateData);
191         checkTopologyTemplate(yamlObject);
192     }
193
194
195     @Test(dependsOnMethods = "addComponentProperty")
196     public void createSubstitutionFilter() throws Exception {
197         componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
198         componentPage.isLoaded();
199         loadSubstitutionFilterProperties();
200         final CompositionPage compositionPage = componentPage.goToComposition();
201         compositionPage.isLoaded();
202         substitutionFilterProperties.forEach(substitutionFilterProperty -> {
203             final CreateSubstitutionFilterFlow createSubstitutionFilterFlow = new CreateSubstitutionFilterFlow(webDriver, substitutionFilterProperty);
204             createSubstitutionFilterFlow.run(compositionPage);
205         });
206         componentPage = compositionPage.goToGeneral();
207         componentPage.isLoaded();
208         verifyToscaTemplateHasSubstitutionFilter(downloadToscaTemplate());
209     }
210
211     @Test(dependsOnMethods = "createBaseService")
212     public void createDirectiveNodeFilterTest() throws Exception {
213         final ResourceCreateData vfcResourceCreateData = vfcs.get(1);
214         final String vfcNameInComposition = vfcResourceCreateData.getName().concat(" 0");
215         final String value = "Test";
216         final LogicalOperator operator = LogicalOperator.EQUALS;
217         homePage.isLoaded();
218         componentPage = (ComponentPage) homePage.clickOnComponent(vfcResourceCreateData.getName());
219
220         componentPage.isLoaded();
221         final ResourcePropertiesPage vfcPropertiesPage = componentPage.goToProperties();
222         vfcPropertiesPage.isLoaded();
223         final List<String> propertyNames = vfcPropertiesPage.getPropertyNames();
224         final ServiceDependencyProperty serviceDependencyProperty = new ServiceDependencyProperty(propertyNames.get(0), value, operator);
225
226         homePage.getTopNavComponent().clickOnHome();
227         homePage.isLoaded();
228         homePage.clickOnComponent(vfResourceCreateData.getName());
229
230         componentPage.isLoaded();
231         final CompositionPage compositionPage = componentPage.goToComposition();
232         compositionPage.isLoaded();
233         compositionPage.selectNode(vfcNameInComposition);
234
235         final CreateDirectiveNodeFilterFlow createDirectiveNodeFilterFlow =
236                 new CreateDirectiveNodeFilterFlow(webDriver, 2, DirectiveType.SELECT, serviceDependencyProperty);
237         createDirectiveNodeFilterFlow.run(componentPage);
238
239         verifyAvailableDirectiveTypes(createDirectiveNodeFilterFlow.getDirectiveOptions());
240
241         verifyAvailablePropertyNames(propertyNames, createDirectiveNodeFilterFlow.getPropertyOptions());
242
243         componentPage = compositionPage.goToGeneral();
244         componentPage.isLoaded();
245         final Map<?, ?> yaml = downloadToscaTemplate();
246         verifyToscaTemplateHasDirectiveNodeFilter(yaml, serviceDependencyProperty, vfcNameInComposition);
247     }
248
249     private void checkMetadata(final Map<String, Object> map, final ResourceCreateData createdData) {
250         final Map<String, Object> metadata = getMapEntry(map, "metadata");
251
252         assertEquals(createdData.getName(), metadata.get("name"));
253         assertEquals(createdData.getDescription(), metadata.get("description"));
254         assertEquals("Generic", metadata.get("category"));
255         assertThat((String) metadata.get("type"), not(emptyString()));
256         assertEquals(createdData.getCategory(), metadata.get("subcategory"));
257         assertEquals(createdData.getVendorName(), metadata.get("resourceVendor"));
258         assertEquals(createdData.getVendorRelease(), metadata.get("resourceVendorRelease"));
259         assertEquals(createdData.getVendorModelNumber(), metadata.get("reourceVendorModelNumber"));
260     }
261
262     private void checkTopologyTemplate(final Map<String, Object> map) {
263         final Map<String, Object> mapEntry = getMapEntry(map, "topology_template");
264         assertNotNull(mapEntry);
265
266         final Map<String, Object> inputs = getMapEntry(mapEntry, "inputs");
267         assertThat(inputs, not(anEmptyMap()));
268
269         final Map<String, Object> outputs = getMapEntry(mapEntry, "outputs");
270         assertThat(outputs, not(anEmptyMap()));
271         assertEquals(2, outputs.keySet().stream().filter(s -> (s.contains("_attr_1") || s.contains("_attr_3")) && !s.contains("_attr_2")).count());
272
273         final Map<String, Object> nodeTemplates = getMapEntry(mapEntry, "node_templates");
274         assertThat(nodeTemplates, not(anEmptyMap()));
275
276         final Map<String, Object> substitutionMappings = getMapEntry(mapEntry, "substitution_mappings");
277         assertThat(substitutionMappings, not(anEmptyMap()));
278
279         final Map<String, Object> attributes = getMapEntry(substitutionMappings, "attributes");
280         assertThat(attributes, not(anEmptyMap()));
281         assertEquals(2, attributes.keySet().stream().filter(s -> (s.contains("_attr_1") || s.contains("_attr_3")) && !s.contains("_attr_2")).count());
282     }
283
284     private Map<String, Object> downloadToscaArtifact(final ComponentPage resourceCreatePage) throws UnzipException {
285         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadToscaCsar(resourceCreatePage);
286         final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
287             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
288
289         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
290         final String downloadedCsarName = toscaArtifactsPage.getDownloadedArtifactList().get(0);
291         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
292         final Map<String, byte[]> filesFromZip = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
293         final Optional<String> resourceEntryOpt = filesFromZip.keySet().stream()
294             .filter(s -> s.equals("Definitions/" + downloadedCsarName.replace("-csar.csar", "-template.yml")))
295             .findFirst();
296         if (resourceEntryOpt.isEmpty()) {
297             fail("Could not find the resource package in Definitions");
298         }
299         return loadYamlObject(filesFromZip.get(resourceEntryOpt.get()));
300     }
301
302     private CreateVfFlow createVF() {
303         final ResourceCreateData vfCreateData = createVfFormData();
304         final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
305         createVfFlow.run(homePage);
306         return createVfFlow;
307     }
308
309     private ResourceCreateData createVfFormData() {
310         vfResourceCreateData = new ResourceCreateData();
311         vfResourceCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VF");
312         vfResourceCreateData.setCategory(ResourceCategoryEnum.GENERIC_ABSTRACT.getSubCategory());
313         vfResourceCreateData.setTagList(Arrays.asList(vfResourceCreateData.getName(), "createVF"));
314         vfResourceCreateData.setDescription("aDescription");
315         vfResourceCreateData.setVendorName("EST");
316         vfResourceCreateData.setVendorRelease("4.1.1");
317         vfResourceCreateData.setVendorModelNumber("0001");
318         return vfResourceCreateData;
319     }
320
321     private CreateVfcFlow createVFC(final String vfcFullFilename, final String resourceName) {
322         final ResourceCreateData vfcCreateData = createVfcFormData(resourceName);
323         final CreateVfcFlow createVfcFlow = new CreateVfcFlow(webDriver, vfcCreateData, vfcFullFilename);
324         createVfcFlow.run(homePage);
325         ExtentTestActions.takeScreenshot(Status.INFO, "vfc-created", String.format("VFC '%s' was created", resourceName));
326         assertThat(vfcs, notNullValue());
327         vfcs.add(vfcCreateData);
328         return createVfcFlow;
329     }
330
331     private ResourceCreateData createVfcFormData(final String resourceName) {
332         final ResourceCreateData vfcCreateData = new ResourceCreateData();
333         vfcCreateData.setRandomName(resourceName);
334         vfcCreateData.setCategory(ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS.getSubCategory());
335         vfcCreateData.setTagList(Arrays.asList(vfcCreateData.getName(), "importVFC"));
336         vfcCreateData.setDescription("aDescription");
337         vfcCreateData.setVendorName("EST");
338         vfcCreateData.setVendorRelease("4.1.1");
339         vfcCreateData.setVendorModelNumber("0001");
340         return vfcCreateData;
341     }
342
343     private AddNodeToCompositionFlow addNodeToCompositionAndCreateRelationship(final CreateVfFlow createVfFlow) {
344         final ResourceCreatePage resourceCreatePage = createVfFlow.getLandedPage()
345             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ResourceCreatePage"));
346         resourceCreatePage.isLoaded();
347         assertThat(vfcs, hasSize(2));
348         final ComponentData parentComponent = new ComponentData();
349         parentComponent.setName(vfResourceCreateData.getName());
350         parentComponent.setVersion("0.1");
351         parentComponent.setComponentType(ComponentType.RESOURCE);
352
353         // Adds networkFunction to VF composition
354         final ComponentData networkFunction = new ComponentData();
355         networkFunction.setName(vfcs.get(0).getName());
356         networkFunction.setVersion("1.0");
357         networkFunction.setComponentType(ComponentType.RESOURCE);
358         CompositionPage compositionPage = resourceCreatePage.goToComposition();
359         compositionPage.isLoaded();
360         AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkFunction, compositionPage);
361         networkFunctionInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
362             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
363
364         // Adds networkService to VF composition
365         final ComponentData networkService = new ComponentData();
366         networkService.setName(vfcs.get(1).getName());
367         networkService.setVersion("1.0");
368         networkService.setComponentType(ComponentType.RESOURCE);
369         addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkService, compositionPage);
370         networkServiceInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
371             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
372
373         // Creates a dependsOn relationship from networkServiceInstance to networkFunctionInstance
374         createRelationship(compositionPage, networkFunctionInstance.getName(), "tosca.capabilities.Node",
375             networkServiceInstance.getName(), "tosca.capabilities.Node");
376
377         return addNodeToCompositionFlow;
378     }
379
380     public AddNodeToCompositionFlow addNodeToComposition(final ComponentData parentComponent,
381                                                          final ComponentData resourceToAdd,
382                                                          CompositionPage compositionPage) {
383         final AddNodeToCompositionFlow addNodeToCompositionFlow = new AddNodeToCompositionFlow(webDriver, parentComponent, resourceToAdd);
384         compositionPage = (CompositionPage) addNodeToCompositionFlow.run(compositionPage)
385             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected CompositionPage"));
386         compositionPage.isLoaded();
387         ExtentTestActions.takeScreenshot(Status.INFO, "node-added-to-composition",
388             String.format("Resource '%s' was added to composition", resourceToAdd.getName()));
389         return addNodeToCompositionFlow;
390     }
391
392     /**
393      * Creates a DependsOn relationship between the imported VFCs
394      * @param compositionPage Composition Page
395      * @param fromComponentInstanceName VFC - Network Function
396      * @param fromCapability Node Capability
397      * @param toComponentInstanceName  VFC - Network Service
398      * @param toRequirement Node Requirement
399      */
400     private void createRelationship(final CompositionPage compositionPage, final String fromComponentInstanceName,
401                                     final String fromCapability, final String toComponentInstanceName, final String toRequirement) {
402         final RelationshipInformation relationshipInformation =
403             new RelationshipInformation(fromComponentInstanceName, fromCapability, toComponentInstanceName, toRequirement);
404         CreateRelationshipFlow createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInformation);
405         createRelationshipFlow.run(compositionPage).orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a CompositionPage instance"));
406         ExtentTestActions.takeScreenshot(Status.INFO, "relationship",
407             String.format("Relationship from networkFunctionInstance '%s' to networkServiceInstanceResource '%s' was created",
408                 fromComponentInstanceName, toComponentInstanceName));
409     }
410
411     /**
412      * Adds a property to the base service
413      * @param propertyMap map of properties to be added
414      */
415     private void addProperty(final Map<String, String> propertyMap) {
416         componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
417         componentPage.isLoaded();
418         final AddComponentPropertyFlow addComponentPropertyFlow = new AddComponentPropertyFlow(webDriver, propertyMap);
419         addComponentPropertyFlow.run(componentPage.goToPropertiesAssignment());
420     }
421
422     /**
423      * Edits a property to add a value
424      * @param propertyMap map of properties to be edited
425      */
426     private ComponentPage addValueToProperty(final Map<String, Object> propertyMap) {
427         final EditComponentPropertiesFlow editComponentPropertiesFlow = new EditComponentPropertiesFlow(webDriver, propertyMap);
428         return editComponentPropertiesFlow.run().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ComponentPage"));
429     }
430
431     /**
432      * Downloads and verifies the generated tosca templates.
433      * @param componentPage the component page
434      * @throws UnzipException
435      */
436     private void downloadAndVerifyCsarPackageAfterBaseServiceCreation(final ComponentPage componentPage) throws UnzipException {
437         checkCsarPackage(downloadCsarPackage(componentPage));
438     }
439
440     /**
441      * Downloads and verifies if the generated Tosca template contains the expected properties.
442      * @throws UnzipException
443      * @param componentPage
444      */
445     private void downloadAndVerifyCsarPackageAfterAddProperty(final ComponentPage componentPage) throws UnzipException {
446         verifyPropertiesOnGeneratedTemplate(downloadCsarPackage(componentPage));
447     }
448
449     private String downloadCsarPackage(final ComponentPage componentPage) {
450         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadToscaCsar(componentPage);
451         final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
452             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
453         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
454         return toscaArtifactsPage.getDownloadedArtifactList().get(0);
455     }
456
457     /**
458      * Downloads the generated CSAR package.
459      * @param componentPage the component page
460      * @return the Downloaded Tosca CSAR file
461      */
462     private DownloadCsarArtifactFlow downloadToscaCsar(final ComponentPage componentPage) {
463         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = new DownloadCsarArtifactFlow(webDriver);
464         downloadCsarArtifactFlow.setWaitBeforeGetTheFile(5L);
465         downloadCsarArtifactFlow.run(componentPage);
466         return downloadCsarArtifactFlow;
467     }
468
469     /**
470      * Verifies if the generated Tosca template contains the expected properties.
471      * @param downloadedCsarName the downloaded csar file name
472      * @throws UnzipException
473      */
474     private void verifyPropertiesOnGeneratedTemplate(final String downloadedCsarName) throws UnzipException {
475         final Map<String, byte[]> filesFromZip = extractFilesFromCsar(downloadedCsarName);
476         final String virtualFunctionName = vfResourceCreateData.getName().replace("-", "").toLowerCase();
477         final String vfResourceTemplateFile = "Definitions/resource-" + virtualFunctionName + "-template-interface.yml";
478         final String interfaceTemplateFile = filesFromZip.keySet().stream()
479             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
480             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
481         final byte[] toscaInterfaceTemplateGenerated = filesFromZip.get(interfaceTemplateFile);
482         assertThat("The Generated Tosca template should not be null", toscaInterfaceTemplateGenerated, is(notNullValue()));
483         final Map<String, Object> interfaceTemplateYamlMap = loadYamlObject(toscaInterfaceTemplateGenerated);
484         final Map<String, Object> nodeTypesYamlMap = getMapEntry(interfaceTemplateYamlMap, "node_types");
485         assertThat(String.format("'%s' should contain a node_types entry", interfaceTemplateYamlMap), nodeTypesYamlMap, is(notNullValue()));
486         final Map<String, Object> properties = (Map) nodeTypesYamlMap.values().stream().filter(stringObjectEntry -> stringObjectEntry != null)
487             .collect(Collectors.toList()).get(0);
488         final Map<String, Object> propertiesFoundMap = (Map<String, Object>) properties.get("properties");
489         assertThat(String.format("The generated template file %s should contain all added properties", vfResourceTemplateFile),
490             propertiesFoundMap.keySet().containsAll(propertiesToBeAddedMap.keySet()), is(true));
491     }
492
493     /**
494      * Checks if the downloaded Tosca csar includes the node templates for the added VFCs,
495      * the generated service template declared “tosca_simple_yaml_1_3” as its Tosca version,
496      * the generated csar contains the node type definitions for the added VFCs in the Definitions directory,
497      * the interface template contains the relationship declaration
498      * @param downloadedCsarName download Tosca CSAR filename
499      * @throws UnzipException
500      */
501     private void checkCsarPackage(final String downloadedCsarName) throws UnzipException {
502         final Map<String, byte[]> filesFromZip = extractFilesFromCsar(downloadedCsarName);
503         final String virtualFunctionName = vfResourceCreateData.getName().replace("-", "").toLowerCase();
504         final List<String> expectedDefinitionFolderFileList = getExpectedDefinitionFolderFileList(virtualFunctionName);
505         final Map<String, byte[]> expectedFilesFromZipMap = filesFromZip.entrySet().parallelStream()
506             .filter(key -> expectedDefinitionFolderFileList.stream()
507                 .anyMatch(filename -> filename.equalsIgnoreCase(key.getKey()))).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
508         final String vfResourceTemplateFile = "Definitions/resource-" + virtualFunctionName + "-template.yml";
509         final String generatedTemplateFile = expectedFilesFromZipMap.keySet().stream()
510             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
511             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
512         final byte[] toscaTemplateGenerated = filesFromZip.get(generatedTemplateFile);
513         assertThat(toscaTemplateGenerated, is(notNullValue()));
514         verifyGeneratedTemplate(toscaTemplateGenerated, generatedTemplateFile);
515         verifyNodesRelationship(expectedFilesFromZipMap, virtualFunctionName, filesFromZip);
516     }
517
518     private Map<String, byte[]> extractFilesFromCsar(final String downloadedCsarName) throws UnzipException {
519         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
520         final Map<String, byte[]> filesFromCsar = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
521         return filesFromCsar;
522     }
523
524     private void verifyGeneratedTemplate(final byte[] generatedTemplateData, final String generatedTemplateFile) {
525         final Map<String, Object> templateYamlMap = loadYamlObject(generatedTemplateData);
526         final boolean hasToscaDefinitionVersionEntry = templateYamlMap.containsKey("tosca_definitions_version");
527         assertThat(String.format("'%s' should contain tosca_definitions_version entry", generatedTemplateFile), hasToscaDefinitionVersionEntry,
528             is(true));
529         final String toscaVersion = (String) templateYamlMap.get("tosca_definitions_version");
530         assertThat(String.format("'%s' tosca_definitions_version entry should have tosca_simple_yaml_1_3 value", generatedTemplateFile),
531             toscaVersion.equalsIgnoreCase("tosca_simple_yaml_1_3"));
532         final Map<String, Object> topologyTemplateTosca = getMapEntry(templateYamlMap, "topology_template");
533         assertThat(String.format("'%s' should contain a topology_template entry", generatedTemplateFile), topologyTemplateTosca, is(notNullValue()));
534         final Map<String, Object> nodeTemplatesTosca = getMapEntry(topologyTemplateTosca, "node_templates");
535         assertThat(String.format("'%s' should contain a node_templates entry", generatedTemplateFile), nodeTemplatesTosca, is(notNullValue()));
536         final List<String> nodeTemplateFound = nodeTemplatesTosca.keySet().parallelStream().filter(s -> vfcs.stream()
537             .anyMatch(vfc -> s.startsWith(vfc.getName()))).collect(Collectors.toList());
538         assertThat(String.format("'%s' should contain the node type definitions for the added VFCs '%s'", nodeTemplatesTosca, vfcs),
539             nodeTemplateFound, hasSize(vfcs.size()));
540     }
541
542     private void verifyNodesRelationship(final Map<String, byte[]> expectedFilesFromZipMap, final String virtualFunctionName,
543                                          final Map<String, byte[]> filesFromZip) {
544         final String vfResourceTemplateFile = "Definitions/resource-" + virtualFunctionName + "-template-interface.yml";
545         final String interfaceTemplateFile = expectedFilesFromZipMap.keySet().stream()
546             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
547             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
548         final byte[] toscaInterfaceTemplateGenerated = filesFromZip.get(interfaceTemplateFile);
549         assertThat(toscaInterfaceTemplateGenerated, is(notNullValue()));
550         final Map<String, Object> interfaceTemplateYamlMap = loadYamlObject(toscaInterfaceTemplateGenerated);
551         final Map<String, Object> nodeTypesYamlMap = getMapEntry(interfaceTemplateYamlMap, "node_types");
552         assertThat(String.format("'%s' should contain a node_types entry", interfaceTemplateYamlMap), nodeTypesYamlMap, is(notNullValue()));
553         final String result = Arrays.asList(nodeTypesYamlMap.values()).toString();
554         assertThat(String.format("'%s' should contain a capabilities entry", nodeTypesYamlMap), result.contains("capabilities"), is(true));
555         assertThat(String.format("'%s' should contain a requirements entry", nodeTypesYamlMap), result.contains("requirements"), is(true));
556         assertThat(String.format("'%s' should contain a relationship entry", nodeTypesYamlMap), result.contains("relationship"), is(true));
557         assertThat(String.format("'%s' should contain a DependsOn relationship value", nodeTypesYamlMap),
558             result.contains("tosca.relationships.DependsOn"), is(true));
559     }
560
561     private List<String> getExpectedDefinitionFolderFileList(final String vfResourceName) {
562         final List<String> expectedDefinitionFolderFileList = new ArrayList<>();
563         vfcs.forEach(vfc -> expectedDefinitionFolderFileList.add("Definitions/resource-" + vfc.getName() + "-template.yml"));
564         expectedDefinitionFolderFileList.add("Definitions/resource-" + vfResourceName + "-template.yml");
565         expectedDefinitionFolderFileList.add("Definitions/resource-" + vfResourceName + "-template-interface.yml");
566         return expectedDefinitionFolderFileList;
567     }
568
569     private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
570         try {
571             return (Map<String, Object>) yamlObj.get(entryName);
572         } catch (final Exception e) {
573             final String errorMsg = String.format("Could not get the '%s' entry.", entryName);
574             LOGGER.error(errorMsg, e);
575             fail(errorMsg + "Error message: " + e.getMessage());
576         }
577         return null;
578     }
579
580     private Map<String, Object> loadYamlObject(final byte[] definitionYamlFile) {
581         return new Yaml().load(new String(definitionYamlFile));
582     }
583
584     private Map<String, String> loadPropertiesToAdd() {
585         final Map<String, String> propertyMap = new HashMap<>();
586         propertyMap.put("property1", "string");
587         propertyMap.put("property2", "integer");
588         propertyMap.put("property3", "boolean");
589         propertyMap.put("property4", "list");
590         propertyMap.put("property5", "map");
591         propertyMap.put("property6", "scalar-unit.size");
592         return propertyMap;
593     }
594
595     private Map<String, Object> loadPropertiesToEdit() {
596         final Map<String, Object> propertyMap = new HashMap<>();
597         propertyMap.put("property1", "Integration Test");
598         propertyMap.put("property2", 100);
599         propertyMap.put("property3", Boolean.TRUE);
600         propertyMap.put("property4", Arrays.asList("PropListV1", "PropListV2", "PropListV3"));
601         final Map<String, String> stringMap = new HashMap<>();
602         stringMap.put("PropMapKey1", "PropMapValue1");
603         stringMap.put("PropMapKey2", "PropMapValue2");
604         stringMap.put("PropMapKey3", "PropMapValue3");
605         propertyMap.put("property5", stringMap);
606         propertyMap.put("property6", 500);
607         return propertyMap;
608     }
609
610     private void loadSubstitutionFilterProperties() {
611         final ResourcePropertiesAssignmentPage propertiesPage = componentPage.goToPropertiesAssignment();
612         propertiesPage.isLoaded();
613         ExtentTestActions.takeScreenshot(Status.INFO, "propertiesAssigment",
614             String.format("The %s Properties Assignment Page is loaded", vfResourceCreateData.getName()));
615         Map<String, String> propertyNamesAndTypes = propertiesPage.getPropertyNamesAndTypes();
616         assertThat(String.format("The Component '%s' should have properties", vfResourceCreateData.getName()), propertyNamesAndTypes,
617             not(anEmptyMap()));
618         propertyNamesAndTypes.forEach((name, type)
619             -> substitutionFilterProperties.add(new ServiceDependencyProperty(name, getPropertyValueByType(type), LogicalOperator.EQUALS)));
620     }
621
622     private String getPropertyValueByType(final String type) {
623         switch (type) {
624             case "string":
625                 return "IntegrationTest";
626             case "integer":
627                 return "202";
628             case "size":
629                 return "500";
630             case "boolean":
631                 return "TRUE";
632             case "list":
633                 return "[value1, value2]";
634             case "map":
635                 return "MyKey: MyValue";
636             default:
637                 throw new UnsupportedOperationException("Not yet implemented for " + type);
638         }
639     }
640
641     /**
642      * Downloads Tosca Template file
643      * @return the tosca template yaml file
644      * @throws Exception
645      */
646     private Map<?, ?> downloadToscaTemplate() throws Exception {
647         final DownloadToscaTemplateFlow downloadToscaTemplateFlow = new DownloadToscaTemplateFlow(webDriver);
648         final ToscaArtifactsPage toscaArtifactsPage = (ToscaArtifactsPage) downloadToscaTemplateFlow.run(componentPage).get();
649         return FileHandling.parseYamlFile(getConfig().getDownloadAutomationFolder()
650             .concat(java.io.File.separator).concat(toscaArtifactsPage.getDownloadedArtifactList().get(0)));
651     }
652
653     private void verifyToscaTemplateHasSubstitutionFilter(final Map<?, ?> yaml) {
654         assertNotNull(yaml, "No contents in TOSCA Template");
655         final List<?> substitutionFilters = (List<?>) getSubstitutionFilterFromYaml(yaml).get("properties");
656         substitutionFilterProperties.forEach(substitutionFilterProperty -> {
657             final Map<?, ?> substitutionFilterMap = (Map<?, ?>) substitutionFilters.stream()
658                 .filter(subFilter -> ((Map<?, ?>) subFilter).containsKey(substitutionFilterProperty.getName())).findAny().get();
659             assertThat("Added substitution filter not found in TOSCA Template",
660                 substitutionFilterMap.containsKey(substitutionFilterProperty.getName()));
661             final Map<?, ?> substitutionFilterValue = (Map<?, ?>) ((List<?>) substitutionFilterMap.get(substitutionFilterProperty.getName())).get(0);
662             assertThat("Substitution Filter Value should not be empty", substitutionFilterMap, not(anEmptyMap()));
663             final String expectedSubstitutionPropertyValue = substitutionFilterProperty.getValue();
664             final String actualSubstitutionPropertyValue = substitutionFilterValue.values().stream().findFirst().get() instanceof Map
665                 ? substitutionFilterValue.values().stream().findFirst().get().toString().replace("=", ": ")
666                 .replaceAll("\\{(.*?)\\}", "$1").trim()
667                 : substitutionFilterValue.values().stream().findFirst().get().toString();
668             assertThat("Invalid value for added substitution filters found in TOSCA Template",
669                 expectedSubstitutionPropertyValue.equalsIgnoreCase(actualSubstitutionPropertyValue));
670             assertThat("Invalid logical operator for added substitution filters found in TOSCA Template",
671                 substitutionFilterValue.containsKey(substitutionFilterProperty.getLogicalOperator().getName()));
672         });
673     }
674
675     private Map<?, ?> getSubstitutionFilterFromYaml(final Map<?, ?> yaml) {
676         final Map<?, ?> topology = (Map<?, ?>) yaml.get("topology_template");
677         final Map<?, ?> substitutionMappings = (Map<?, ?>) topology.get("substitution_mappings");
678         return (Map<?, ?>) substitutionMappings.get("substitution_filter");
679     }
680
681     private void verifyAvailableDirectiveTypes(final List<String> availableDirectiveTypes) {
682         assertNotNull(availableDirectiveTypes, "Expected list of available Directive Types, but recieved null");
683         Arrays.asList(DirectiveType.values()).forEach(directiveType -> {
684             assertTrue(availableDirectiveTypes.contains(directiveType.getName())
685                     , String.format("Expected directive %s to be availabe in UI options %s"
686                             , directiveType.getName(), availableDirectiveTypes.toString()));
687         });
688         ExtentTestActions.log(Status.PASS, "All expected directive types are available for selection");
689     }
690
691     private void verifyAvailablePropertyNames(List<String> propertyNames, List<String> propertyNameOptions) {
692         assertEquals(propertyNameOptions.size(), propertyNames.size(), "Mismatch in the number of properties available for selection");
693         propertyNames.forEach(name -> {
694             assertNotEquals(false, propertyNameOptions.remove(name)
695                     , String.format("Expected property %s not found in UI Select element", name));
696         });
697         ExtentTestActions.log(Status.PASS, "All expected properties are available for selection");
698     }
699
700     private void verifyToscaTemplateHasDirectiveNodeFilter(final Map<?, ?> yaml, ServiceDependencyProperty nodeFilterProperty, String nodeTemplateName) {
701         assertNotNull(yaml, "Tosca Template Yaml is not expected to be empty");
702         final List<?> nodeFilters = (List<?>) getDirectiveNodeFilterFromYaml(yaml, nodeTemplateName).get("properties");
703         final Map<?, ?> nodeFilter = (Map<?, ?>) nodeFilters.stream()
704                     .filter(yamlNodeFilter -> ((Map<?, ?>) yamlNodeFilter).containsKey(nodeFilterProperty.getName())).findAny().get();
705         assertNotNull(nodeFilter, "Added directive node filter not found in TOSCA Template");
706
707         final Map<?, ?> nodeFilterValue = (Map<?, ?>) ((List<?>) nodeFilter.get(nodeFilterProperty.getName())).get(0);
708         assertTrue(nodeFilterValue.containsValue(nodeFilterProperty.getValue())
709                 , "Invalid value for added directive node filter found in TOSCA Template");
710         assertTrue(nodeFilterValue.containsKey(nodeFilterProperty.getLogicalOperator().getName())
711                 , "Invalid logical operator for added directive node filter found in TOSCA Template");
712     }
713
714     private Map<?,?> getDirectiveNodeFilterFromYaml(final Map<?,?> yaml, String nodeTemplateName) {
715         final Map<?, ?> topology = (Map<?, ?>) yaml.get("topology_template");
716         final Map<?, ?> nodeTemplates = (Map<?, ?>) topology.get("node_templates");
717         final Map<?, ?> resourceNode = (Map<?, ?>) nodeTemplates.get(nodeTemplateName);
718         return (Map<?, ?>) resourceNode.get("node_filter");
719     }
720 }