Fix instance declared inputs mapped to substitution mapping
[sdc.git] / integration-tests / src / test / java / org / onap / sdc / frontend / ci / tests / execute / sanity / ServiceTemplateDesignUiTests.java
index 967a97b..7409588 100644 (file)
@@ -23,11 +23,13 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.anEmptyMap;
 import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.emptyString;
+import static org.hamcrest.Matchers.equalToIgnoringCase;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
@@ -47,25 +49,40 @@ import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
 import org.onap.sdc.backend.ci.tests.datatypes.enums.ResourceCategoryEnum;
 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
+import org.onap.sdc.frontend.ci.tests.datatypes.DirectiveType;
+import org.onap.sdc.frontend.ci.tests.datatypes.LogicalOperator;
 import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
+import org.onap.sdc.frontend.ci.tests.datatypes.ServiceDependencyProperty;
 import org.onap.sdc.frontend.ci.tests.datatypes.composition.RelationshipInformation;
 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.AddComponentInputFlow;
 import org.onap.sdc.frontend.ci.tests.flow.AddComponentPropertyFlow;
 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
+import org.onap.sdc.frontend.ci.tests.flow.CreateDirectiveNodeFilterFlow;
+import org.onap.sdc.frontend.ci.tests.flow.CreateSubstitutionFilterFlow;
 import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
 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.DownloadToscaTemplateFlow;
 import org.onap.sdc.frontend.ci.tests.flow.EditComponentPropertiesFlow;
 import org.onap.sdc.frontend.ci.tests.flow.composition.CreateRelationshipFlow;
 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
 import org.onap.sdc.frontend.ci.tests.pages.AttributesOutputsPage;
 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
-import org.onap.sdc.frontend.ci.tests.pages.TopNavComponent;
+import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesAssignmentPage;
+import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesPage;
+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.CompositionInterfaceOperationsTab;
 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.RelationshipWizardInterfaceOperation.InterfaceOperationsData;
 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;
@@ -82,7 +99,6 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTemplateDesignUiTests.class);
 
     private WebDriver webDriver;
-    private TopNavComponent topNavComponent;
     private HomePage homePage;
     private List<ResourceCreateData> vfcs = new ArrayList<>();
     private ResourceCreateData vfResourceCreateData;
@@ -91,11 +107,18 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
     private AddNodeToCompositionFlow addNodeToCompositionFlow;
     private ComponentPage componentPage;
     private Map<String, String> propertiesToBeAddedMap;
+    private ResourceCreatePage resourceCreatePage;
+    private Map<String, String> inputsToBeAddedMap;
+    private final List<ServiceDependencyProperty> substitutionFilterProperties = new ArrayList<>();
+    private final String interfaceName = "Standard";
+    private final String interfaceOperationName = "create";
+    private final String implementationName = "IntegrationTest";
+    private final String inputName = "InputName1";
+    private final String inputValue = "InputValue1";
 
     @BeforeMethod
     public void init() {
         webDriver = DriverFactory.getDriver();
-        topNavComponent = new TopNavComponent(webDriver);
         homePage = new HomePage(webDriver);
     }
 
@@ -115,15 +138,11 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
     }
 
     @Test(dependsOnMethods = "importAndCertifyVfc")
-    public void createBaseService() throws UnzipException {
+    public void createBaseService() {
         final CreateVfFlow createVfFlow = createVF();
-        addNodeToCompositionFlow = addNodeToCompositionAndCreateRelationship(createVfFlow);
-        final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
-            .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
-        compositionPage.isLoaded();
-        componentPage = compositionPage.goToGeneral();
-        componentPage.isLoaded();
-        downloadAndVerifyCsarPackageAfterBaseServiceCreation(componentPage);
+        resourceCreatePage = createVfFlow.getLandedPage()
+            .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ResourceCreatePage"));
+        resourceCreatePage.isLoaded();
     }
 
     @Test(dependsOnMethods = "createBaseService")
@@ -136,6 +155,42 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
     }
 
     @Test(dependsOnMethods = "createBaseService")
