Add integration test for adding directive node filters to a base service 45/121145/2
authordavsad <david.sadlier@est.tech>
Thu, 29 Apr 2021 08:58:42 +0000 (09:58 +0100)
committerDavid Sadlier <david.sadlier@est.tech>
Fri, 7 May 2021 00:04:08 +0000 (00:04 +0000)
Issue-ID: SDC-3575

Signed-off-by: davsad <david.sadlier@est.tech>
Change-Id: Idc4dfaad59239f1fb46d04246564554058b4095a

catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.component.html
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/DirectiveType.java [new file with mode: 0644]
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/CreateDirectiveNodeFilterFlow.java [new file with mode: 0644]
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ComponentPage.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourceLeftSideMenu.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java [new file with mode: 0644]
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDetailSideBarComponent.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDirectiveNodeFilterTab.java [new file with mode: 0644]
integration-tests/src/test/resources/ci/testSuites/frontend/onapUiSanity.xml

index dcf3447..df2136b 100644 (file)
@@ -24,6 +24,7 @@
             <div class="i-sdc-form-item propertySchemaType" *ngIf="showSchema()">
                 <label class="i-sdc-form-label required">Schema Type</label>
                 <ui-element-dropdown [testId]="'property-schema-type'"
+                                     data-tests-id="property-schema-type"
                                      class="cell link-selector"
                                      [values]="typesSchemaProperties"
                                      [(value)]="propertyModel.schema.property.type"></ui-element-dropdown>
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/DirectiveType.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/DirectiveType.java
new file mode 100644 (file)
index 0000000..5c72e5c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * ============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.datatypes;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum DirectiveType {
+    SELECT("select"),
+    SELECTABLE("selectable"),
+    SUBSTITUTE("substitute"),
+    SUBSTITUTABLE("substitutable");
+
+    private final String name;
+}
index 578edbe..d3ab9d4 100644 (file)
@@ -28,11 +28,11 @@ 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;
 
-import com.aventstack.extentreports.Status;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,11 +42,13 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.stream.Collectors;
+
 import org.onap.sdc.backend.ci.tests.data.providers.OnboardingDataProviders;
 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;
@@ -57,6 +59,7 @@ 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.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;
@@ -69,6 +72,7 @@ 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.ResourcePropertiesAssignmentPage;
+import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesPage;
 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;
@@ -81,6 +85,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 import org.yaml.snakeyaml.Yaml;
 
+import com.aventstack.extentreports.Status;
+
 public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTemplateDesignUiTests.class);
