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
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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
19 package org.onap.sdc.frontend.ci.tests.execute.sanity;
21 import static org.hamcrest.MatcherAssert.assertThat;
22 import static org.hamcrest.Matchers.empty;
23 import static org.hamcrest.Matchers.emptyString;
24 import static org.hamcrest.Matchers.not;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertFalse;
27 import static org.junit.jupiter.api.Assertions.assertNotNull;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.junit.jupiter.api.Assertions.fail;
31 import com.aventstack.extentreports.Status;
32 import java.util.Arrays;
33 import java.util.List;
35 import java.util.Optional;
36 import org.apache.commons.collections.MapUtils;
37 import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
38 import org.onap.sdc.backend.ci.tests.datatypes.enums.ResourceCategoryEnum;
39 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
40 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
41 import org.onap.sdc.frontend.ci.tests.datatypes.ModelName;
42 import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
43 import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
44 import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
45 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
46 import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
47 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
48 import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
49 import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
50 import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
51 import org.onap.sdc.frontend.ci.tests.flow.InterfaceDefinitionFlow;
52 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
53 import org.onap.sdc.frontend.ci.tests.pages.AttributeModal;
54 import org.onap.sdc.frontend.ci.tests.pages.AttributesPage;
55 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
56 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
57 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent;
58 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent.CompositionDetailTabName;
59 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInformationTab;
60 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
61 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
62 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
63 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
64 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionPage;
65 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
66 import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
67 import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
68 import org.openecomp.sdc.be.model.ComponentInstance;
69 import org.openqa.selenium.WebDriver;
70 import org.testng.annotations.BeforeClass;
71 import org.testng.annotations.Ignore;
72 import org.testng.annotations.Test;
73 import org.yaml.snakeyaml.Yaml;
75 @Ignore // solved in https://gerrit.onap.org/r/c/sdc/+/127976
76 public class ImportVfcUiTest extends SetupCDTest {
78 private String filePath;
79 private WebDriver webDriver;
80 private HomePage homePage;
81 private ResourceCreateData vfcCreateData;
82 private ResourceCreateData vfCreateData;
83 private ComponentInstance createdComponentInstance;
84 private final String vfcCategory = ResourceCategoryEnum.NETWORK_L4.getSubCategory();
87 public void beforeClass() {
88 filePath = FileHandling.getFilePath("VFCs/");
89 webDriver = DriverFactory.getDriver();
90 homePage = new HomePage(webDriver);
94 public void importVFC_createVF_addVFC2VF_test() throws UnzipException {
95 ComponentPage componentPage;
96 // TC - Import VFC with root namespace
97 String fileName = "org.openecomp.resource.VFC-root.yml";
98 CreateVfcFlow createVfcFlow = createVFC(fileName, ModelName.DEFAULT_MODEL_NAME.getName(), vfcCategory);
100 componentPage = createVfcFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
101 componentPage.isLoaded();
102 componentPage.certifyComponent();
103 componentPage.isLoaded();
105 Map<String, Object> yamlObject = downloadToscaArtifact(componentPage);
106 checkMetadata(yamlObject, vfcCreateData);
107 checkNodeTypes(yamlObject);
108 homePage.getTopNavComponent().clickOnHome();
110 // TC - Import hierarchy of VFCs
111 fileName = "org.openecomp.resource.VFC-child.yml";
112 createVfcFlow = createVFC(fileName, ModelName.DEFAULT_MODEL_NAME.getName(), vfcCategory);
113 componentPage = createVfcFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
114 componentPage.isLoaded();
116 componentPage = manageAttributes(componentPage);
117 componentPage.isLoaded();
118 componentPage.certifyComponent();
119 componentPage.isLoaded();
121 yamlObject = downloadToscaArtifact(componentPage);
122 checkMetadata(yamlObject, vfcCreateData);
123 checkNodeTypes(yamlObject);
125 componentPage = viewInterfaceDefinitionFromVFC(componentPage);
126 componentPage.isLoaded();
128 homePage.getTopNavComponent().clickOnHome();
130 // TC - Import VFC with interface inputs
131 // TC - Import VFC with attributes
132 final CreateVfFlow createVfFlow = createVF();
133 componentPage = createVfFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
134 componentPage.isLoaded();
136 final CompositionPage compositionPage = addInterfaceOperations(componentPage);
137 componentPage = compositionPage.goToGeneral();
138 componentPage.isLoaded();
139 componentPage.certifyComponent();
140 componentPage.isLoaded();
142 yamlObject = downloadToscaArtifact(componentPage);
143 checkMetadata(yamlObject, vfCreateData);
144 checkTopologyTemplate(yamlObject);
148 private ComponentPage viewInterfaceDefinitionFromVFC(final ComponentPage componentPage) {
149 final InterfaceDefinitionFlow interfaceDefinitionFlow = new InterfaceDefinitionFlow(webDriver);
150 interfaceDefinitionFlow.run(componentPage);
151 final InterfaceDefinitionPage interfaceDefinitionPage = interfaceDefinitionFlow.getLandedPage()
152 .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return InterfaceDefinitionPage"));
153 final var OPERATION_NAME = "create";
154 assertTrue(interfaceDefinitionPage.isInterfaceDefinitionOperationPresent(OPERATION_NAME));
155 final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal = interfaceDefinitionPage.clickOnInterfaceDefinitionOperation(
157 interfaceDefinitionOperationsModal.isLoaded(true);
159 .takeScreenshot(Status.INFO, "clickOnOInterfaceOperation", "Interface Definition Operation Modal opened");
160 checkInterfaceDefinitionData(interfaceDefinitionOperationsModal);
161 interfaceDefinitionOperationsModal.clickOnCancel();
162 return interfaceDefinitionPage;
166 public void importVfcWithModel() {
167 final String fileName = "VFC-For-Model.yaml";
168 final CreateVfcFlow createVfcFlow = createVFC(fileName, ModelName.ETSI_SOL001_v2_5_1.getName(), vfcCategory);
169 final ComponentPage componentPage = createVfcFlow.getLandedPage()
170 .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
171 componentPage.isLoaded();
172 componentPage.certifyComponent();
173 componentPage.isLoaded();
176 private void checkInterfaceDefinitionData(final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal) {
177 assertTrue(interfaceDefinitionOperationsModal.getDescription().isEmpty());
178 assertEquals("path/to/my/implementation.sh", interfaceDefinitionOperationsModal.getImplementationName());
179 final List<InputData> inputList = interfaceDefinitionOperationsModal.getInputs();
180 assertTrue(inputList.stream().anyMatch(inputData -> "first".equals(inputData.getName())), "Input of name 'first' expected");
183 private ComponentPage manageAttributes(final ComponentPage componentPage) {
184 final AttributesPage attributesPage = componentPage.goToAttributes();
185 attributesPage.isLoaded();
187 assertTrue(attributesPage.isAttributePresent("test_1"));
188 assertTrue(attributesPage.isAttributePresent("test_2"));
189 assertTrue(attributesPage.isAttributePresent("test_3"));
190 assertTrue(attributesPage.isAttributePresent("test_4"));
192 attributesPage.deleteAttribute("test_2");
193 assertFalse(attributesPage.isAttributePresent("test_2"));
194 ExtentTestActions.takeScreenshot(Status.INFO, "attributesPage.deleteAttribute", "Attribute 'test_2' successfully deleted");
195 attributesPage.addAttribute(new AttributeModal.AttributeData("test_9", "Additional attribute added from UI", "string", "one More Attribute"));
196 attributesPage.isLoaded();
197 assertTrue(attributesPage.isAttributePresent("test_9"));
198 ExtentTestActions.takeScreenshot(Status.INFO, "attributesPage.addAttribute", "Additional Attribute 'test_9' successfully added");
200 attributesPage.editAttribute(new AttributeModal.AttributeData("test_9", "Additional attribute added from UI".toUpperCase(), "string",
201 "one More Attribute".toUpperCase()));
202 attributesPage.isLoaded();
203 assertTrue(attributesPage.isAttributePresent("test_9"));
204 ExtentTestActions.takeScreenshot(Status.INFO, "attributesPage.editAttribute", "Additional Attribute 'test_9' successfully altered");
206 return attributesPage.clickOnGeneralMenuItem(ResourceCreatePage.class);
209 private CompositionPage addInterfaceOperations(final ComponentPage componentPage) {
210 final AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToCompositionFlow(componentPage);
211 final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
212 .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
213 final CompositionDetailSideBarComponent detailSideBar = compositionPage.getDetailSideBar();
214 detailSideBar.isLoaded();
216 createdComponentInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
217 .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ComponentInstance"));
219 compositionPage.selectNode(createdComponentInstance.getName());
221 CompositionInterfaceOperationsTab compositionInterfaceOperationsTab =
222 (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
223 compositionInterfaceOperationsTab.isLoaded();
224 ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab", "Composition Interface Operations Tab opened");
225 assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
226 InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
227 compositionInterfaceOperationsModal.isLoaded();
229 .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
230 compositionInterfaceOperationsModal.deleteInput("first");
231 ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.clickOnDelete", "Input deleted");
233 List<InputData> inputDataList = List.of(
234 new InputData("stringInput", "string", "1"),
235 new InputData("booleanInput", "boolean", true),
236 new InputData("integerInput", "integer", 1)
238 final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData =
239 new InterfaceDefinitionOperationsModal.InterfaceOperationsData(
240 "This is CREATE operation", "fullPath/to/my/newImplementation.sh", inputDataList
242 compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
243 compositionInterfaceOperationsTab.isLoaded();
245 final CompositionInformationTab compositionInformationTab =
246 (CompositionInformationTab) detailSideBar.selectTab(CompositionDetailTabName.INFORMATION);
247 compositionInformationTab.isLoaded();
249 compositionInterfaceOperationsTab =
250 (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
251 compositionInterfaceOperationsTab.isLoaded();
253 assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
254 assertTrue(compositionInterfaceOperationsTab.isDescriptionPresent());
255 ExtentTestActions.takeScreenshot(Status.INFO, "isDescriptionPresent", "Description is present");
256 compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
257 compositionInterfaceOperationsModal.isLoaded();
259 .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
261 checkCompositionInterfaceOperations(compositionInterfaceOperationsModal, interfaceOperationsData);
262 compositionInterfaceOperationsModal.clickOnCancel();
263 compositionInterfaceOperationsTab.isLoaded();
264 return compositionPage;
267 private AddNodeToCompositionFlow addNodeToCompositionFlow(final ComponentPage componentPage) {
268 componentPage.isLoaded();
269 final ComponentData parentComponent = new ComponentData();
270 parentComponent.setName(vfCreateData.getName());
271 parentComponent.setVersion("0.1");
272 parentComponent.setComponentType(ComponentType.RESOURCE);
273 final ComponentData componentToAdd = new ComponentData();
274 componentToAdd.setName(vfcCreateData.getName());
275 componentToAdd.setVersion("1.0");
276 componentToAdd.setComponentType(ComponentType.RESOURCE);
277 final AddNodeToCompositionFlow addNodeToCompositionFlow = new AddNodeToCompositionFlow(webDriver, parentComponent, componentToAdd);
278 addNodeToCompositionFlow.run(componentPage.goToComposition());
279 return addNodeToCompositionFlow;
282 private Map<String, Object> downloadToscaArtifact(final ComponentPage componentPage) throws UnzipException {
283 final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadCsarArtifact(componentPage);
284 final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
285 .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
287 assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
288 final String downloadedCsarName = toscaArtifactsPage.getDownloadedArtifactList().get(0);
289 final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
290 final Map<String, byte[]> filesFromZip = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
291 final Optional<String> resourceEntryOpt = filesFromZip.keySet().stream()
292 .filter(s -> s.equals("Definitions/" + downloadedCsarName.replace("-csar.csar", "-template.yml")))
294 if (resourceEntryOpt.isEmpty()) {
295 fail("Could not find the resource package in Definitions");
297 return loadYamlObject(filesFromZip.get(resourceEntryOpt.get()));
300 private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
302 return (Map<String, Object>) yamlObj.get(entryName);
303 } catch (final Exception e) {
304 final String errorMsg = String.format("Could not get the '%s' entry.", entryName);
305 fail(errorMsg + "Error message: " + e.getMessage());
310 private Map<String, Object> loadYamlObject(final byte[] mainDefinitionFileBytes) {
311 return new Yaml().load(new String(mainDefinitionFileBytes));
314 private DownloadCsarArtifactFlow downloadCsarArtifact(final ComponentPage componentPage) {
315 final DownloadCsarArtifactFlow downloadCsarArtifactFlow = new DownloadCsarArtifactFlow(webDriver);
316 downloadCsarArtifactFlow.setWaitBeforeGetTheFile(5L);
317 downloadCsarArtifactFlow.run(componentPage);
318 return downloadCsarArtifactFlow;
321 private CreateVfcFlow createVFC(final String fileName, final String model, final String category) {
322 vfcCreateData = createVfcFormData(model, category);
323 final CreateVfcFlow createVfcFlow = new CreateVfcFlow(webDriver, vfcCreateData, filePath + fileName);
324 createVfcFlow.run(homePage);
325 return createVfcFlow;
328 private CreateVfFlow createVF() {
329 vfCreateData = createVfFormData();
330 final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
331 createVfFlow.run(homePage);
335 private ResourceCreateData createVfcFormData(final String model, final String category) {
336 final ResourceCreateData vfcCreateData = new ResourceCreateData();
337 vfcCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VFC");
338 vfcCreateData.setModel(model);
339 vfcCreateData.setCategory(category);
340 vfcCreateData.setTagList(Arrays.asList(vfcCreateData.getName(), "importVFC"));
341 vfcCreateData.setDescription("aDescription");
342 vfcCreateData.setVendorName("Ericsson");
343 vfcCreateData.setVendorRelease("1.2.3");
344 vfcCreateData.setVendorModelNumber("4.5.6");
345 return vfcCreateData;
348 private ResourceCreateData createVfFormData() {
349 final ResourceCreateData vfCreateData = new ResourceCreateData();
350 vfCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VF");
351 vfCreateData.setCategory(ResourceCategoryEnum.NETWORK_L4.getSubCategory());
352 vfCreateData.setTagList(Arrays.asList(vfCreateData.getName(), "createVF"));
353 vfCreateData.setDescription("aDescription");
354 vfCreateData.setVendorName("Ericsson");
355 vfCreateData.setVendorRelease("6.5.4");
356 vfCreateData.setVendorModelNumber("3.2.1");
360 private void checkMetadata(final Map<String, Object> map, final ResourceCreateData createdData) {
361 final Map<String, Object> metadata = getMapEntry(map, "metadata");
363 assertEquals(createdData.getName(), metadata.get("name"));
364 assertEquals(createdData.getDescription(), metadata.get("description"));
365 assertEquals("Network L4+", metadata.get("category"));
366 assertThat((String) metadata.get("type"), not(emptyString()));
367 assertEquals(createdData.getCategory(), metadata.get("subcategory"));
368 assertEquals(createdData.getVendorName(), metadata.get("resourceVendor"));
369 assertEquals(createdData.getVendorRelease(), metadata.get("resourceVendorRelease"));
370 assertEquals(createdData.getVendorModelNumber(), metadata.get("reourceVendorModelNumber"));
373 private void checkNodeTypes(final Map<String, Object> map) {
374 final Map<String, Object> mapEntry = getMapEntry(map, "node_types");
375 final Map<String, Object> nodeTypes = getMapEntry(mapEntry, mapEntry.keySet().iterator().next());
377 assertFalse(MapUtils.isEmpty(nodeTypes));
378 assertEquals("aDescription", nodeTypes.get("description"));
380 final Map<String, Object> properties = getMapEntry(nodeTypes, "properties");
381 assertFalse(MapUtils.isEmpty(properties));
383 final Map<String, Object> attributes = getMapEntry(nodeTypes, "attributes");
384 assertFalse(MapUtils.isEmpty(attributes));
386 final Map<String, Object> interfaces = getMapEntry(nodeTypes, "interfaces");
387 assertFalse(MapUtils.isEmpty(interfaces));
391 private void checkTopologyTemplate(final Map<String, Object> map) {
392 final Map<String, Object> topologyTemplate = getMapEntry(map, "topology_template");
393 assertNotNull(topologyTemplate);
395 final Map<String, Object> inputs = getMapEntry(topologyTemplate, "inputs");
396 assertFalse(MapUtils.isEmpty(inputs));
398 final Map<String, Object> nodeTemplates = getMapEntry(topologyTemplate, "node_templates");
399 assertFalse(MapUtils.isEmpty(nodeTemplates));
401 final Map<String, Object> attributes = getMapEntry((Map<String, Object>) nodeTemplates.get(createdComponentInstance.getName()), "attributes");
402 assertFalse(MapUtils.isEmpty(attributes));
403 assertEquals(4, attributes.keySet().stream()
404 .filter(s -> (s.contains("test_1") || s.contains("test_3") || s.contains("test_4") || s.contains("test_9")) && !s.contains("test_2"))
407 final Map<String, Object> substitutionMappings = getMapEntry(topologyTemplate, "substitution_mappings");
408 assertFalse(MapUtils.isEmpty(substitutionMappings));
412 private void checkCompositionInterfaceOperations(final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal,
413 final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
414 assertEquals(interfaceOperationsData.getDescription(), compositionInterfaceOperationsModal.getDescription());
415 assertEquals(interfaceOperationsData.getImplementationName(), compositionInterfaceOperationsModal.getImplementationName());
416 interfaceOperationsData.getInputList().forEach(inputData -> {
417 final boolean hasInput = compositionInterfaceOperationsModal.getInputs().stream()
418 .anyMatch(inputData1 -> inputData1.getName().equals(inputData.getName()));
419 assertTrue(hasInput, String.format("Expecting input '%s'", inputData.getName()));