+    public void addRelationshipTemplate() throws UnzipException {
+        homePage.isLoaded();
+        resourceCreatePage = (ResourceCreatePage) homePage.clickOnComponent(vfResourceCreateData.getName());
+        resourceCreatePage.isLoaded();
+        addNodeToCompositionFlow = addNodeToCompositionAndCreateRelationship();
+        final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
+            .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
+        compositionPage.isLoaded();
+        componentPage = compositionPage.goToGeneral();
+        componentPage.isLoaded();
+        downloadAndVerifyCsarPackage(componentPage);
+    }
+
+    @Test(dependsOnMethods = "addRelationshipTemplate")
+    public void createMetadataForServiceProperty() throws Exception {
+        homePage.isLoaded();
+        componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
+        componentPage.isLoaded();
+        final ResourcePropertiesAssignmentPage propertiesAssignmentPage = componentPage.goToPropertiesAssignment();
+
+        propertiesAssignmentPage.isLoaded();
+        propertiesAssignmentPage.selectInputTab();
+        final var propertyName = propertiesAssignmentPage.getInputPropertyNames().get(0);
+        final var key = "Key";
+        final var value = "Test";
+        propertiesAssignmentPage.setInputPropertyMetadata(propertyName, key, value);
+
+        final var topologyTemplate = getMapEntry(downloadToscaTemplate(), "topology_template");
+        final var inputs = getMapEntry(topologyTemplate, "inputs");
+        final var serviceProperty = getMapEntry(inputs, propertyName);
+        final var servicePropertyMetadata = getMapEntry(serviceProperty, "metadata");
+        assertNotNull(servicePropertyMetadata, String.format("Metadata not found for property %s", propertyName));
+        assertEquals(servicePropertyMetadata.get(key), value, "Created service property metadata has invalid value");
+    }
+
+    @Test(dependsOnMethods = "addRelationshipTemplate")
     public void addOutputsToVF_test() throws UnzipException, IOException {
         homePage.isLoaded();
         final ComponentPage resourceCreatePage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
@@ -177,13 +232,106 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         attributesOutputsPage.clickOnOutputsTab();
         ExtentTestActions.addScreenshot(Status.INFO, "OutputsTab", "The Output's list : ");
 
-        attributesOutputsPage.certifyComponent();
-        attributesOutputsPage.isLoaded();
-
         Map<String, Object> yamlObject = downloadToscaArtifact(attributesOutputsPage);
         checkMetadata(yamlObject, vfResourceCreateData);
         checkTopologyTemplate(yamlObject);
+    }
+
+    @Test(dependsOnMethods = "addRelationshipTemplate")
+    public void updateInterfaceOperation() throws Exception {
+        homePage.isLoaded();
+        componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
+        componentPage.isLoaded();
+        final CompositionPage compositionPage = componentPage.goToComposition();
+        compositionPage.isLoaded();
+        ExtentTestActions.addScreenshot(Status.INFO, "select-VFC-node", "Selecting Node on composition");
+        compositionPage.selectNode(vfcs.get(1).getName());
+        final List<InputData> inputList = List.of(
+            new InputData("My_IT_InputName", "string", "My_IT_InputValue")
+        );
+        final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData =
+            new InterfaceDefinitionOperationsModal.InterfaceOperationsData("IT for updating an Interface Operation",
+                "MyIntegrationTestImplementationName", inputList);
+        updateInterfaceOperation(compositionPage, interfaceOperationsData);
+        componentPage = compositionPage.goToGeneral();
+        componentPage.isLoaded();
+        verifyToscaTemplateHasUpdatedInterfaceOperation(downloadToscaTemplate(), interfaceOperationsData);
+    }
+
+    @Test(dependsOnMethods = "addComponentProperty")
+    public void createSubstitutionFilter() throws Exception {
+        componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
+        componentPage.isLoaded();
+        loadSubstitutionFilterProperties();
+        final CompositionPage compositionPage = componentPage.goToComposition();
+        compositionPage.isLoaded();
+        substitutionFilterProperties.forEach(substitutionFilterProperty -> {
+            final CreateSubstitutionFilterFlow createSubstitutionFilterFlow = new CreateSubstitutionFilterFlow(webDriver, substitutionFilterProperty);
+            createSubstitutionFilterFlow.run(compositionPage);
+        });
+        componentPage = compositionPage.goToGeneral();
+        componentPage.isLoaded();
+        verifyToscaTemplateHasSubstitutionFilter(downloadToscaTemplate());
+    }
+
+    @Test(dependsOnMethods = "createBaseService")
+    public void createDirectiveNodeFilterTest() throws Exception {
+        final ResourceCreateData vfcResourceCreateData = vfcs.get(1);
+        final String vfcNameInComposition = vfcResourceCreateData.getName().concat(" 0");
+        final String value = "Test";
+        final LogicalOperator operator = LogicalOperator.EQUALS;
+        homePage.isLoaded();
+        componentPage = (ComponentPage) homePage.clickOnComponent(vfcResourceCreateData.getName());
+
+        componentPage.isLoaded();
+        final ResourcePropertiesPage vfcPropertiesPage = componentPage.goToProperties();
+        vfcPropertiesPage.isLoaded();
+        final Map<String, String> propertyNamesAndTypes = vfcPropertiesPage.getPropertyNamesAndTypes();
+        final List<String> propertyNames = propertyNamesAndTypes.keySet().stream().collect(Collectors.toList());
+        final ServiceDependencyProperty serviceDependencyProperty =
+            new ServiceDependencyProperty(propertyNames.get(0), propertyNamesAndTypes.get(propertyNames.get(0)), value, operator);
+
+        homePage.getTopNavComponent().clickOnHome();
+        homePage.isLoaded();
+        homePage.clickOnComponent(vfResourceCreateData.getName());
 
+        componentPage.isLoaded();
+        final CompositionPage compositionPage = componentPage.goToComposition();
+        compositionPage.isLoaded();
+        compositionPage.selectNode(vfcNameInComposition);
+
+        final CreateDirectiveNodeFilterFlow createDirectiveNodeFilterFlow =
+            new CreateDirectiveNodeFilterFlow(webDriver, 2, serviceDependencyProperty);
+        createDirectiveNodeFilterFlow.run(componentPage);
+
+        verifyAvailableDirectiveTypes(createDirectiveNodeFilterFlow.getDirectiveOptions());
+
+        verifyAvailablePropertyNames(propertyNames, createDirectiveNodeFilterFlow.getPropertyOptions());
+
+        componentPage = compositionPage.goToGeneral();
+        componentPage.isLoaded();
+        final Map<?, ?> yaml = downloadToscaTemplate();
+        verifyToscaTemplateHasDirectiveNodeFilter(yaml, serviceDependencyProperty, vfcNameInComposition);
+    }
+
+    @Test(dependsOnMethods = "addComponentProperty")
+    public void declareInputFromProperties() throws Exception {
+        componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
+        componentPage.isLoaded();
+
+        ResourcePropertiesAssignmentPage propertiesAssignmentPage = componentPage.goToPropertiesAssignment();
+        propertiesAssignmentPage.isLoaded();
+
+        declareInputToBaseService(propertiesAssignmentPage, "property1");
+        declareInputToInstanceProperties(propertiesAssignmentPage, "resourceSubtype");
+        verifyToscaTemplateHasDeclareInput(downloadToscaTemplate());
+    }
+
+    @Test(dependsOnMethods = "createBaseService")
+    public void addComponentInputs() throws Exception {
+        inputsToBeAddedMap = loadInputsToAdd();
+        addInput(inputsToBeAddedMap);
+        verifyToscaTemplateAddInput(downloadToscaTemplate());
     }
 
     private void checkMetadata(final Map<String, Object> map, final ResourceCreateData createdData) {
@@ -219,7 +367,102 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         final Map<String, Object> attributes = getMapEntry(substitutionMappings, "attributes");
         assertThat(attributes, not(anEmptyMap()));
         assertEquals(2, attributes.keySet().stream().filter(s -> (s.contains("_attr_1") || s.contains("_attr_3")) && !s.contains("_attr_2")).count());
+    }
 