@@ -202,6 +208,44 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         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 List<String> propertyNames = vfcPropertiesPage.getPropertyNames();
+        final ServiceDependencyProperty serviceDependencyProperty = new ServiceDependencyProperty(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, DirectiveType.SELECT, serviceDependencyProperty);
+        createDirectiveNodeFilterFlow.run(componentPage);
+
+        verifyAvailableDirectiveTypes(createDirectiveNodeFilterFlow.getDirectiveOptions());
+
+        verifyAvailablePropertyNames(propertyNames, createDirectiveNodeFilterFlow.getPropertyOptions());
+
+        componentPage = compositionPage.goToGeneral();
+        componentPage.isLoaded();
+        final Map<?, ?> yaml = downloadToscaTemplate();
+        verifyToscaTemplateHasDirectiveNodeFilter(yaml, serviceDependencyProperty, vfcNameInComposition);
+    }
+
     private void checkMetadata(final Map<String, Object> map, final ResourceCreateData createdData) {
         final Map<String, Object> metadata = getMapEntry(map, "metadata");
 
@@ -633,4 +677,44 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         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");
+    }
 }
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/CreateDirectiveNodeFilterFlow.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/flow/CreateDirectiveNodeFilterFlow.java
new file mode 100644 (file)
index 0000000..b55eab7
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * ============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.flow;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.onap.sdc.frontend.ci.tests.datatypes.DirectiveType;
+import org.onap.sdc.frontend.ci.tests.datatypes.ServiceDependencyProperty;
+import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
+import org.onap.sdc.frontend.ci.tests.pages.PageObject;
+import org.onap.sdc.frontend.ci.tests.pages.ServiceDependenciesEditor;
+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.CompositionDirectiveNodeFilterTab;
+import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
+import org.openqa.selenium.WebDriver;
+
+import com.aventstack.extentreports.Status;
+
+import lombok.Getter;
+
+public class CreateDirectiveNodeFilterFlow extends AbstractUiTestFlow {
+
+    @Getter
+    private List<String> directiveOptions;
+    @Getter
+    private List<String> propertyOptions;
+
+    private final int buttonIndex;
+    private final DirectiveType directiveType;
+    private final ServiceDependencyProperty serviceDependencyProperty;
+    private CompositionPage compositionPage;
+
+    public CreateDirectiveNodeFilterFlow(final WebDriver webDriver, final int buttonIndex, final DirectiveType directiveType
+            , final ServiceDependencyProperty serviceDependencyProperty) {
+        super(webDriver);
+        this.buttonIndex = buttonIndex;
+        this.directiveType = directiveType;
+        this.serviceDependencyProperty = serviceDependencyProperty;
+    }
+
+    @Override
+    public Optional<CompositionPage> run(final PageObject... pageObjects) {
+        extendTest.log(Status.INFO, "Creating directive node filter");
+
+        compositionPage = getCompositionPage(pageObjects);
+        compositionPage.isLoaded();
+
+        final CompositionDetailSideBarComponent sideBar = compositionPage.getDetailSideBar();
+        sideBar.isLoaded();
+        final CompositionDirectiveNodeFilterTab compositionDirectiveNodeFilterTab = (CompositionDirectiveNodeFilterTab)
+                sideBar.selectTab(CompositionDetailTabName.DIRECTIVE_NODE_FILTER);
+        compositionDirectiveNodeFilterTab.isLoaded();
+        directiveOptions = compositionDirectiveNodeFilterTab.getDirectiveSelectOptions();
+        if (!compositionDirectiveNodeFilterTab.isDirectiveSelected(directiveType)) {
+            compositionDirectiveNodeFilterTab.selectDirective(directiveType);
+        }
+
+        final ServiceDependenciesEditor compositionDependenciesEditor = compositionDirectiveNodeFilterTab.clickAddNodeFilter(buttonIndex);
+        compositionDependenciesEditor.isLoaded();
+        propertyOptions = compositionDependenciesEditor.getPropertySelectOptions();
+        compositionDependenciesEditor.addProperty(serviceDependencyProperty);
+        assertTrue(compositionDirectiveNodeFilterTab.isRulePresent(serviceDependencyProperty.getName()), "Created Directive Node filter is not present");
+        ExtentTestActions.takeScreenshot(Status.INFO, serviceDependencyProperty.getName(), "Created directive node filter");
+        return Optional.of(compositionPage);
+    }
+
+    @Override
+    public Optional<CompositionPage> getLandedPage() {
+        return Optional.ofNullable(compositionPage);
+    }
+
+    private CompositionPage getCompositionPage(final PageObject... pageObjects) {
+        return getParameter(pageObjects, CompositionPage.class).orElse(new CompositionPage(webDriver));
+    }
+}
index 8bbbf5a..ada3410 100644 (file)
@@ -102,4 +102,8 @@ public class ComponentPage extends AbstractPageObject {
     public ResourcePropertiesAssignmentPage goToPropertiesAssignment() {
         return resourceLeftSideMenu.clickOnPropertiesAssignmentMenuItem();
     }
+
+    public ResourcePropertiesPage goToProperties() {
+        return resourceLeftSideMenu.clickOnPropertiesMenuItem();
+    }
 }
index 413d4b4..f0a9739 100644 (file)
@@ -109,6 +109,11 @@ public class ResourceLeftSideMenu extends AbstractPageObject {
         return new CompositionPage(webDriver);
     }
 
