aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvasraz <vasyl.razinkov@est.tech>2021-04-26 14:52:08 +0100
committervasraz <vasyl.razinkov@est.tech>2021-04-27 16:09:16 +0100
commit5aa2c74c18bc5f7e9774f192d7419259a0fac733 (patch)
tree6114a5c54f69ef71c20ef83bed2e10ff973ef7ba
parent8c814c644cbcdd27e45bad595abe971983d3a850 (diff)
Enrich 'Import VFC UI test'
Import a node types which contains interface operations with an implementation and inputs Change-Id: Ibf778747b69c60514d94985fc13097403ae1dd56 Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech> Issue-ID: SDC-3567
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html3
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html114
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java76
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceCreatePage.java6
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDetailSideBarComponent.java4
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java149
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java94
-rw-r--r--integration-tests/src/test/resources/Files/VFCs/org.openecomp.resource.VFC-child.yml20
8 files changed, 396 insertions, 70 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html
index 80aceeadda..156b657645 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/input-param-row/input-param-row.component.html
@@ -21,6 +21,7 @@
<div class="cell field-input-name">
<sdc-input
[(value)]="input.name"
+ testId="interface-operation-input-name"
(valueChange)="onChange()">
</sdc-input>
</div>
@@ -28,9 +29,9 @@
<div class="cell field-input-value">
<sdc-input
[(value)]="input.toscaDefaultValue"
+ testId="interface-operation-input-value"
(valueChange)="onChange()">
</sdc-input>
-
</div>
<div class="cell remove" *ngIf="!readonly">
diff --git a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
index cd2d6063c1..f71102053a 100644
--- a/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
+++ b/catalog-ui/src/app/ng2/pages/composition/interface-operatons/operation-creator/interface-operation-handler.component.html
@@ -19,68 +19,70 @@
-->
<div class="operation-handler">
- <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
+ <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
- <form class="w-sdc-form">
+ <form class="w-sdc-form">
- <div class="side-by-side">
- <div class="form-item">
- <sdc-input
- label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}"
- [(value)]="interfaceType"
- [disabled]="true">
- </sdc-input>
- </div>
+ <div class="side-by-side">
+ <div class="form-item">
+ <sdc-input
+ label="{{ 'OPERATION_INTERFACE_TYPE' | translate }}"
+ [(value)]="interfaceType"
+ [disabled]="true">
+ </sdc-input>
+ </div>
- <div class="form-item">
- <sdc-input
- label="{{ 'OPERATION_NAME' | translate }}"
- [(value)]="operationToUpdate.name"
- [disabled]="true">
- </sdc-input>
- </div>
- </div>
+ <div class="form-item">
+ <sdc-input
+ label="{{ 'OPERATION_NAME' | translate }}"
+ [(value)]="operationToUpdate.name"
+ [disabled]="true">
+ </sdc-input>
+ </div>
+ </div>
- <div class="i-sdc-form-item">
- <sdc-input
- label="{{'OPERATION_DESCRIPTION' | translate}}"
- [(value)]="operationToUpdate.description"
- (valueChange)="onDescriptionChange($event)">
- </sdc-input>
- </div>
+ <div class="i-sdc-form-item">
+ <sdc-input
+ label="{{'OPERATION_DESCRIPTION' | translate}}"
+ [(value)]="operationToUpdate.description"
+ testId="interface-operation-description"
+ (valueChange)="onDescriptionChange($event)">
+ </sdc-input>
+ </div>
- <div class="i-sdc-form-item">
- <sdc-input
- label="{{'IMPLEMENTATION_NAME' | translate}}"
- [(value)]="operationToUpdate.implementation.artifactName">
- </sdc-input>
- </div>
+ <div class="i-sdc-form-item">
+ <sdc-input
+ label="{{'IMPLEMENTATION_NAME' | translate}}"
+ testId="interface-operation-implementation-name"
+ [(value)]="operationToUpdate.implementation.artifactName">
+ </sdc-input>
+ </div>
- <div class="separator-buttons">
- <tab tabTitle="Inputs"></tab>
- <a class="add-param-link add-btn"
- [ngClass]="{'disabled': readonly}"
- (click)="onAddInput()">{{'OPERATION_ADD_INPUT' | translate}}
- </a>
- </div>
+ <div class="separator-buttons">
+ <tab tabTitle="Inputs"></tab>
+ <a class="add-param-link add-btn"
+ [ngClass]="{'disabled': readonly}"
+ (click)="onAddInput()">{{'OPERATION_ADD_INPUT' | translate}}
+ </a>
+ </div>
- <div class="generic-table">
- <div class="header-row table-row">
- <span class="cell header-cell field-input-name">{{ 'OPERATION_PARAM_NAME' | translate }}</span>
- <span class="cell header-cell field-input-value">{{ 'OPERATION_INPUT_VALUE' | translate }}</span>
- <span class="cell header-cell remove">●●●</span>
- </div>
- <div class="empty-msg data-row" *ngIf="!inputs.length">
- <div>{{ 'OPERATION_INPUT_EMPTY' | translate }}</div>
- </div>
- <input-param-row
- *ngFor="let inputParameter of inputs"
- class="data-row"
- [input]="inputParameter"
- [onRemoveInput]="onRemoveInput"
- [validityChanged]="validityChanged">
- </input-param-row>
- </div>
+ <div class="generic-table">
+ <div class="header-row table-row">
+ <span class="cell header-cell field-input-name">{{ 'OPERATION_PARAM_NAME' | translate }}</span>
+ <span class="cell header-cell field-input-value">{{ 'OPERATION_INPUT_VALUE' | translate }}</span>
+ <span class="cell header-cell remove">●●●</span>
+ </div>
+ <div class="empty-msg data-row" *ngIf="!inputs.length">
+ <div>{{ 'OPERATION_INPUT_EMPTY' | translate }}</div>
+ </div>
+ <input-param-row
+ *ngFor="let inputParameter of inputs"
+ class="data-row"
+ [input]="inputParameter"
+ [onRemoveInput]="onRemoveInput"
+ [validityChanged]="validityChanged">
+ </input-param-row>
+ </div>
- </form>
+ </form>
</div>
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
index 9c733f6aa5..a571c1b9f6 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java
@@ -25,8 +25,10 @@ import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+import com.aventstack.extentreports.Status;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
@@ -37,6 +39,7 @@ import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
+import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
@@ -44,10 +47,16 @@ import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionDetailSideBarComponent.CompositionDetailTabName;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInformationTab;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsModal;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInterfaceOperationsTab;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
+import org.openecomp.sdc.be.model.ComponentInstance;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -105,20 +114,71 @@ public class ImportVfcUiTest extends SetupCDTest {
componentPage = createVfFlow.getLandedPage().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
componentPage.isLoaded();
- final AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToCompositionFlow(componentPage);
-
- final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
- .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
+ final CompositionPage compositionPage = addInterfaceOperations(componentPage);
componentPage = compositionPage.goToGeneral();
componentPage.isLoaded();
componentPage.certifyComponent();
componentPage.isLoaded();
+
yamlObject = downloadToscaArtifact(componentPage);
checkMetadata(yamlObject, vfCreateData);
checkTopologyTemplate(yamlObject);
}
+ private CompositionPage addInterfaceOperations(final ComponentPage componentPage) {
+ final AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToCompositionFlow(componentPage);
+ final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
+ .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
+ final CompositionDetailSideBarComponent detailSideBar = compositionPage.getDetailSideBar();
+ detailSideBar.isLoaded();
+
+ final ComponentInstance createdComponentInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
+ .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ComponentInstance"));
+
+ compositionPage.selectNode(createdComponentInstance.getName());
+
+ CompositionInterfaceOperationsTab compositionInterfaceOperationsTab =
+ (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
+ compositionInterfaceOperationsTab.isLoaded();
+ ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab", "Composition Interface Operations Tab opened");
+ assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
+ CompositionInterfaceOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
+ compositionInterfaceOperationsModal.isLoaded();
+ ExtentTestActions
+ .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
+ compositionInterfaceOperationsModal.clickOnDelete();
+ ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.clickOnDelete", "Input deleted");
+ compositionInterfaceOperationsModal.addInput();
+ ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.addInput", "Adding Input");
+
+ final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData = new CompositionInterfaceOperationsModal.InterfaceOperationsData
+ ("This is CREATE operation", "fullPath/to/my/newImplementation.sh", "second", "9876");
+ compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
+ compositionInterfaceOperationsTab.isLoaded();
+
+ final CompositionInformationTab compositionInformationTab =
+ (CompositionInformationTab) detailSideBar.selectTab(CompositionDetailTabName.INFORMATION);
+ compositionInformationTab.isLoaded();
+
+ compositionInterfaceOperationsTab =
+ (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
+ compositionInterfaceOperationsTab.isLoaded();
+
+ assertTrue(compositionInterfaceOperationsTab.isOperationPresent("create"));
+ assertTrue(compositionInterfaceOperationsTab.isDescriptionPresent());
+ ExtentTestActions.takeScreenshot(Status.INFO, "isDescriptionPresent", "Description is present");
+ compositionInterfaceOperationsModal = compositionInterfaceOperationsTab.clickOnOperation("create");
+ compositionInterfaceOperationsModal.isLoaded();
+ ExtentTestActions
+ .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened");
+
+ checkCompositionInterfaceOperations(compositionInterfaceOperationsModal, interfaceOperationsData);
+ compositionInterfaceOperationsModal.clickOnCancel();
+ compositionInterfaceOperationsTab.isLoaded();
+ return compositionPage;
+ }
+
private AddNodeToCompositionFlow addNodeToCompositionFlow(final ComponentPage componentPage) {
componentPage.isLoaded();
final ComponentData parentComponent = new ComponentData();
@@ -256,4 +316,12 @@ public class ImportVfcUiTest extends SetupCDTest {
assertThat(interfaces, not(anEmptyMap()));
}
+
+ private void checkCompositionInterfaceOperations(final CompositionInterfaceOperationsModal compositionInterfaceOperationsModal,
+ final CompositionInterfaceOperationsModal.InterfaceOperationsData interfaceOperationsData) {
+ assertEquals(interfaceOperationsData.getDescription(), compositionInterfaceOperationsModal.getDescription());
+ assertEquals(interfaceOperationsData.getImplementationName(), compositionInterfaceOperationsModal.getImplementationName());
+ assertEquals(interfaceOperationsData.getInputName(), compositionInterfaceOperationsModal.getInputName());
+ assertEquals(interfaceOperationsData.getInputValue(), compositionInterfaceOperationsModal.getInputValue());
+ }
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceCreatePage.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceCreatePage.java
index d6e023a7d3..686f63c552 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceCreatePage.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceCreatePage.java
@@ -92,7 +92,7 @@ public class ResourceCreatePage extends ComponentPage {
}
private void fillDescription(final String description) {
- setTextAreaField(By.xpath(XpathSelector.DESCRIPTION_TEXT_AREA.getXpath()), description);
+ setInputField(By.xpath(XpathSelector.DESCRIPTION_TEXT_AREA.getXpath()), description);
}
private void fillContactId(final String contactId) {
@@ -125,10 +125,6 @@ public class ResourceCreatePage extends ComponentPage {
findElement(locator).sendKeys(value);
}
- private void setTextAreaField(final By locator, final String value) {
- setInputField(locator, value);
- }
-
/**
* Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
*/
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDetailSideBarComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDetailSideBarComponent.java
index b80b28ced7..346f639405 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDetailSideBarComponent.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDetailSideBarComponent.java
@@ -78,6 +78,8 @@ public class CompositionDetailSideBarComponent extends AbstractPageObject {
return new CompositionSubstitutionFilterTab(webDriver);
case REQUIREMENTS_CAPABILITIES:
return new CompositionRequirementsCapabilitiesTab(webDriver);
+ case INTERFACE_OPERATIONS:
+ return new CompositionInterfaceOperationsTab(webDriver);
default:
throw new IllegalStateException("Not yet implemented: " + tabName);
}
@@ -99,6 +101,7 @@ public class CompositionDetailSideBarComponent extends AbstractPageObject {
INFORMATION_ARTIFACTS_TAB("detail-tab-information-artifacts", "//li[@data-tests-id='%s']"),
REQUIREMENTS_CAPABILITIES_TAB("detail-tab-requirements-capabilities", "//li[@data-tests-id='%s']"),
API_ARTIFACTS_TAB("detail-tab-api-artifacts", "//li[@data-tests-id='%s']"),
+ INTERFACE_OPERATIONS_TAB("detail-tab-interface-operations", "//li[@data-tests-id='%s']"),
SUBSTITUTION_FILTER_TAB("detail-tab-substitution-filter", "//li[@data-tests-id='%s']");
@Getter
@@ -119,6 +122,7 @@ public class CompositionDetailSideBarComponent extends AbstractPageObject {
INFORMATIONAL_ARTIFACTS(XpathSelector.INFORMATION_ARTIFACTS_TAB),
API_ARTIFACTS(XpathSelector.API_ARTIFACTS_TAB),
SUBSTITUTION_FILTER(XpathSelector.SUBSTITUTION_FILTER_TAB),
+ INTERFACE_OPERATIONS(XpathSelector.INTERFACE_OPERATIONS_TAB),
REQUIREMENTS_CAPABILITIES(XpathSelector.REQUIREMENTS_CAPABILITIES_TAB);
private final XpathSelector xpathSelector;
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java
new file mode 100644
index 0000000000..434885c4cb
--- /dev/null
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsModal.java
@@ -0,0 +1,149 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
+
+import com.aventstack.extentreports.Status;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
+import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ * Represents the Composition Interface Operations Modal.
+ */
+public class CompositionInterfaceOperationsModal extends AbstractPageObject {
+
+ public CompositionInterfaceOperationsModal(final WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ public void isLoaded() {
+ waitForElementVisibility(By.xpath(XpathSelector.TITLE_SPAN.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.INTERFACE_NAME_LABEL.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.OPERATION_NAME_LABEL.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.INPUT_NAME_SPAN.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.INPUT_VALUE_SPAN.getXPath()));
+
+ waitToBeClickable(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath()));
+ waitToBeClickable(By.xpath(XpathSelector.SAVE_BTN.getXPath()));
+ waitToBeClickable(By.xpath(XpathSelector.CANCEL_BTN.getXPath()));
+ }
+
+ public void clickOnSave() {
+ waitToBeClickable(By.xpath(XpathSelector.SAVE_BTN.getXPath())).click();
+ }
+
+ public void clickOnCancel() {
+ waitToBeClickable(By.xpath(XpathSelector.CANCEL_BTN.getXPath())).click();
+ }
+
+ public void clickOnDelete() {
+ waitToBeClickable(By.xpath(XpathSelector.DELELE_BTN.getXPath())).click();
+ }
+
+ public void updateInterfaceOperation(final InterfaceOperationsData interfaceOperationsData) {
+ fillDescription(interfaceOperationsData.getDescription());
+ fillImplementationName(interfaceOperationsData.getImplementationName());
+ fillInputName(interfaceOperationsData.getInputName());
+ fillInputValue(interfaceOperationsData.getInputValue());
+ clickOnSave();
+ }
+
+ private void fillDescription(final String description) {
+ setInputField(By.xpath(XpathSelector.INTERFACE_OPERATION_DESCRIPTION_INPUT.getXPath()), description);
+ }
+
+ private void fillImplementationName(final String implementationName) {
+ setInputField(By.xpath(XpathSelector.INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT.getXPath()), implementationName);
+ }
+
+ private void fillInputName(final String inputName) {
+ setInputField(By.xpath(XpathSelector.FIELD_INPUT_NAME_INPUT.getXPath()), inputName);
+ }
+
+ private void fillInputValue(final String inputValue) {
+ setInputField(By.xpath(XpathSelector.FIELD_INPUT_VALUE_INPUT.getXPath()), inputValue);
+ }
+
+ private void setInputField(final By locator, final String value) {
+ if (value == null) {
+ return;
+ }
+ final WebElement webElement = findElement(locator);
+ webElement.clear();
+ webElement.sendKeys(value);
+ ExtentTestActions.takeScreenshot(Status.INFO, value, value);
+ }
+
+ public void addInput() {
+ waitToBeClickable(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath())).click();
+ }
+
+ public String getDescription() {
+ return findElement(By.xpath(XpathSelector.INTERFACE_OPERATION_DESCRIPTION_INPUT.getXPath())).getAttribute("value");
+ }
+
+ public String getImplementationName() {
+ return findElement(By.xpath(XpathSelector.INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT.getXPath())).getAttribute("value");
+ }
+
+ public String getInputName() {
+ return findElement(By.xpath(XpathSelector.FIELD_INPUT_NAME_INPUT.getXPath())).getAttribute("value");
+ }
+
+ public String getInputValue() {
+ return findElement(By.xpath(XpathSelector.FIELD_INPUT_VALUE_INPUT.getXPath())).getAttribute("value");
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public static class InterfaceOperationsData {
+
+ private final String description;
+ private final String implementationName;
+ private final String inputName;
+ private final String inputValue;
+ }
+
+ @AllArgsConstructor
+ private enum XpathSelector {
+ TITLE_SPAN("//span[@class='title' and contains(text(), 'Edit Operation')]"),
+ ADD_INPUT_BTN("//a[contains(@class,'add-param-link add-btn') and contains(text(), 'Add Input')]"),
+ DELELE_BTN("//svg-icon[@name='trash-o']"),
+ SAVE_BTN("//button[@data-tests-id='Save']"),
+ CANCEL_BTN("//button[@data-tests-id='Cancel']"),
+ INTERFACE_NAME_LABEL("//label[contains(@class,'sdc-input') and contains(text(), 'Interface Name')]"),
+ OPERATION_NAME_LABEL("//label[contains(@class,'sdc-input') and contains(text(), 'Operation Name')]"),
+ INTERFACE_OPERATION_DESCRIPTION_INPUT("//input[@data-tests-id='interface-operation-description']"),
+ INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT("//input[@data-tests-id='interface-operation-implementation-name']"),
+ INPUT_NAME_SPAN("//span[contains(@class,'field-input-name') and contains(text(), 'Name')]"),
+ INPUT_VALUE_SPAN("//span[contains(@class,'field-input-value') and contains(text(), 'Value')]"),
+ FIELD_INPUT_NAME_INPUT("//input[@data-tests-id='interface-operation-input-name']"),
+ FIELD_INPUT_VALUE_INPUT("//input[@data-tests-id='interface-operation-input-value']");
+
+ @Getter
+ private final String xPath;
+
+ }
+}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java
new file mode 100644
index 0000000000..c67293939e
--- /dev/null
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionInterfaceOperationsTab.java
@@ -0,0 +1,94 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.sdc.frontend.ci.tests.pages.component.workspace;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+/**
+ * Represents the Composition Interface Operations tab.
+ */
+public class CompositionInterfaceOperationsTab extends AbstractPageObject {
+
+ private WebElement webElement;
+
+ public CompositionInterfaceOperationsTab(final WebDriver webDriver) {
+ super(webDriver);
+ }
+
+ @Override
+ public void isLoaded() {
+ waitForElementVisibility(By.xpath(XpathSelector.INTERFACE_OPERATIONS.getXPath()));
+ waitForElementVisibility(By.xpath(XpathSelector.INTERFACE_NAME_SPAN.getXPath()));
+ webElement = findElement(By.xpath(XpathSelector.OPERATION_LIST.getXPath()));
+ }
+
+ public boolean isOperationPresent(final String operationName) {
+ try {
+ final WebElement webElementInterfaceRow = webElement.findElement(By.xpath(XpathSelector.INTERFACE_ROW.getXPath()));
+ webElementInterfaceRow.findElement(By.xpath(XpathSelector.FIELD_NAME_SPAN.getXPath(operationName)));
+ } catch (final Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isDescriptionPresent() {
+ try {
+ final WebElement webElementInterfaceRow = webElement.findElement(By.xpath(XpathSelector.INTERFACE_ROW.getXPath()));
+ final WebElement rowElement = webElementInterfaceRow.findElement(By.xpath(XpathSelector.FIELD_DESCRIPTION_SPAN.getXPath()));
+ return rowElement != null && !rowElement.getText().isEmpty();
+ } catch (final Exception e) {
+ return false;
+ }
+ }
+
+ public CompositionInterfaceOperationsModal clickOnOperation(final String operationName) {
+ final WebElement webElementInterfaceRow = webElement.findElement(By.xpath(XpathSelector.INTERFACE_ROW.getXPath()));
+ webElementInterfaceRow.findElement(By.xpath(XpathSelector.FIELD_NAME_SPAN.getXPath(operationName))).click();
+ return new CompositionInterfaceOperationsModal(webDriver);
+ }
+
+ @AllArgsConstructor
+ private enum XpathSelector {
+ INTERFACE_OPERATIONS("//div[@class='interface-operations']"),
+ OPERATION_LIST("//div[@class='operation-list']"),
+ EXPAND_COLLAPSE("//div[@class='expand-collapse']"),
+ INTERFACE_ACCORDION("//div[@class='interface-accordion']"),
+ INTERFACE_ROW("//div[contains(@class,'interface-row')]"),
+ INTERFACE_NAME_SPAN("//span[@class='interface-name']"),
+ FIELD_NAME_SPAN("//span[contains(@class,'field-name') and contains(text(), '%s')]"),
+ FIELD_DESCRIPTION_SPAN("//span[contains(@class,'field-description')]");
+
+ @Getter
+ private final String xPath;
+
+ public String getXPath(final String... xpathParams) {
+ return String.format(xPath, xpathParams);
+ }
+
+ }
+}
diff --git a/integration-tests/src/test/resources/Files/VFCs/org.openecomp.resource.VFC-child.yml b/integration-tests/src/test/resources/Files/VFCs/org.openecomp.resource.VFC-child.yml
index 2c00cbd7e9..e86349a566 100644
--- a/integration-tests/src/test/resources/Files/VFCs/org.openecomp.resource.VFC-child.yml
+++ b/integration-tests/src/test/resources/Files/VFCs/org.openecomp.resource.VFC-child.yml
@@ -10,15 +10,27 @@ node_types:
test_1:
type: string
default: 'MydefaultValue'
-
test_2:
type: integer
default: 266305
-
test_3:
type: string
default: 'TestValue3'
-
test_4:
type: boolean
- default: true \ No newline at end of file
+ default: true
+ interfaces:
+ Standard:
+ type: tosca.interfaces.node.lifecycle.Standard
+ inputs:
+ url_path:
+ type: string
+ operations:
+ create:
+ description: 'My create Desc'
+ implementation: path/to/my/implementation.sh
+ inputs:
+ first:
+ type: string
+ default: '1234'
+ description: My inputs Desc