+    /**
+     * Updates an Interface operation from a selected Node (VFC)
+     *
+     * @param compositionPage         the composition page
+     * @param interfaceOperationsData the interface definition
+     * @throws IOException
+     */
+    private void updateInterfaceOperation(final CompositionPage compositionPage,
+                                          final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData)
+        throws IOException {
+        final CompositionDetailSideBarComponent detailSideBar = compositionPage.getDetailSideBar();
+        detailSideBar.isLoaded();
+        final CompositionInterfaceOperationsTab compositionInterfaceOperationsTab =
+            (CompositionInterfaceOperationsTab) detailSideBar.selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
+        compositionInterfaceOperationsTab.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab",
+            "Composition Interface Operations Tab loaded");
+        assertTrue(compositionInterfaceOperationsTab.isOperationPresent(interfaceOperationName));
+        final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab
+            .clickOnOperation(interfaceOperationName);
+        compositionInterfaceOperationsModal.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "update-interface-operation-modal", "Loading Interface Operations Modal");
+        compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData);
+        compositionInterfaceOperationsTab.isLoaded();
+        ExtentTestActions.addScreenshot(Status.INFO, "updated-interface-operation",
+            "The Interface operation from the selected Node was successfully updated");
+        // Gives time for UI to load the Updated Interface Operation
+        final CompositionInformationTab compositionInformationTab =
+            (CompositionInformationTab) detailSideBar.selectTab(CompositionDetailTabName.INFORMATION);
+        compositionInformationTab.isLoaded();
+        validateUpdatedInterfaceOperation(detailSideBar, interfaceOperationsData);
+    }
+
+    /**
+     * Validates if the Updated Interface Operation has the expected values
+     *
+     * @param detailSideBar           The composition Page
+     * @param interfaceOperationsData The Updated Interface Definition
+     */
+    private void validateUpdatedInterfaceOperation(final CompositionDetailSideBarComponent detailSideBar,
+                                                   final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
+        final CompositionInterfaceOperationsTab compositionInterfaceOperationsTab = (CompositionInterfaceOperationsTab) detailSideBar
+            .selectTab(CompositionDetailTabName.INTERFACE_OPERATIONS);
+        compositionInterfaceOperationsTab.isLoaded();
+        assertTrue(compositionInterfaceOperationsTab.isOperationPresent(interfaceOperationName));
+        assertTrue(compositionInterfaceOperationsTab.isDescriptionPresent());
+        final InterfaceDefinitionOperationsModal compositionInterfaceOperationsModal = compositionInterfaceOperationsTab
+            .clickOnOperation(interfaceOperationName);
+        compositionInterfaceOperationsModal.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "validate-updated-interface-operation",
+            "Loading the Interface Operations Modal for validating");
+        assertThat("The Interface Operation Description should match", interfaceOperationsData.getDescription(),
+            equalToIgnoringCase(compositionInterfaceOperationsModal.getDescription()));
+        assertThat("The Interface Operation Implementation Name should match", interfaceOperationsData.getImplementationName(),
+            equalToIgnoringCase(compositionInterfaceOperationsModal.getImplementationName()));
+//        assertThat("The Interface Operation Input key should match", interfaceOperationsData.getInputName(),
+//            equalToIgnoringCase(compositionInterfaceOperationsModal.getInputName()));
+//        assertThat("The Interface Operation Input Value should match", interfaceOperationsData.getInputValue(),
+//            equalToIgnoringCase(compositionInterfaceOperationsModal.getInputValue()));
+        compositionInterfaceOperationsModal.clickOnCancel();
+    }
+
+    private void verifyToscaTemplateHasUpdatedInterfaceOperation(final Map<?, ?> toscaTemplateYaml,
+                                                                 final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) {
+
+        assertNotNull(toscaTemplateYaml, "No contents in TOSCA Template");
+        final Map<String, Object> topologyTemplateTosca = getMapEntry((Map<String, Object>) toscaTemplateYaml, "topology_template");
+        assertThat("Should contain a topology_template entry", toscaTemplateYaml, is(notNullValue()));
+        final Map<String, Object> nodeTemplatesTosca = getMapEntry(topologyTemplateTosca, "node_templates");
+        assertThat("Should contain a node_templates entry", nodeTemplatesTosca, is(notNullValue()));
+        final Optional<Entry<String, Object>> nodeWithInterfaceOperation = nodeTemplatesTosca.entrySet().stream()
+            .filter(s -> s.getKey().startsWith(vfcs.get(1).getName())).findFirst();
+        assertThat("Should contain a node (VFC)", nodeWithInterfaceOperation.isPresent(), is(true));
+        final Map<String, Object> interfacesEntry = (Map<String, Object>) nodeWithInterfaceOperation.get().getValue();
+        assertThat("The Interfaces Entry should not be empty", interfacesEntry, not(anEmptyMap()));
+        final Map<String, Object> interfaceOperations = (Map<String, Object>) interfacesEntry.get("interfaces");
+        assertThat("The Interface Entry should have operations", interfaceOperations, not(anEmptyMap()));
+        final Map<String, Object> interfaceNameMap = (Map<String, Object>) interfaceOperations.get(interfaceName);
+        assertThat(String.format("'%s' should contain a Interface Name entry '%s'", interfaceNameMap, interfaceName),
+            interfaceOperations, not(anEmptyMap()));
+        final Map<String, Object> updatedInterfaceOperation = (Map<String, Object>) interfaceNameMap.get(interfaceOperationName);
+        assertThat(String.format("'%s' should contain a Interface Operation Name '%s'", updatedInterfaceOperation, interfaceOperationName),
+            updatedInterfaceOperation, not(anEmptyMap()));
+        assertThat("The Interface Operation Description should match",
+            updatedInterfaceOperation.get("description").equals(interfaceOperationsData.getDescription()));
+        assertThat("The Interface Operation Implementation Name should match",
+            updatedInterfaceOperation.get("implementation").equals(interfaceOperationsData.getImplementationName()));
+        final Map<String, Object> updatedInterfaceOperationInput = (Map<String, Object>) updatedInterfaceOperation.get("inputs");
+        interfaceOperationsData.getInputList().forEach(inputData -> {
+            assertThat("The Interface Operation Input Key should match",
+                updatedInterfaceOperationInput.containsKey(inputData.getName()));
+            assertThat("The Interface Operation Input Value should match",
+                updatedInterfaceOperationInput.containsValue(inputData.getValue()));
+        });
     }
 
     private Map<String, Object> downloadToscaArtifact(final ComponentPage resourceCreatePage) throws UnzipException {
@@ -240,6 +483,23 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         return loadYamlObject(filesFromZip.get(resourceEntryOpt.get()));
     }
 