+    public ResourcePropertiesPage clickOnPropertiesMenuItem() {
+        wrappingElement.findElement(By.xpath(XpathSelector.PROPERTIES_MENU.getXpath())).click();
+        return new ResourcePropertiesPage(webDriver);
+    }
+
     /**
      * 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/ResourcePropertiesPage.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java
new file mode 100644 (file)
index 0000000..ace3041
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * ============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;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Handles the Resource Properties Page UI actions
+ */
+public class ResourcePropertiesPage extends AbstractPageObject {
+
+    public ResourcePropertiesPage(final WebDriver webDriver) {
+        super(webDriver);
+    }
+
+    @Override
+    public void isLoaded() {
+        waitForElementVisibility(By.xpath(XpathSelector.TITLE_DIV.getXpath()));
+        waitPropertiesToLoad();
+    }
+
+    /**
+     * Waits for the properties table to load.
+     */
+    private void waitPropertiesToLoad() {
+        waitForElementVisibility(By.xpath(XpathSelector.PROPERTIES_TABLE.getXpath()));
+        waitForElementInvisibility(By.xpath(XpathSelector.NO_DATA_MESSAGE.getXpath()));
+    }
+
+    /**
+     * Returns a list based on property names
+     * @return list of names from the properties table
+     */
+    public List<String> getPropertyNames() {
+        waitPropertiesToLoad();
+        return findElements(By.xpath(XpathSelector.PROPERTY_NAMES.getXpath())).stream()
+                .map(ele -> ele.getAttribute("innerText")).collect(Collectors.toList());
+    }
+
+    @AllArgsConstructor
+    @Getter
+    private enum XpathSelector {
+        TITLE_DIV("//div[contains(@class,'tab-title') and contains(text(), 'Properties')]"),
+        PROPERTIES_TABLE("//div[contains(@class,'table')]"),
+        NO_DATA_MESSAGE("//div[contains(@class,'no-data') and text()='No data to display']"),
+        PROPERTY_TYPES("//*[contains(@data-tests-id, 'propertyType')]"),
+        PROPERTY_NAMES("//*[contains(@data-tests-id, 'propertyName')]");
+
+        private final String xpath;
+    }
+
+}
index d1ec6d0..cc3e284 100644 (file)
@@ -19,6 +19,9 @@
 
 package org.onap.sdc.frontend.ci.tests.pages;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 import org.onap.sdc.frontend.ci.tests.datatypes.ServiceDependencyProperty;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebDriver;
