From f13f58eb867c763e6ed1c3b674fd99b1081a0664 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Wed, 9 Feb 2022 19:00:35 +0000 Subject: Support complex types in interface operation inputs Issue-ID: SDC-3897 Change-Id: Ieac2d74ad340de1d9f6e4cd3ac830e2ec8c35d5b Signed-off-by: andre.schmid Signed-off-by: vasraz Signed-off-by: MichaelMorris --- .../ci/tests/execute/sanity/ImportVfcUiTest.java | 32 +++-- .../sanity/ServiceTemplateDesignUiTests.java | 25 ++-- .../ci/tests/pages/AbstractPageObject.java | 11 ++ .../InterfaceDefinitionOperationsModal.java | 100 ++++++++----- .../InterfaceOperationAddInputComponent.java | 134 +++++++++++++++++ .../InterfaceOperationInputListComponent.java | 160 +++++++++++++++++++++ 6 files changed, 402 insertions(+), 60 deletions(-) create mode 100644 integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java create mode 100644 integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java (limited to 'integration-tests') 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 bac613861b..e1705a2255 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 @@ -30,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail; import com.aventstack.extentreports.Status; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Optional; import org.apache.commons.collections.MapUtils; @@ -59,6 +60,7 @@ import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInfor 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.InterfaceDefinitionPage; import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage; import org.onap.sdc.frontend.ci.tests.pages.home.HomePage; @@ -150,7 +152,7 @@ public class ImportVfcUiTest extends SetupCDTest { assertTrue(interfaceDefinitionPage.isInterfaceDefinitionOperationPresent(OPERATION_NAME)); final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal = interfaceDefinitionPage.clickOnInterfaceDefinitionOperation( OPERATION_NAME); - interfaceDefinitionOperationsModal.isLoaded(); + interfaceDefinitionOperationsModal.isLoaded(true); ExtentTestActions .takeScreenshot(Status.INFO, "clickOnOInterfaceOperation", "Interface Definition Operation Modal opened"); checkInterfaceDefinitionData(interfaceDefinitionOperationsModal); @@ -171,9 +173,9 @@ public class ImportVfcUiTest extends SetupCDTest { private void checkInterfaceDefinitionData(final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal) { assertTrue(interfaceDefinitionOperationsModal.getDescription().isEmpty()); - assertEquals(interfaceDefinitionOperationsModal.getImplementationName(), "path/to/my/implementation.sh"); - assertEquals(interfaceDefinitionOperationsModal.getInputName(), "first"); - assertEquals(interfaceDefinitionOperationsModal.getInputValue(), "1234"); + assertEquals("path/to/my/implementation.sh", interfaceDefinitionOperationsModal.getImplementationName()); + final List inputList = interfaceDefinitionOperationsModal.getInputs(); + assertTrue(inputList.stream().anyMatch(inputData -> "first".equals(inputData.getName())), "Input of name 'first' expected"); } private ComponentPage manageAttributes(final ComponentPage componentPage) { @@ -223,13 +225,18 @@ public class ImportVfcUiTest extends SetupCDTest { compositionInterfaceOperationsModal.isLoaded(); ExtentTestActions .takeScreenshot(Status.INFO, "compositionInterfaceOperationsTab.clickOnOperation", "Composition Interface Operations Modal opened"); - compositionInterfaceOperationsModal.clickOnDelete(); + compositionInterfaceOperationsModal.deleteInput("first"); ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.clickOnDelete", "Input deleted"); - compositionInterfaceOperationsModal.addInput(); - ExtentTestActions.takeScreenshot(Status.INFO, "compositionInterfaceOperationsModal.addInput", "Adding Input"); - final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData = new InterfaceDefinitionOperationsModal.InterfaceOperationsData - ("This is CREATE operation", "fullPath/to/my/newImplementation.sh", "second", "9876"); + List inputDataList = List.of( + new InputData("stringInput", "string", "1"), + new InputData("booleanInput", "boolean", true), + new InputData("integerInput", "integer", 1) + ); + final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData = + new InterfaceDefinitionOperationsModal.InterfaceOperationsData( + "This is CREATE operation", "fullPath/to/my/newImplementation.sh", inputDataList + ); compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData); compositionInterfaceOperationsTab.isLoaded(); @@ -404,7 +411,10 @@ public class ImportVfcUiTest extends SetupCDTest { final InterfaceDefinitionOperationsModal.InterfaceOperationsData interfaceOperationsData) { assertEquals(interfaceOperationsData.getDescription(), compositionInterfaceOperationsModal.getDescription()); assertEquals(interfaceOperationsData.getImplementationName(), compositionInterfaceOperationsModal.getImplementationName()); - assertEquals(interfaceOperationsData.getInputName(), compositionInterfaceOperationsModal.getInputName()); - assertEquals(interfaceOperationsData.getInputValue(), compositionInterfaceOperationsModal.getInputValue()); + interfaceOperationsData.getInputList().forEach(inputData -> { + final boolean hasInput = compositionInterfaceOperationsModal.getInputs().stream() + .anyMatch(inputData1 -> inputData1.getName().equals(inputData.getName())); + assertTrue(hasInput, String.format("Expecting input '%s'", inputData.getName())); + }); } } diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java index 46c0aefe18..96193f69a2 100644 --- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java @@ -81,6 +81,7 @@ import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionInfor import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal; 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.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; @@ -247,9 +248,12 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest { compositionPage.isLoaded(); ExtentTestActions.addScreenshot(Status.INFO, "select-VFC-node", "Selecting Node on composition"); compositionPage.selectNode(vfcs.get(1).getName()); + final List 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", "My_IT_InputName", "My_IT_InputValue"); + "MyIntegrationTestImplementationName", inputList); updateInterfaceOperation(compositionPage, interfaceOperationsData); componentPage = compositionPage.goToGeneral(); componentPage.isLoaded(); @@ -387,7 +391,6 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest { .clickOnOperation(interfaceOperationName); compositionInterfaceOperationsModal.isLoaded(); ExtentTestActions.takeScreenshot(Status.INFO, "update-interface-operation-modal", "Loading Interface Operations Modal"); - compositionInterfaceOperationsModal.addInput(); compositionInterfaceOperationsModal.updateInterfaceOperation(interfaceOperationsData); compositionInterfaceOperationsTab.isLoaded(); ExtentTestActions.addScreenshot(Status.INFO, "updated-interface-operation", @@ -420,10 +423,10 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest { 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())); +// 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(); } @@ -453,10 +456,12 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest { assertThat("The Interface Operation Implementation Name should match", updatedInterfaceOperation.get("implementation").equals(interfaceOperationsData.getImplementationName())); final Map updatedInterfaceOperationInput = (Map) updatedInterfaceOperation.get("inputs"); - assertThat("The Interface Operation Input Key should match", - updatedInterfaceOperationInput.containsKey(interfaceOperationsData.getInputName())); - assertThat("The Interface Operation Input Value should match", - updatedInterfaceOperationInput.containsValue(interfaceOperationsData.getInputValue())); + 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 downloadToscaArtifact(final ComponentPage resourceCreatePage) throws UnzipException { diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java index 47b655924c..d834c4c3bc 100644 --- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/AbstractPageObject.java @@ -116,6 +116,17 @@ public abstract class AbstractPageObject implements PageObject { return element.findElement(locator); } + /** + * Find elements inside the provided element using the provided xpath. + * + * @param element the parent element + * @param xpath the xpath expression to search for the internal element + * @return the list of WebElement if any found, otherwise throws an exception + */ + protected List findSubElements(final WebElement element, final String xpath) { + return element.findElements(By.xpath(xpath)); + } + /** * Find elements inside the provided element using the provided By locator. * diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java index c8af405411..5a2cb2f5d5 100644 --- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceDefinitionOperationsModal.java @@ -21,10 +21,12 @@ package org.onap.sdc.frontend.ci.tests.pages.component.workspace; import com.aventstack.extentreports.Status; import java.time.Duration; +import java.util.List; 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.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -35,23 +37,33 @@ import org.openqa.selenium.interactions.Actions; */ public class InterfaceDefinitionOperationsModal extends AbstractPageObject { + private InterfaceOperationInputListComponent inputListComponent; + private InterfaceOperationAddInputComponent addInputComponent; + public InterfaceDefinitionOperationsModal(final WebDriver webDriver) { super(webDriver); } @Override public void isLoaded() { + isLoaded(false); + } + + public void isLoaded(boolean isInViewMode) { 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())); - waitForElementVisibility(By.xpath(XpathSelector.ADD_INPUT_BTN.getXPath())); waitForElementVisibility(By.xpath(XpathSelector.SAVE_BTN.getXPath())); waitToBeClickable(By.xpath(XpathSelector.CANCEL_BTN.getXPath())); + this.inputListComponent = new InterfaceOperationInputListComponent(webDriver); + this.inputListComponent.isLoaded(); + if (!isInViewMode) { + this.addInputComponent = new InterfaceOperationAddInputComponent(webDriver); + this.addInputComponent.isLoaded(); + } } - public void clickOnSave() { + private void clickOnSave() { waitToBeClickable(By.xpath(XpathSelector.SAVE_BTN.getXPath())).click(); } @@ -63,11 +75,26 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject { waitToBeClickable(By.xpath(XpathSelector.DELETE_BTN.getXPath())).click(); } + public void deleteInput(String inputName) { + inputListComponent.loadInputList(); + inputListComponent.deleteInput(inputName); + } + public void updateInterfaceOperation(final InterfaceOperationsData interfaceOperationsData) { fillDescription(interfaceOperationsData.getDescription()); fillImplementationName(interfaceOperationsData.getImplementationName()); - fillInputName(interfaceOperationsData.getInputName()); - fillInputValue(interfaceOperationsData.getInputValue()); + interfaceOperationsData.getInputList().forEach(inputData -> { + final InterfaceOperationAddInputComponent addInputComponent = new InterfaceOperationAddInputComponent(webDriver); + addInputComponent.isLoaded(); + addInputComponent.clickOnAddInputLink(); + addInputComponent.fillInput(inputData); + addInputComponent.clickOnAddButton(); + ExtentTestActions.takeScreenshot(Status.INFO, + "compositionInterfaceOperationsModal.addInput." + inputData.getName(), + String.format("Input '%s' added", inputData.getName()) + ); + addInputComponent.fillValue(inputData); + }); clickOnSave(); //there is no feedback from the UI to check if the update was successful. Forcing a wait time trying to guarantee that, // although time is never a guarantee in this case. @@ -82,14 +109,6 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject { 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; @@ -97,11 +116,12 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject { 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 void clickOnAddInput() { + addInputComponent.clickOnAddInputLink(); } public String getDescription() { @@ -112,42 +132,44 @@ public class InterfaceDefinitionOperationsModal extends AbstractPageObject { 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; + public List getInputs() { + inputListComponent.loadInputList(); + return inputListComponent.getInputList(); } @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')]"), DELETE_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']"); + INTERFACE_OPERATION_IMPLEMENTATION_NAME_INPUT("//input[@data-tests-id='interface-operation-implementation-name']"); - @Getter private final String xPath; + public String getXPath(final String... xpathParams) { + return String.format(xPath, xpathParams); + } + } + + @Getter + @AllArgsConstructor + public static class InterfaceOperationsData { + + private final String description; + private final String implementationName; + private final List inputList; + + @Getter + @AllArgsConstructor + public static class InputData { + + private final String name; + private final String type; + private final Object value; + } } } diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java new file mode 100644 index 0000000000..f28d98d3c7 --- /dev/null +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationAddInputComponent.java @@ -0,0 +1,134 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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 lombok.AllArgsConstructor; +import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject; +import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +/** + * Handles the add input inside the interface operation modal. + * + * @see "catalog-ui app-add-input component" + */ +public class InterfaceOperationAddInputComponent extends AbstractPageObject { + + public InterfaceOperationAddInputComponent(final WebDriver webDriver) { + super(webDriver); + } + + @Override + public void isLoaded() { + waitForElementVisibility(XpathSelector.ADD_INPUT_LINK.getXPath()); + } + + /** + * Clicks on the add input link, that opens the add input form. + */ + public void clickOnAddInputLink() { + waitToBeClickable(By.xpath(XpathSelector.ADD_INPUT_LINK.getXPath())).click(); + waitForElementVisibility(XpathSelector.NAME_INPUT.getXPath()); + waitForElementVisibility(XpathSelector.TYPE_INPUT.getXPath()); + waitForElementVisibility(XpathSelector.ADD_BTN.getXPath()); + waitForElementVisibility(XpathSelector.CANCEL_BTN.getXPath()); + } + + /** + * Clicks on the add button that submits the input form. + */ + public void clickOnAddButton() { + waitToBeClickable(By.xpath(XpathSelector.ADD_BTN.getXPath())).click(); + } + + /** + * Fills the input form fields with the given data. + * + * @param inputData the input information + */ + public void fillInput(final InputData inputData) { + fillName(inputData.getName()); + fillType(inputData.getType()); + } + + /** + * Fills an input value, in the input list, based on the given input data. + * + * @param inputData the input information + */ + public void fillValue(final InputData inputData) { + var interfaceOperationInputListComponent = new InterfaceOperationInputListComponent(webDriver); + interfaceOperationInputListComponent.isLoaded(); + interfaceOperationInputListComponent.fillInputValue(inputData.getName(), inputData.getValue()); + } + + /** + * Fills the input name field. + * + * @param name the name to fill + */ + public void fillName(final String name) { + setInputValue(By.xpath(XpathSelector.NAME_INPUT.getXPath()), name); + } + + /** + * Fills the input type field. + * + * @param type the type to fill + */ + public void fillType(final String type) { + final WebElement inputElement = findElement(By.xpath(XpathSelector.TYPE_INPUT.getXPath())); + inputElement.click(); + waitForElementVisibility(By.xpath(XpathSelector.DROPDOWN_RESULTS.getXPath())); + inputElement.sendKeys(type); + waitForElementVisibility(By.xpath(XpathSelector.DROPDOWN_OPTION.getXPath(type))).click(); + } + + private void setInputValue(final By locator, final String value) { + if (value == null) { + return; + } + + final WebElement webElement = findElement(locator); + webElement.clear(); + webElement.sendKeys(value); + } + + @AllArgsConstructor + private enum XpathSelector { + ADD_INPUT_LINK("//a[@data-tests-id='add-input.add-input-link']"), + NAME_INPUT("//input[@data-tests-id='add-input.input-name']"), + TYPE_INPUT("//input[starts-with(@data-tests-id, 'add-input.input-type')]"), + ADD_BTN("//button[@data-tests-id='add-input.add-input-btn']"), + CANCEL_BTN("//button[@data-tests-id='add-input.cancel-btn']"), + DROPDOWN_RESULTS("//dropdown-results"), + DROPDOWN_OPTION("//li[@data-tests-id='%s']"); + + private final String xPath; + + public String getXPath(final String... xpathParams) { + return String.format(xPath, xpathParams); + } + } +} diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java new file mode 100644 index 0000000000..c023401deb --- /dev/null +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/component/workspace/InterfaceOperationInputListComponent.java @@ -0,0 +1,160 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import lombok.AllArgsConstructor; +import org.onap.sdc.frontend.ci.tests.pages.AbstractPageObject; +import org.onap.sdc.frontend.ci.tests.pages.component.workspace.InterfaceDefinitionOperationsModal.InterfaceOperationsData.InputData; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +/** + * Handles the input list inside the interface operation modal. + * + * @see "catalog-ui app-input-list and app-input-list-item ui components" + */ +public class InterfaceOperationInputListComponent extends AbstractPageObject { + + private WebElement wrappingElement; + private List inputList = new ArrayList<>(); + + public InterfaceOperationInputListComponent(final WebDriver webDriver) { + super(webDriver); + } + + @Override + public void isLoaded() { + this.wrappingElement = waitForElementVisibility(XpathSelector.WRAPPING_ELEMENT.getXPath()); + loadInputList(); + } + + /** + * Loads the input list + */ + public void loadInputList() { + this.inputList = findSubElements(wrappingElement, XpathSelector.INPUT_LIST.getXPath()); + } + + /** + * Fill an input value. + * + * @param inputName the input name + * @param value the value + */ + public void fillInputValue(final String inputName, final Object value) { + if (value == null) { + return; + } + if (value instanceof String || value instanceof Integer || value instanceof Boolean) { + fillSimpleValue(inputName, String.valueOf(value)); + return; + } + throw new UnsupportedOperationException("Set input value not yet implemented for value type: " + value.getClass().getName()); + } + + /** + * Expands or retracts an input in the input list. + * + * @param name the input name + */ + public void toggleInputExpansion(final String name) { + final Optional inputOpt = findInput(name); + final By expandIconSelector = By.xpath(XpathSelector.EXPAND_ICON.getXPath()); + inputOpt.ifPresent(webElement -> + webElement.findElement(expandIconSelector).click() + ); + } + + /** + * Deletes an input from the input list. + * + * @param name the name of the input to delete + */ + public void deleteInput(final String name) { + final Optional inputOpt = findInput(name); + final By deleteIconSelector = By.xpath(XpathSelector.DELETE_ICON.getXPath()); + inputOpt.ifPresent(webElement -> + webElement.findElement(deleteIconSelector).click() + ); + loadInputList(); + assertTrue(findInput(name).isEmpty()); + } + + public List getInputList() { + if (inputList.isEmpty()) { + return Collections.emptyList(); + } + final List inputDataList = new ArrayList<>(); + final By inputLabelSelector = By.xpath(XpathSelector.INPUT_LABEL.getXPath()); + final By inputTypeSelector = By.xpath(XpathSelector.INPUT_TYPE.getXPath()); + inputList.forEach(inputWebElement -> { + String inputLabel = inputWebElement.findElement(inputLabelSelector).getText(); + inputLabel = inputLabel.substring(0, inputLabel.length() -1); + final String inputType = inputWebElement.findElement(inputTypeSelector).getText(); + var inputData = new InputData(inputLabel, inputType, null); + inputDataList.add(inputData); + }); + + return inputDataList; + } + + private Optional findInput(final String name) { + final String label = name + ":"; + final By inputLabelSelector = By.xpath(XpathSelector.INPUT_LABEL.getXPath()); + return inputList.stream().filter(webElement -> { + final WebElement inputLabel = webElement.findElement(inputLabelSelector); + return label.equals(inputLabel.getText()); + }).findFirst(); + } + + private void fillSimpleValue(final String inputName, final String inputValue) { + toggleInputExpansion(inputName); + final Optional inputOpt = findInput(inputName); + assertTrue(inputOpt.isPresent(), String.format("Could not set value for input '%s'. The input was not found.", inputName)); + final By simpleInputValueSelector = By.xpath(XpathSelector.SIMPLE_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO.getXPath()); + inputOpt.ifPresent(webElement -> webElement.findElement(simpleInputValueSelector).sendKeys(inputValue)); + } + + @AllArgsConstructor + private enum XpathSelector { + WRAPPING_ELEMENT("//div[@class='input-tree']"), + INPUT_LIST("//div[@class='input-tree']/*/*/*/span[@class='input-info']"), + INPUT_LABEL("label[@class='input-label']"), + INPUT_TYPE("em[@data-tests-id='input-type']"), + SIMPLE_VALUE_INPUT_RELATIVE_FROM_INPUT_INFO("..//li[@class='input-value']/input"), + EXPAND_ICON("em[contains(concat(' ',normalize-space(@class),' '),' round-expand-icon ')]"), + DELETE_ICON("span[contains(concat(' ',normalize-space(@class),' '),' delete-btn ')]"); + + private final String xPath; + + public String getXPath(final String... xpathParams) { + return String.format(xPath, xpathParams); + } + } +} -- cgit 1.2.3-korg