+    private void declareInputToBaseService(ResourcePropertiesAssignmentPage propertiesAssignmentPage, String propertyName) {
+        propertiesAssignmentPage.selectProperty(propertyName);
+        propertiesAssignmentPage.clickOnDeclareInput();
+        propertiesAssignmentPage.clickInputTab(propertyName);
+        propertiesAssignmentPage.isInputPresent(vfResourceCreateData.getName() + "_" + propertyName);
+    }
+
+    private void declareInputToInstanceProperties(ResourcePropertiesAssignmentPage propertiesAssignmentPage, String propertyName) {
+        propertiesAssignmentPage.selectPropertiesTab();
+        propertiesAssignmentPage.loadCompositionTab();
+        propertiesAssignmentPage.loadComponentInstanceProperties(vfcs.get(0).getName().concat(" 0"));
+        propertiesAssignmentPage.selectProperty(propertyName);
+        propertiesAssignmentPage.clickOnDeclareInput();
+        propertiesAssignmentPage.clickInputTab(propertyName);
+        propertiesAssignmentPage.isInputPresent(vfResourceCreateData.getName() + "_" + vfcs.get(0).getName());
+    }
+
     private CreateVfFlow createVF() {
         final ResourceCreateData vfCreateData = createVfFormData();
         final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
@@ -281,10 +541,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         return vfcCreateData;
     }
 