@@ -41,6 +44,15 @@ public class ServiceDependenciesEditor extends AbstractPageObject {
     public void isLoaded() {
         waitForElementVisibility(By.xpath(XpathSelector.SERVICE_DEPENDENCIES_EDITOR.xPath));
     }
+    /**
+     * Returns a list of strings based on the property UI Select
+     * @return List of property names which can be selected
+     */
+    public List<String> getPropertySelectOptions() {
+        return new Select(webDriver.findElement(By.xpath(XpathSelector.SERVICE_PROPERTY_NAME.xPath)))
+                .getOptions().stream()
+                .map(option -> option.getAttribute("innerText")).collect(Collectors.toList());
+    }
 
     public void addProperty(final ServiceDependencyProperty property) {
         final Select properties = new Select(webDriver.findElement(By.xpath(XpathSelector.SERVICE_PROPERTY_NAME.xPath)));
index 346f639..fc968fc 100644 (file)
@@ -80,6 +80,8 @@ public class CompositionDetailSideBarComponent extends AbstractPageObject {
                 return new CompositionRequirementsCapabilitiesTab(webDriver);
             case INTERFACE_OPERATIONS:
                 return new CompositionInterfaceOperationsTab(webDriver);
+            case DIRECTIVE_NODE_FILTER:
+                return new CompositionDirectiveNodeFilterTab(webDriver);
             default:
                 throw new IllegalStateException("Not yet implemented: " + tabName);
         }
@@ -102,7 +104,8 @@ public class CompositionDetailSideBarComponent extends AbstractPageObject {
         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']");
+        SUBSTITUTION_FILTER_TAB("detail-tab-substitution-filter", "//li[@data-tests-id='%s']"),
+        DIRECTIVE_NODE_FILTER_TAB("detail-tab-directives-node-filter", "//li[@data-tests-id='%s']");
 
         @Getter
         private final String id;
@@ -123,7 +126,8 @@ public class CompositionDetailSideBarComponent extends AbstractPageObject {
         API_ARTIFACTS(XpathSelector.API_ARTIFACTS_TAB),
         SUBSTITUTION_FILTER(XpathSelector.SUBSTITUTION_FILTER_TAB),
         INTERFACE_OPERATIONS(XpathSelector.INTERFACE_OPERATIONS_TAB),
-        REQUIREMENTS_CAPABILITIES(XpathSelector.REQUIREMENTS_CAPABILITIES_TAB);
+        REQUIREMENTS_CAPABILITIES(XpathSelector.REQUIREMENTS_CAPABILITIES_TAB),
+        DIRECTIVE_NODE_FILTER(XpathSelector.DIRECTIVE_NODE_FILTER_TAB);
 
         private final XpathSelector xpathSelector;
 
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDirectiveNodeFilterTab.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/CompositionDirectiveNodeFilterTab.java
new file mode 100644 (file)
index 0000000..92f8056
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * ============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 java.util.List;
+import java.util.stream.Collectors;
+
+import org.onap.sdc.frontend.ci.tests.datatypes.DirectiveType;
+import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject;
+import org.onap.sdc.frontend.ci.tests.pages.ServiceDependenciesEditor;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ui.Select;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Represents the composition page, details panel, Directives and Node Filters tab
+ */
+public class CompositionDirectiveNodeFilterTab extends AbstractPageObject {
+
+    public CompositionDirectiveNodeFilterTab(final WebDriver webDriver) {
+        super(webDriver);
+    }
+
+    @Override
+    public void isLoaded() {
+        waitForElementVisibility(By.xpath(XpathSelector.NODE_FILTER_TAB.xPath));
+    }
+
+    /**
+     * Select option from the directive select web element
+     *
+     * @param type which directive type to select from options
+     */
+    public void selectDirective(final DirectiveType type) {
+        final Select directiveSelect = getDirectiveSelect();
+        directiveSelect.selectByVisibleText(type.getName());
+    }
+
+    /**
+     * Returns a ServiceDependenciesEditor when the add node filter button is clicked
+     *
+     * @param index an index indicating which add node filter button to click
+     * @return a new ServiceDependenciesEditor component instance
+     */
+    public ServiceDependenciesEditor clickAddNodeFilter(final int index) {
+        waitForElementVisibility(By.xpath(XpathSelector.ADD_RULE_BUTTON.formatXPath(index))).click();
+        return new ServiceDependenciesEditor(webDriver);
+    }
+
+    /**
+     * Verify a rule has been created
+     *
+     * @param propertyName name of the created rule
+     * @return true if the rule is present on screen otherwise false
+     */
+    public boolean isRulePresent(final String propertyName) {
+        try {
+            return waitForElementVisibility(By.xpath(XpathSelector.RULE_DESC.formatXPath(propertyName))) != null;
+        } catch (final Exception ignored) {
+            return false;
+        }
+    }
+
+    /**
+     * Return all available directive types from the directive select web element
+     *
+     * @return list of strings in lower case based on visible text of the select's web element options.
+     * The List values should correspond to {@link DirectiveType}
+     */
+    public List<String> getDirectiveSelectOptions() {
+        final Select directiveSelect = getDirectiveSelect();
+        final List<String> directiveOptions =  directiveSelect.getOptions().stream()
+                .map(option -> option.getText().toLowerCase()).collect(Collectors.toList());
+        directiveOptions.remove("select directive");
+        return directiveOptions;
+    }
+
+    /**
+     * Verify a directive has been selected
+     *
+     * @param type which directive type to verify
+     * @return true if the directive type is selected on screen otherwise false
+     */
+    public boolean isDirectiveSelected(final DirectiveType type) {
+        try {
+            return waitForElementVisibility(
+                    By.xpath(XpathSelector.NODE_FILTER_DIRECTIVE_SELECTED
+                            .formatXPath(type.getName().toUpperCase())), 2) != null;
+        } catch (final Exception ignored) {
+            return false;
+        }
+    }
+
+    private Select getDirectiveSelect() {
+        return new Select(findElement(By.xpath(XpathSelector.NODE_FILTER_DIRECTIVE_SELECT.xPath)));
+    }
+
+    @AllArgsConstructor
+    @Getter
+    private enum XpathSelector {
+        NODE_FILTER_TAB("//service-dependencies-tab"),
+        NODE_FILTER_DIRECTIVE_SELECT("//select[@id='singleSelect']"),
+        NODE_FILTER_DIRECTIVE_SELECTED("//label[contains(text(),': %s')]"),
+        ADD_RULE_BUTTON("(//*[@data-tests-id='add-rule-button'])[%d]"),
+        RULE_DESC("//*[contains(text(),'%s')]");
+
+        private final String xPath;
+
+        public String formatXPath(Object value) {
+            return String.format(xPath, value);
+        }
+    }
+}
index e6647c7..08a84b9 100644 (file)
@@ -41,6 +41,7 @@
           <include name="addComponentProperty"/>
           <include name="addOutputsToVF_test"/>
           <include name="createSubstitutionFilter"/>
+          <include name="createDirectiveNodeFilterTest"/>
         </methods>
       </class>
     </classes>