-    private AddNodeToCompositionFlow addNodeToCompositionAndCreateRelationship(final CreateVfFlow createVfFlow) {
-        final ResourceCreatePage resourceCreatePage = createVfFlow.getLandedPage()
-            .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ResourceCreatePage"));
-        resourceCreatePage.isLoaded();
+    private AddNodeToCompositionFlow addNodeToCompositionAndCreateRelationship() {
         assertThat(vfcs, hasSize(2));
         final ComponentData parentComponent = new ComponentData();
         parentComponent.setName(vfResourceCreateData.getName());
@@ -296,7 +553,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         networkFunction.setName(vfcs.get(0).getName());
         networkFunction.setVersion("1.0");
         networkFunction.setComponentType(ComponentType.RESOURCE);
-        CompositionPage compositionPage = resourceCreatePage.goToComposition();
+        final CompositionPage compositionPage = resourceCreatePage.goToComposition();
         compositionPage.isLoaded();
         AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkFunction, compositionPage);
         networkFunctionInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
@@ -332,17 +589,19 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     /**
      * Creates a DependsOn relationship between the imported VFCs
-     * @param compositionPage Composition Page
+     *
+     * @param compositionPage           Composition Page
      * @param fromComponentInstanceName VFC - Network Function
-     * @param fromCapability Node Capability
-     * @param toComponentInstanceName  VFC - Network Service
-     * @param toRequirement Node Requirement
+     * @param fromCapability            Node Capability
+     * @param toComponentInstanceName   VFC - Network Service
+     * @param toRequirement             Node Requirement
      */
     private void createRelationship(final CompositionPage compositionPage, final String fromComponentInstanceName,
                                     final String fromCapability, final String toComponentInstanceName, final String toRequirement) {
         final RelationshipInformation relationshipInformation =
             new RelationshipInformation(fromComponentInstanceName, fromCapability, toComponentInstanceName, toRequirement);
-        CreateRelationshipFlow createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInformation);
+        final CreateRelationshipFlow createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInformation,
+            new InterfaceOperationsData(interfaceName, interfaceOperationName, implementationName, inputName, inputValue));
         createRelationshipFlow.run(compositionPage).orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a CompositionPage instance"));
         ExtentTestActions.takeScreenshot(Status.INFO, "relationship",
             String.format("Relationship from networkFunctionInstance '%s' to networkServiceInstanceResource '%s' was created",
@@ -351,6 +610,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     /**
      * Adds a property to the base service
+     *
      * @param propertyMap map of properties to be added
      */
     private void addProperty(final Map<String, String> propertyMap) {
@@ -360,8 +620,21 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         addComponentPropertyFlow.run(componentPage.goToPropertiesAssignment());
     }
 
+    /**
+     * Adds a input to the base service
+     *
+     * @param inputMap map of inputs to be added
+     */
+    private void addInput(final Map<String, String> inputMap) {
+        componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
+        componentPage.isLoaded();
+        final AddComponentInputFlow addComponentInputFlow = new AddComponentInputFlow(webDriver, inputMap);
+        addComponentInputFlow.run(componentPage.goToPropertiesAssignment());
+    }
+
     /**
      * Edits a property to add a value
+     *
      * @param propertyMap map of properties to be edited
      */
     private ComponentPage addValueToProperty(final Map<String, Object> propertyMap) {
@@ -371,17 +644,19 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     /**
      * Downloads and verifies the generated tosca templates.
+     *
      * @param componentPage the component page
      * @throws UnzipException
      */
-    private void downloadAndVerifyCsarPackageAfterBaseServiceCreation(final ComponentPage componentPage) throws UnzipException {
+    private void downloadAndVerifyCsarPackage(final ComponentPage componentPage) throws UnzipException {
         checkCsarPackage(downloadCsarPackage(componentPage));
     }
 
     /**
      * Downloads and verifies if the generated Tosca template contains the expected properties.
-     * @throws UnzipException
+     *
      * @param componentPage
+     * @throws UnzipException
      */
     private void downloadAndVerifyCsarPackageAfterAddProperty(final ComponentPage componentPage) throws UnzipException {
         verifyPropertiesOnGeneratedTemplate(downloadCsarPackage(componentPage));
@@ -397,6 +672,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     /**
      * Downloads the generated CSAR package.
+     *
      * @param componentPage the component page
      * @return the Downloaded Tosca CSAR file
      */
@@ -409,6 +685,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     /**
      * Verifies if the generated Tosca template contains the expected properties.
+     *
      * @param downloadedCsarName the downloaded csar file name
      * @throws UnzipException
      */
@@ -478,6 +755,28 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
             .anyMatch(vfc -> s.startsWith(vfc.getName()))).collect(Collectors.toList());
         assertThat(String.format("'%s' should contain the node type definitions for the added VFCs '%s'", nodeTemplatesTosca, vfcs),
             nodeTemplateFound, hasSize(vfcs.size()));
+        verifyRelationshipTemplate(topologyTemplateTosca, generatedTemplateFile);
+    }
+
+    private void verifyRelationshipTemplate(final Map<String, Object> topologyTemplateToscaMap, final String generatedTemplateFile) {
+        final Map<String, Object> relationshipTemplateMap = getMapEntry(topologyTemplateToscaMap, "relationship_templates");
+        assertThat(String.format("'%s' should contain a topology_template entry", generatedTemplateFile), relationshipTemplateMap,
+            is(notNullValue()));
+        final String result = Arrays.asList(relationshipTemplateMap.values()).toString();
+        assertThat(String.format("'%s' should contain a DependsOn relationship", relationshipTemplateMap),
+            result.contains("tosca.relationships.DependsOn"), is(true));
+        assertThat(String.format("'%s' should contain interfaces entry", relationshipTemplateMap), result.contains("interfaces"), is(true));
+        assertThat(String.format("'%s' should contain a Interface Name entry '%s'", relationshipTemplateMap, interfaceName),
+            result.contains(interfaceName), is(true));
+        assertThat(String.format("'%s' should contain a Interface Operation Name '%s'", relationshipTemplateMap, interfaceOperationName),
+            result.contains(interfaceOperationName), is(true));
+        assertThat(String.format("'%s' should contain Implementation Name '%s'", relationshipTemplateMap, implementationName),
+            result.contains(implementationName), is(true));
+        assertThat(String.format("'%s' should contain inputs entry", relationshipTemplateMap), result.contains("inputs"), is(true));
+        assertThat(String.format("'%s' should contain Input Name '%s'", relationshipTemplateMap, inputName), result.contains(inputName),
+            is(true));
+        assertThat(String.format("'%s' should contain Input Value '%s'", relationshipTemplateMap, inputValue), result.contains(inputValue),
+            is(true));
     }
 
     private void verifyNodesRelationship(final Map<String, byte[]> expectedFilesFromZipMap, final String virtualFunctionName,
@@ -507,7 +806,40 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         return expectedDefinitionFolderFileList;
     }
 
-    private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
+    private void verifyToscaTemplateHasDeclareInput(Map<?, ?> yaml) {
+        assertNotNull(yaml, "No contents in TOSCA Template");
+        final Map<String, Object> toscaYaml = (Map<String, Object>) yaml;
+        final Map<String, Object> topologyTemplateTosca = getMapEntry(toscaYaml, "topology_template");
+        assertThat(String.format("'%s' should contain a topology_template entry", toscaYaml), topologyTemplateTosca,
+            notNullValue());
+        final Map<String, Object> inputsTosca = getMapEntry(topologyTemplateTosca, "inputs");
+        assertThat(String.format("'%s' should contain a inputs entry", toscaYaml), inputsTosca, notNullValue());
+        assertEquals(2, inputsTosca.keySet().stream()
+            .filter(s -> (s.contains("resourceSubtype") || s.contains("property1"))).count());
+        final Map<String, Object> substitutionMapping = getMapEntry(topologyTemplateTosca, "substitution_mappings");
+        assertThat(String.format("'%s' should contain a substitution_mappings entry", toscaYaml), substitutionMapping,
+            notNullValue());
+        final Map<String, Object> substitutionMappingProperties = getMapEntry(substitutionMapping, "properties");
+        assertThat(String.format("'%s' should contain a properties entry", toscaYaml), substitutionMappingProperties,
+            notNullValue());
+        assertEquals(1, substitutionMappingProperties.keySet().stream()
+            .filter(s -> (s.contains("property1"))).count());
+    }
+
+    private void verifyToscaTemplateAddInput(Map<?, ?> yaml) {
+        final Map<String, String> inputMap = loadInputsToAdd();
+        assertNotNull(yaml, "No contents in TOSCA Template");
+        final Map<String, Object> toscaYaml = (Map<String, Object>) yaml;
+        final Map<String, Object> topologyTemplateTosca = getMapEntry(toscaYaml, "topology_template");
+        assertThat(String.format("'%s' should contain a topology_template entry", toscaYaml), topologyTemplateTosca,
+            notNullValue());
+        final Map<String, Object> inputsTosca = getMapEntry(topologyTemplateTosca, "inputs");
+        assertThat(String.format("'%s' should contain a inputs entry", toscaYaml), inputsTosca, notNullValue());
+        assertEquals(3, inputsTosca.keySet().stream()
+            .filter(s -> inputMap.containsKey(s)).count());
+    }
+
+    private Map<String, Object> getMapEntry(final Map<?, ?> yamlObj, final String entryName) {
         try {
             return (Map<String, Object>) yamlObj.get(entryName);
         } catch (final Exception e) {
@@ -544,7 +876,128 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         stringMap.put("PropMapKey2", "PropMapValue2");
         stringMap.put("PropMapKey3", "PropMapValue3");
         propertyMap.put("property5", stringMap);
-        propertyMap.put("property6", 500);
+        propertyMap.put("property6", "500GB");
         return propertyMap;
     }
+
+    private Map<String, String> loadInputsToAdd() {
+        final Map<String, String> inputMap = new HashMap<>();
+        inputMap.put("input1", "string");
+        inputMap.put("input2", "integer");
+        inputMap.put("input3", "boolean");
+        return inputMap;
+    }
+
+    private void loadSubstitutionFilterProperties() {
+        final ResourcePropertiesAssignmentPage propertiesPage = componentPage.goToPropertiesAssignment();
+        propertiesPage.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "propertiesAssigment",
+            String.format("The %s Properties Assignment Page is loaded", vfResourceCreateData.getName()));
+        Map<String, String> propertyNamesAndTypes = propertiesPage.getPropertyNamesAndTypes();
+        assertThat(String.format("The Component '%s' should have properties", vfResourceCreateData.getName()), propertyNamesAndTypes,
+            not(anEmptyMap()));
+        propertyNamesAndTypes.forEach((name, type)
+            -> substitutionFilterProperties.add(new ServiceDependencyProperty(name, type, getPropertyValueByType(type), LogicalOperator.EQUALS)));
+    }
+
+    private String getPropertyValueByType(final String type) {
+        switch (type) {
+            case "string":
+                return "IntegrationTest";
+            case "integer":
+                return "202";
+            case "size":
+                return "500";
+            case "boolean":
+                return "TRUE";
+            case "list":
+                return "[\"value1\", \"value2\"]";
+            case "map":
+                return "{\"MyKey\": \"MyValue\"}";
+            default:
+                throw new UnsupportedOperationException("Not yet implemented for " + type);
+        }
+    }
+
+    /**
+     * Downloads Tosca Template file
+     *
+     * @return the tosca template yaml file
+     * @throws Exception
+     */
+    private Map<?, ?> downloadToscaTemplate() throws Exception {
+        final DownloadToscaTemplateFlow downloadToscaTemplateFlow = new DownloadToscaTemplateFlow(webDriver);
+        final ToscaArtifactsPage toscaArtifactsPage = (ToscaArtifactsPage) downloadToscaTemplateFlow.run(componentPage).get();
+        return FileHandling.parseYamlFile(getConfig().getDownloadAutomationFolder()
+            .concat(java.io.File.separator).concat(toscaArtifactsPage.getDownloadedArtifactList().get(0)));
+    }
+
+    private void verifyToscaTemplateHasSubstitutionFilter(final Map<?, ?> yaml) {
+        assertNotNull(yaml, "No contents in TOSCA Template");
+        final List<?> substitutionFilters = (List<?>) getSubstitutionFilterFromYaml(yaml).get("properties");
+        substitutionFilterProperties.forEach(substitutionFilterProperty -> {
+            final Map<?, ?> substitutionFilterMap = (Map<?, ?>) substitutionFilters.stream()
+                .filter(subFilter -> ((Map<?, ?>) subFilter).containsKey(substitutionFilterProperty.getName())).findAny().get();
+            assertThat("Added substitution filter not found in TOSCA Template",
+                substitutionFilterMap.containsKey(substitutionFilterProperty.getName()));
+            final Map<?, ?> substitutionFilterValue = (Map<?, ?>) ((List<?>) substitutionFilterMap.get(substitutionFilterProperty.getName())).get(0);
+            assertThat("Substitution Filter Value should not be empty", substitutionFilterMap, not(anEmptyMap()));
+            final String expectedSubstitutionPropertyValue = substitutionFilterProperty.getValue().replaceAll("[\"{}]", "");
+            final String actualSubstitutionPropertyValue = substitutionFilterValue.values().stream().findFirst().get() instanceof Map
+                ? substitutionFilterValue.values().stream().findFirst().get().toString().replace("=", ": ")
+                .replaceAll("\\{(.*?)\\}", "$1").trim()
+                : substitutionFilterValue.values().stream().findFirst().get().toString();
+            assertThat("Invalid value for added substitution filters found in TOSCA Template",
+                expectedSubstitutionPropertyValue.equalsIgnoreCase(actualSubstitutionPropertyValue));
+            assertThat("Invalid logical operator for added substitution filters found in TOSCA Template",
+                substitutionFilterValue.containsKey(substitutionFilterProperty.getLogicalOperator().getName()));
+        });
+    }
+
+    private Map<?, ?> getSubstitutionFilterFromYaml(final Map<?, ?> yaml) {
+        final Map<?, ?> topology = (Map<?, ?>) yaml.get("topology_template");
+        final Map<?, ?> substitutionMappings = (Map<?, ?>) topology.get("substitution_mappings");
+        return (Map<?, ?>) substitutionMappings.get("substitution_filter");
+    }
+
+    private void verifyAvailableDirectiveTypes(final List<String> availableDirectiveTypes) {
+        assertNotNull(availableDirectiveTypes, "Expected list of available Directive Types, but recieved null");
+        Arrays.asList(DirectiveType.values()).forEach(directiveType -> {
+            assertTrue(availableDirectiveTypes.contains(directiveType.getName())
+                , String.format("Expected directive %s to be availabe in UI options %s"
+                    , directiveType.getName(), availableDirectiveTypes.toString()));
+        });
+        ExtentTestActions.log(Status.PASS, "All expected directive types are available for selection");
+    }
+
+    private void verifyAvailablePropertyNames(List<String> propertyNames, List<String> propertyNameOptions) {
+        assertEquals(propertyNameOptions.size(), propertyNames.size(), "Mismatch in the number of properties available for selection");
+        propertyNames.forEach(name -> {
+            assertNotEquals(false, propertyNameOptions.remove(name)
+                , String.format("Expected property %s not found in UI Select element", name));
+        });
+        ExtentTestActions.log(Status.PASS, "All expected properties are available for selection");
+    }
+
+    private void verifyToscaTemplateHasDirectiveNodeFilter(final Map<?, ?> yaml, ServiceDependencyProperty nodeFilterProperty,
+                                                           String nodeTemplateName) {
+        assertNotNull(yaml, "Tosca Template Yaml is not expected to be empty");
+        final List<?> nodeFilters = (List<?>) getDirectiveNodeFilterFromYaml(yaml, nodeTemplateName).get("properties");
+        final Map<?, ?> nodeFilter = (Map<?, ?>) nodeFilters.stream()
+            .filter(yamlNodeFilter -> ((Map<?, ?>) yamlNodeFilter).containsKey(nodeFilterProperty.getName())).findAny().get();
+        assertNotNull(nodeFilter, "Added directive node filter not found in TOSCA Template");
+
+        final Map<?, ?> nodeFilterValue = (Map<?, ?>) ((List<?>) nodeFilter.get(nodeFilterProperty.getName())).get(0);
+        assertTrue(nodeFilterValue.containsValue(nodeFilterProperty.getValue())
+            , "Invalid value for added directive node filter found in TOSCA Template");
+        assertTrue(nodeFilterValue.containsKey(nodeFilterProperty.getLogicalOperator().getName())
+            , "Invalid logical operator for added directive node filter found in TOSCA Template");
+    }
+
+    private Map<?, ?> getDirectiveNodeFilterFromYaml(final Map<?, ?> yaml, String nodeTemplateName) {
+        final Map<?, ?> topology = (Map<?, ?>) yaml.get("topology_template");
+        final Map<?, ?> nodeTemplates = (Map<?, ?>) topology.get("node_templates");
+        final Map<?, ?> resourceNode = (Map<?, ?>) nodeTemplates.get(nodeTemplateName);
+        return (Map<?, ?>) resourceNode.get("node_filter");
+    }
 }