Onboard PNF software version Ui test case 30/99430/7
authorandre.schmid <andre.schmid@est.tech>
Thu, 21 Nov 2019 13:23:07 +0000 (13:23 +0000)
committerOfir Sonsino <ofir.sonsino@intl.att.com>
Mon, 13 Jan 2020 09:56:16 +0000 (09:56 +0000)
Change-Id: Ie5785c220e15afbc35efaa8158ab86c41fc34437
Issue-ID: SDC-2702
Signed-off-by: andre.schmid <andre.schmid@est.tech>
34 files changed:
.gitignore
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/data/providers/OnboardingDataProviders.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ElementFactory.java
ui-ci/.gitignore
ui-ci/pom.xml
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/exception/GeneralUiRuntimeException.java
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/exception/HomePageRuntimeException.java
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/exception/PropertiesAssignmentPageException.java
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/exception/WebDriverThreadRuntimeException.java
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/OnboardingFlowsUi.java
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/setup/ExtentTestActions.java
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/AbstractUiTestFlow.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CheckSoftwareVersionPropertyFlow.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CreateResourceFlow.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CreateVspFlow.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/ImportVspFlow.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/UiTestFlow.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/exception/MissingParameterRuntimeException.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/exception/UiTestFlowRuntimeException.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/AbstractPageObject.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OnboardHeaderComponent.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OnboardHomePage.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/PageObject.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceCreatePage.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceLeftSideMenu.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourcePropertiesAssignmentPage.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/SoftwareProductOnboarding.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/TopNavComponent.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspCommitModal.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspCreationModal.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspRepositoryModalComponent.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/LoaderHelper.java [new file with mode: 0644]
ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/NotificationHelper.java [new file with mode: 0644]
ui-ci/src/main/resources/ci/testSuites/onapUiSanity.xml

index 415b38f..5a68c73 100644 (file)
@@ -189,7 +189,6 @@ catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-co
 catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/logback.xml
 
 test-apis-ci/sdc-api-tests/chef-repo/cookbooks/sdc-api-tests/files/default/testSuites/*
-ui-ci/sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/testSuites/*
  
 sdnc-tests-new-frame-work/test-output/*
 sdnc-tests-new-frame-work/test-output/**
@@ -260,8 +259,6 @@ utils/DmaapPublisher/logs/*
 
 /openecomp-ui/yarn.lock
 
-/ui-ci/sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/Files/VNFs/*
-
 /openecomp-be/dist/sdc-onboard-db-init-docker/artifacts/init_keyspaces.cql
 /openecomp-be/dist/sdc-onboard-db-init-docker/artifacts/init_schemas.cql
 /openecomp-be/dist/sdc-onboard-db-init-docker/artifacts/alter_tables.cql
index cc33e48..a2f39b3 100644 (file)
@@ -22,8 +22,10 @@ package org.openecomp.sdc.ci.tests.data.providers;
 import static org.testng.Assert.fail;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.apache.commons.collections4.CollectionUtils;
 import org.openecomp.sdc.ci.tests.datatypes.enums.XnfTypeEnum;
 import org.openecomp.sdc.ci.tests.utils.general.FileHandling;
@@ -32,7 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.DataProvider;
 
-public class OnboardingDataProviders {
+public final class OnboardingDataProviders {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(OnboardingDataProviders.class);
     private static final String VNF_FILE_PATH = FileHandling.getXnfRepositoryPath(XnfTypeEnum.VNF);
@@ -76,6 +78,27 @@ public class OnboardingDataProviders {
         return provideData(newList, VNF_FILE_PATH);
     }
 
+    @DataProvider(name = "softwareInformationPnf", parallel = true)
+    private static Object[][] softwareInformationPnf() {
+        final List<String> pnfPackageFileNameList = OnboardingUtils.getXnfNamesFileList(XnfTypeEnum.PNF);
+        if (CollectionUtils.isEmpty(pnfPackageFileNameList)) {
+            fail("Could not create softwareInformationPnf datasource");
+        }
+        final String pnfPackage = "sample-pnf-1.0.1-SNAPSHOT.csar";
+        final Optional<String> softwareInformationPnfPackage = pnfPackageFileNameList.stream()
+            .filter(pnfPackage::equals).findFirst();
+        if (!softwareInformationPnfPackage.isPresent()) {
+            fail(String.format("Could not create softwareInformationPnf datasource, the package '%s' was not found",
+                pnfPackage));
+        }
+
+        final String folderPath = FileHandling.getXnfRepositoryPath(XnfTypeEnum.PNF);
+        final Object[][] parametersArray = new Object[1][];
+        parametersArray[0] = new Object[]{folderPath, softwareInformationPnfPackage.get(),
+            Arrays.asList("5gDUv18.05.201", "5gDUv18.06.205")};
+        return parametersArray;
+    }
+
     private static Object[][] provideData(final List<String> fileNamesFromFolder, final String folderPath) {
         final Object[][] parametersArray = new Object[fileNamesFromFolder.size()][];
         int index = 0;
index 82954e6..31b8c5b 100644 (file)
@@ -49,7 +49,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-public class ElementFactory {
+public final class ElementFactory {
 
        private static final String CI_SERVICE = "ciService";
        private static final String CI_RES = "ciRes";
@@ -58,6 +58,10 @@ public class ElementFactory {
        private static final String RESOURCE_INSTANCE_POS_X = "20";
        private static final String RESOURCE_INSTANCE_POS_Y = "20";
        private static final String RESOURCE_INSTANCE_DESCRIPTION = "description";
+
+       private ElementFactory() {
+
+       }
        
        // *** Getters ***
        
@@ -133,7 +137,7 @@ public class ElementFactory {
        }
 
        public static ResourceReqDetails getDefaultResource(String resourceName, NormativeTypesEnum derived, ResourceCategoryEnum category, String contactId) {
-               resourceName = (resourceName + generateUUIDforSufix());
+               resourceName = addRandomSuffixToName(resourceName);
                String description = "Represents a generic software component that can be managed and run by a Compute Node Type.";
                ArrayList<String> resourceTags = new ArrayList<>();
                resourceTags.add(resourceName);
@@ -156,7 +160,7 @@ public class ElementFactory {
        }
 
        public static ResourceReqDetails getDefaultResource(String resourceName, Resource derived, ResourceCategoryEnum category, String contactId) {
-               resourceName = (resourceName + generateUUIDforSufix());
+               resourceName = addRandomSuffixToName(resourceName);
                String description = "Represents a generic software component that can be managed and run by a Compute Node Type.";
                ArrayList<String> resourceTags = new ArrayList<>();
                resourceTags.add(resourceName);
@@ -173,6 +177,10 @@ public class ElementFactory {
 
        }
 
+       public static String addRandomSuffixToName(final String name) {
+               return name + generateUUIDforSufix();
+       }
+
        public static ResourceReqDetails getDefaultResourceByType(String resourceName, NormativeTypesEnum derived, ResourceCategoryEnum category, String contactId, ResourceTypeEnum resourceType) {
                return getDefaultResourceByType(resourceName, derived, category, contactId, resourceType.toString());
        }
@@ -1028,10 +1036,8 @@ public class ElementFactory {
        }
 
        public static String generateUUIDforSufix() {
-
-               String uniqueSufix = UUID.randomUUID().toString();
-               String[] split = uniqueSufix.split("-");
-               return uniqueSufix = split[4];
+               final String uniqueSuffix = UUID.randomUUID().toString();
+               return uniqueSuffix.split("-")[4];
        }
 
        private static String normalizeArtifactLabel(String label) {
index 6405eb7..1b73d10 100644 (file)
@@ -1,2 +1,4 @@
 /bin/
-test-output/
\ No newline at end of file
+test-output/
+sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/Files
+sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/testSuites
\ No newline at end of file
index bf45a1d..30ed36c 100644 (file)
                        <scope>compile</scope>
                </dependency>
 
+               <dependency>
+                       <groupId>org.hamcrest</groupId>
+                       <artifactId>hamcrest</artifactId>
+                       <version>${hamcrest.version}</version>
+                       <scope>compile</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.hamcrest</groupId>
+                       <artifactId>hamcrest-library</artifactId>
+                       <version>${hamcrest.version}</version>
+                       <scope>compile</scope>
+               </dependency>
+
                <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                                                                        <directory>${project.basedir}/sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/testSuites</directory>
                                                                        <followSymlinks>false</followSymlinks>
                                                                </fileset>
-                                                               <!-- VNF files -->
+                                                               <!-- Package files -->
                                                                <fileset>
-                                                                       <directory>${project.basedir}/sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/Files/VNFs</directory>
+                                                                       <directory>${project.basedir}/sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/Files</directory>
                                                                        <followSymlinks>false</followSymlinks>
                                                                </fileset>
                                                        </filesets>
                                                                        <goal>copy-resources</goal>
                                                                </goals>
                                                                <configuration>
-                                                                       <outputDirectory>sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/Files/VNFs</outputDirectory>
+                                                                       <outputDirectory>sdc-ui-tests/chef-repo/cookbooks/sdc-ui-tests/files/default/Files</outputDirectory>
                                                                        <resources>
                                                                                <resource>
-                                                                                       <directory>${project.parent.basedir}/test-apis-ci/sdc-api-tests/chef-repo/cookbooks/sdc-api-tests/files/default/Files/VNFs</directory>
+                                                                                       <directory>${project.parent.basedir}/test-apis-ci/sdc-api-tests/chef-repo/cookbooks/sdc-api-tests/files/default/Files</directory>
+                                                                                       <filtering>false</filtering>
                                                                                        <includes>
-                                                                                               <include>*</include>
+                                                                                               <include>VNFs/*</include>
+                                                                                               <include>PNFs/*</include>
                                                                                        </includes>
                                                                                </resource>
                                                                        </resources>
index 9a4e0d1..81b8500 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.openecomp.sdc.ci.tests.exception;
 
+@SuppressWarnings("serial")
 public class GeneralUiRuntimeException extends RuntimeException {
 
     public GeneralUiRuntimeException(final String s, final Throwable throwable) {
index 39bf648..bcb2013 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.openecomp.sdc.ci.tests.exception;
 
+@SuppressWarnings("serial")
 public class HomePageRuntimeException extends RuntimeException {
 
     public HomePageRuntimeException(final String s, final Throwable throwable) {
index f0fbfeb..f2a7990 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.openecomp.sdc.ci.tests.exception;
 
+@SuppressWarnings("serial")
 public class PropertiesAssignmentPageException extends Exception {
 
     public PropertiesAssignmentPageException(final String s, final Throwable throwable) {
index 8ba4689..8cf55f7 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.openecomp.sdc.ci.tests.exception;
 
+@SuppressWarnings("serial")
 public class WebDriverThreadRuntimeException extends RuntimeException {
 
     public WebDriverThreadRuntimeException(final String s, final Throwable throwable) {
index 9a28ee9..17c953e 100644 (file)
@@ -26,6 +26,7 @@ import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
+import com.aventstack.extentreports.ExtentTest;
 import com.aventstack.extentreports.Status;
 import java.io.File;
 import java.util.Arrays;
@@ -45,17 +46,25 @@ import org.openecomp.sdc.ci.tests.datatypes.VendorSoftwareProductObject;
 import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum;
 import org.openecomp.sdc.ci.tests.datatypes.enums.XnfTypeEnum;
 import org.openecomp.sdc.ci.tests.execute.setup.ArtifactsCorrelationManager;
+import org.openecomp.sdc.ci.tests.execute.setup.DriverFactory;
 import org.openecomp.sdc.ci.tests.execute.setup.ExtentTestActions;
 import org.openecomp.sdc.ci.tests.execute.setup.SetupCDTest;
+import org.openecomp.sdc.ci.tests.flow.CheckSoftwareVersionPropertyFlow;
+import org.openecomp.sdc.ci.tests.flow.CreateResourceFlow;
+import org.openecomp.sdc.ci.tests.flow.CreateVspFlow;
+import org.openecomp.sdc.ci.tests.flow.ImportVspFlow;
+import org.openecomp.sdc.ci.tests.flow.exception.UiTestFlowRuntimeException;
 import org.openecomp.sdc.ci.tests.pages.CompositionPage;
 import org.openecomp.sdc.ci.tests.pages.DeploymentArtifactPage;
 import org.openecomp.sdc.ci.tests.pages.GovernorOperationPage;
 import org.openecomp.sdc.ci.tests.pages.HomePage;
 import org.openecomp.sdc.ci.tests.pages.HomePage.PageElement;
 import org.openecomp.sdc.ci.tests.pages.OpsOperationPage;
+import org.openecomp.sdc.ci.tests.pages.ResourceCreatePage;
 import org.openecomp.sdc.ci.tests.pages.ResourceGeneralPage;
 import org.openecomp.sdc.ci.tests.pages.ServiceGeneralPage;
 import org.openecomp.sdc.ci.tests.pages.TesterOperationPage;
+import org.openecomp.sdc.ci.tests.pages.TopNavComponent;
 import org.openecomp.sdc.ci.tests.pages.VspValidationPage;
 import org.openecomp.sdc.ci.tests.pages.VspValidationResultsPage;
 import org.openecomp.sdc.ci.tests.utilities.FileHandling;
@@ -68,6 +77,7 @@ import org.openecomp.sdc.ci.tests.utils.general.OnboardingUtils;
 import org.openecomp.sdc.ci.tests.utils.general.VendorLicenseModelRestUtils;
 import org.openecomp.sdc.ci.tests.utils.general.VendorSoftwareProductRestUtils;
 import org.openecomp.sdc.ci.tests.verificator.ServiceVerificator;
+import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -169,6 +179,14 @@ public class OnboardingFlowsUi extends SetupCDTest {
         }
     }
 
+    @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "softwareInformationPnf")
+    public void onboardPNFSoftwareInformationFlow(final String rootFolder, final String pnfFile,
+                                                  final List<String> softwareVersionList) {
+        setLog(pnfFile);
+        final String resourceName = ElementFactory.addRandomSuffixToName(ElementFactory.getResourcePrefix());
+        runOnboardPnfSoftwareVersion(resourceName, rootFolder, pnfFile, softwareVersionList);
+    }
+
     @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "Single_VNF")
     public void onapOnboardVSPValidationsConfigurationChangeCheck(String filePath, String vnfFile) throws Exception {
         setLog(vnfFile);
@@ -356,6 +374,38 @@ public class OnboardingFlowsUi extends SetupCDTest {
         return OnboardingUiUtils.createVSP(resourceReqDetails, vnfFile, filePath, getUser()).getName();
     }
 
+    public void runOnboardPnfSoftwareVersion(final String resourceName, final String rootFolder,
+                                             final String pnfFile, final List<String> softwareVersionList) {
+        final ExtentTest extendTest = getExtendTest();
+
+        final String swVersionsToString = String.join(", ", softwareVersionList);
+
+        extendTest.log(Status.INFO,
+            String.format("Creating VSP '%s' by onboarding package '%s' with software version '%s'",
+                resourceName, pnfFile, swVersionsToString)
+        );
+        final WebDriver webDriver = DriverFactory.getDriver();
+        final CreateVspFlow createVspFlow = new CreateVspFlow(webDriver, resourceName, pnfFile, rootFolder);
+        createVspFlow.run(new TopNavComponent(webDriver));
+
+        final ImportVspFlow importVspFlow = new ImportVspFlow(webDriver, resourceName);
+        final ResourceCreatePage resourceCreatePage =
+            (ResourceCreatePage) importVspFlow.run()
+                .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ResourceCreatePage"));
+
+        final CreateResourceFlow createResourceFlow = new CreateResourceFlow(webDriver, resourceName);
+        createResourceFlow.run(resourceCreatePage);
+
+        final CheckSoftwareVersionPropertyFlow checkSoftwareVersionPropertyFlow =
+            new CheckSoftwareVersionPropertyFlow(webDriver, softwareVersionList);
+        checkSoftwareVersionPropertyFlow.run();
+
+        extendTest.log(Status.INFO,
+            String.format("Successfully onboarded the package '%s' with software version '%s'",
+                pnfFile, swVersionsToString)
+        );
+    }
+
     private void runOnboardToDistributionFlow(ResourceReqDetails resourceReqDetails, ServiceReqDetails serviceMetadata, String filePath, String vnfFile) throws Exception {
         getExtendTest().log(Status.INFO, "Going to create resource with category: " + resourceReqDetails.getCategories().get(0).getName()
                 + " subCategory: " + resourceReqDetails.getCategories().get(0).getSubcategories().get(0).getName()
index c3a1d13..4fc05d9 100644 (file)
@@ -26,16 +26,20 @@ import com.aventstack.extentreports.Status;
 import com.aventstack.extentreports.markuputils.ExtentColor;
 import com.aventstack.extentreports.markuputils.Markup;
 import com.aventstack.extentreports.markuputils.MarkupHelper;
+import java.util.Optional;
 import org.openecomp.sdc.ci.tests.api.SomeInterface;
 import org.openecomp.sdc.ci.tests.utilities.GeneralUIUtils;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.UUID;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class ExtentTestActions {
+public final class ExtentTestActions {
 
     private static final SomeInterface testManager = ExtentTestManager.getInstance();
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExtentTestActions.class);
 
     private ExtentTestActions() {
 
@@ -84,6 +88,17 @@ public class ExtentTestActions {
         }
     }
 
+    public static Optional<String> takeScreenshot(final Status logStatus, final String screenshotName,
+                                                  final String message) {
+        try {
+            return Optional.of(addScreenshot(logStatus, screenshotName, message));
+        } catch (final IOException e) {
+            LOGGER.warn("Could not take screenshot", e);
+        }
+
+        return Optional.empty();
+    }
+
     public static String addScreenshot(final Status logStatus, String screenshotName,
                                        final String message) throws IOException {
         final String[] splitUuid = UUID.randomUUID().toString().split("-");
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/AbstractUiTestFlow.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/AbstractUiTestFlow.java
new file mode 100644 (file)
index 0000000..ed4d456
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow;
+
+import com.aventstack.extentreports.ExtentTest;
+import org.openecomp.sdc.ci.tests.execute.setup.ExtentTestManager;
+import org.openecomp.sdc.ci.tests.flow.exception.MissingParameterRuntimeException;
+import org.openecomp.sdc.ci.tests.pages.PageObject;
+import org.openqa.selenium.WebDriver;
+
+public abstract class AbstractUiTestFlow implements UiTestFlow {
+
+    protected final WebDriver webDriver;
+    protected final ExtentTest extendTest = ExtentTestManager.getInstance().getTest();
+
+    public AbstractUiTestFlow(final WebDriver webDriver) {
+        this.webDriver = webDriver;
+    }
+
+    public <T extends PageObject> T findParameter(final PageObject[] pageObjects,
+                                                  final Class<T> expectedParameterType) {
+        for (final PageObject uiTestFlow : pageObjects) {
+            if(expectedParameterType.isInstance(uiTestFlow)) {
+                return (T) uiTestFlow;
+            }
+        }
+
+        throw new MissingParameterRuntimeException(expectedParameterType.getName());
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CheckSoftwareVersionPropertyFlow.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CheckSoftwareVersionPropertyFlow.java
new file mode 100644 (file)
index 0000000..dbdbe10
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertThat;
+
+import com.aventstack.extentreports.Status;
+import java.util.List;
+import java.util.Optional;
+import org.openecomp.sdc.ci.tests.pages.PageObject;
+import org.openecomp.sdc.ci.tests.pages.ResourceLeftSideMenu;
+import org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * UI Flow for checking the software version property in a resource
+ */
+public class CheckSoftwareVersionPropertyFlow extends AbstractUiTestFlow {
+
+    private final List<String> expectedSoftwareVersionList;
+
+    public CheckSoftwareVersionPropertyFlow(final WebDriver webDriver, final List<String> expectedSoftwareVersionList) {
+        super(webDriver);
+        this.expectedSoftwareVersionList = expectedSoftwareVersionList;
+    }
+
+    @Override
+    public Optional<PageObject> run(final PageObject... pageObjects) {
+        final ResourceLeftSideMenu resourceLeftSideMenu = new ResourceLeftSideMenu(webDriver);
+        resourceLeftSideMenu.isLoaded();
+
+        final ResourcePropertiesAssignmentPage resourcePropertiesAssignmentPage = accessPropertiesAssignmentPage();
+
+        checkSoftwareVersionProperty(resourcePropertiesAssignmentPage);
+        return Optional.empty();
+    }
+
+    /**
+     * Checks if the software_version property values are as expected by the {@link #expectedSoftwareVersionList}.
+     *
+     * @param resourcePropertiesAssignmentPage the resource properties assignment page
+     */
+    private void checkSoftwareVersionProperty(final ResourcePropertiesAssignmentPage resourcePropertiesAssignmentPage) {
+        extendTest.log(Status.INFO,
+            String.format("Checking the presence of software versions '%s' in 'software_versions' property",
+                getSoftwareVersionListAsString())
+        );
+        final List<String> actualSoftwareVersionList = resourcePropertiesAssignmentPage.getSoftwareVersionProperty();
+        assertThat("Software Version should have the expected size", actualSoftwareVersionList,
+            hasSize(expectedSoftwareVersionList.size()));
+        assertThat("Software Version should be as expected", actualSoftwareVersionList,
+            containsInAnyOrder(expectedSoftwareVersionList.toArray(new String[0])));
+    }
+
+    /**
+     * Accesses the properties assignment page by clicking in the resource left side menu.
+     *
+     * @return the resulting resource properties assignment page
+     */
+    private ResourcePropertiesAssignmentPage accessPropertiesAssignmentPage() {
+        final ResourceLeftSideMenu resourceLeftSideMenu = new ResourceLeftSideMenu(webDriver);
+        resourceLeftSideMenu.isLoaded();
+
+        extendTest.log(Status.INFO,
+            String.format("Accessing the Properties Assignment page to check the software versions '%s'",
+                getSoftwareVersionListAsString())
+        );
+        final ResourcePropertiesAssignmentPage resourcePropertiesAssignmentPage =
+            resourceLeftSideMenu.clickOnPropertiesAssignmentMenuItem();
+        resourcePropertiesAssignmentPage.isLoaded();
+        return resourcePropertiesAssignmentPage;
+    }
+
+    /**
+     * Converts the {@link #expectedSoftwareVersionList} in a comma + space separated string.
+     *
+     * @return the software version list as a comma + space separated string
+     */
+    private String getSoftwareVersionListAsString() {
+        return String.join(", ", expectedSoftwareVersionList);
+    }
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CreateResourceFlow.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CreateResourceFlow.java
new file mode 100644 (file)
index 0000000..0ff923c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow;
+
+import com.aventstack.extentreports.Status;
+import java.util.Optional;
+import org.openecomp.sdc.ci.tests.execute.setup.ExtentTestActions;
+import org.openecomp.sdc.ci.tests.pages.PageObject;
+import org.openecomp.sdc.ci.tests.pages.ResourceCreatePage;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * UI Flow for Resource creation
+ */
+public class CreateResourceFlow extends AbstractUiTestFlow {
+
+    private final String resourceName;
+
+    public CreateResourceFlow(final WebDriver webDriver, final String resourceName) {
+        super(webDriver);
+        this.resourceName = resourceName;
+    }
+
+    @Override
+    public Optional<PageObject> run(final PageObject... pageObjects) {
+        final ResourceCreatePage resourceCreatePage = findParameter(pageObjects, ResourceCreatePage.class);
+        extendTest.log(Status.INFO, String.format("Creating the Resource '%s'", resourceName));
+        resourceCreatePage.createResource();
+        ExtentTestActions.takeScreenshot(Status.INFO, "resource-created",
+            String.format("Resource '%s' was created", resourceName));
+        return Optional.empty();
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CreateVspFlow.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/CreateVspFlow.java
new file mode 100644 (file)
index 0000000..910ef4d
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import com.aventstack.extentreports.Status;
+import java.util.Optional;
+import org.openecomp.sdc.ci.tests.execute.setup.ExtentTestActions;
+import org.openecomp.sdc.ci.tests.pages.OnboardHomePage;
+import org.openecomp.sdc.ci.tests.pages.PageObject;
+import org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding;
+import org.openecomp.sdc.ci.tests.pages.TopNavComponent;
+import org.openecomp.sdc.ci.tests.pages.VspCreationModal;
+import org.openecomp.sdc.ci.tests.utilities.GeneralUIUtils;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * UI Flow for VSP creation
+ */
+public class CreateVspFlow extends AbstractUiTestFlow {
+
+    private final String resourceName;
+    private final String packageFile;
+    private final String rootFolder;
+
+    public CreateVspFlow(final WebDriver webDriver, final String resourceName, final String packageFile,
+                         final String rootFolder) {
+        super(webDriver);
+        this.resourceName = resourceName;
+        this.packageFile = packageFile;
+        this.rootFolder = rootFolder;
+    }
+
+    @Override
+    public Optional<PageObject> run(final PageObject... pageObjects) {
+        final TopNavComponent topNavComponent = findParameter(pageObjects, TopNavComponent.class);
+        extendTest.log(Status.INFO, "Accessing the Onboard Home Page");
+        topNavComponent.isLoaded();
+        final OnboardHomePage onboardHomePage = goToOnboardHomePage(topNavComponent);
+        final SoftwareProductOnboarding softwareProductOnboarding = createNewVsp(onboardHomePage);
+        uploadPackage(softwareProductOnboarding);
+        submitVsp(softwareProductOnboarding);
+        goToHomePage(topNavComponent);
+        return Optional.empty();
+    }
+
+    /**
+     * Goes to the onboard home page by clicking in the onboard tab in the top nav component.
+     *
+     * @param topNavComponent the top nav component
+     * @return the onboard home page
+     */
+    private OnboardHomePage goToOnboardHomePage(final TopNavComponent topNavComponent) {
+        final OnboardHomePage onboardHomePage = topNavComponent.clickOnOnboard();
+        onboardHomePage.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "onboard-homepage", "Onboard homepage is loaded");
+        return onboardHomePage;
+    }
+
+    /**
+     * Creates a new VSP in the onboard home page.
+     *
+     * @param onboardHomePage the onboard home page representation
+     * @return the software product onboarding page
+     */
+    private SoftwareProductOnboarding createNewVsp(final OnboardHomePage onboardHomePage) {
+        extendTest.log(Status.INFO, "Creating a new VSP");
+        final VspCreationModal vspCreationModal = onboardHomePage.clickOnCreateNewVsp();
+        vspCreationModal.isLoaded();
+        vspCreationModal.fillCreationForm(resourceName);
+        ExtentTestActions.takeScreenshot(Status.INFO, "vsp-creation-form",
+            "Creating VSP with given information");
+        final SoftwareProductOnboarding softwareProductOnboarding = vspCreationModal.clickOnCreate();
+        softwareProductOnboarding.isLoaded();
+        extendTest.log(Status.INFO, String.format("VSP '%s' created", resourceName));
+        final String actualResourceName = softwareProductOnboarding.getResourceName();
+        assertThat(String.format("Should be in the Software Product '%s' page", resourceName),
+            actualResourceName, is(resourceName));
+        return softwareProductOnboarding;
+    }
+
+    /**
+     * Uploads a package in the software product onboarding page.
+     *
+     * @param softwareProductOnboarding the software product onboarding page
+     */
+    private void uploadPackage(final SoftwareProductOnboarding softwareProductOnboarding) {
+        extendTest.log(Status.INFO,
+            String.format("Uploading package '%s' to VSP '%s'", packageFile, resourceName)
+        );
+        softwareProductOnboarding.uploadFile(rootFolder + packageFile);
+        softwareProductOnboarding.attachmentScreenIsLoaded();
+        extendTest.log(Status.INFO,
+            String.format("Package '%s' was uploaded to VSP '%s'.", packageFile, resourceName)
+        );
+    }
+
+    /**
+     * Submits the VSP through the software product onboarding page.
+     *
+     * @param softwareProductOnboarding the software product onboarding page
+     */
+    private void submitVsp(final SoftwareProductOnboarding softwareProductOnboarding) {
+        extendTest.log(Status.INFO, "Submitting the first VSP version.");
+        softwareProductOnboarding.submit();
+        ExtentTestActions.takeScreenshot(Status.INFO, "vsp-submitted", "The first VSP version was submitted");
+    }
+
+    /**
+     * Go to the system home page through the top nav menu.
+     *
+     * @param topNavComponent the top nav component
+     */
+    private void goToHomePage(final TopNavComponent topNavComponent) {
+        extendTest.log(Status.INFO, "Accessing the Home page to import the created VSP");
+        topNavComponent.isLoaded();
+        topNavComponent.clickOnHome();
+        GeneralUIUtils.ultimateWait();
+        topNavComponent.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "home-is-loaded", "The Home page is loaded.");
+    }
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/ImportVspFlow.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/ImportVspFlow.java
new file mode 100644 (file)
index 0000000..e59a5c1
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow;
+
+import com.aventstack.extentreports.Status;
+import java.util.Optional;
+import org.openecomp.sdc.ci.tests.execute.setup.ExtentTestActions;
+import org.openecomp.sdc.ci.tests.pages.PageObject;
+import org.openecomp.sdc.ci.tests.pages.ResourceCreatePage;
+import org.openecomp.sdc.ci.tests.pages.TopNavComponent;
+import org.openecomp.sdc.ci.tests.pages.VspRepositoryModalComponent;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * UI Flow for importing a VSP
+ */
+public class ImportVspFlow extends AbstractUiTestFlow {
+
+    private final String resourceName;
+
+    public ImportVspFlow(final WebDriver webDriver, final String resourceName) {
+        super(webDriver);
+        this.resourceName = resourceName;
+    }
+
+    @Override
+    public Optional<PageObject> run(final PageObject... pageObjects) {
+        final VspRepositoryModalComponent vspRepositoryModalComponent = openVspRepository();
+        searchForVsp(vspRepositoryModalComponent);
+        return Optional.of(importVsp(vspRepositoryModalComponent));
+    }
+
+    /**
+     * Opens the VSP repository modal by clicking in its icon from the top nav menu.
+     *
+     * @return the VSP repository modal
+     */
+    private VspRepositoryModalComponent openVspRepository() {
+        extendTest.log(Status.INFO, "Opening the VSP repository");
+        final TopNavComponent topNavComponent = new TopNavComponent(webDriver);
+        topNavComponent.isLoaded();
+        final VspRepositoryModalComponent vspRepositoryModalComponent = topNavComponent.clickOnRepositoryIcon();
+        vspRepositoryModalComponent.isLoaded();
+        return vspRepositoryModalComponent;
+    }
+
+    /**
+     * Searches for a VSP in the repository modal.
+     *
+     * @param vspRepositoryModalComponent the repository modal component
+     */
+    private void searchForVsp(final VspRepositoryModalComponent vspRepositoryModalComponent) {
+        extendTest.log(Status.INFO, String.format("Searching for VSP '%s' in the repository", resourceName));
+        vspRepositoryModalComponent.searchForVSP(resourceName);
+        ExtentTestActions.takeScreenshot(Status.INFO, "vsp-found-repository",
+            String.format("Searching for VSP '%s' found in the repository", resourceName));
+    }
+
+    /**
+     * Imports the first VSP in the repository list.
+     *
+     * @param vspRepositoryModalComponent the repository modal component that contains the VSP list
+     * @return the resource creation page that the import action redirects
+     */
+    private ResourceCreatePage importVsp(final VspRepositoryModalComponent vspRepositoryModalComponent) {
+        extendTest.log(Status.INFO, String.format("Importing VSP '%s'", resourceName));
+        final ResourceCreatePage resourceCreatePage = vspRepositoryModalComponent.clickOnImportVsp(1);
+        resourceCreatePage.isLoaded();
+        ExtentTestActions.takeScreenshot(Status.INFO, "vsp-imported",
+            String.format("VSP '%s' was imported", resourceName));
+        return resourceCreatePage;
+    }
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/UiTestFlow.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/UiTestFlow.java
new file mode 100644 (file)
index 0000000..eedecbf
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow;
+
+import java.util.Optional;
+import org.openecomp.sdc.ci.tests.pages.PageObject;
+
+/**
+ * Represents a UI test flow
+ */
+@FunctionalInterface
+public interface UiTestFlow {
+
+    /**
+     * Runs the flow
+     * @param pageObjects any required page object for the flow
+     * @return an optional page object representing the page that the flow has ended
+     */
+    Optional<PageObject> run(final PageObject... pageObjects);
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/exception/MissingParameterRuntimeException.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/exception/MissingParameterRuntimeException.java
new file mode 100644 (file)
index 0000000..92dc870
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow.exception;
+
+@SuppressWarnings("serial")
+public class MissingParameterRuntimeException extends UiTestFlowRuntimeException {
+
+    public MissingParameterRuntimeException(final String parameterName) {
+        super(String.format("Missing parameter expected %s", parameterName));
+    }
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/exception/UiTestFlowRuntimeException.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/flow/exception/UiTestFlowRuntimeException.java
new file mode 100644 (file)
index 0000000..a535077
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.flow.exception;
+
+@SuppressWarnings("serial")
+public class UiTestFlowRuntimeException extends RuntimeException {
+
+    public UiTestFlowRuntimeException(final String s) {
+        super(s);
+    }
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/AbstractPageObject.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/AbstractPageObject.java
new file mode 100644 (file)
index 0000000..1c051db
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import java.util.List;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+/**
+ * Base UI test object that represents a page or component in a html page
+ */
+public abstract class AbstractPageObject implements PageObject {
+
+    protected final WebDriver webDriver;
+    protected int timeoutInSeconds;
+
+    public AbstractPageObject(final WebDriver webDriver) {
+        this.webDriver = webDriver;
+        timeoutInSeconds = 10;
+    }
+
+    /**
+     * Sets the default timeout for Page Object actions.
+     */
+    public void setTimeout(final int timeoutInSeconds) {
+        this.timeoutInSeconds = timeoutInSeconds;
+    }
+
+    /**
+     * Creates a WebDriverWait instance with the default timeout.
+     *
+     * @return a new WebDriverWait instance
+     */
+    protected WebDriverWait getWait() {
+        return new WebDriverWait(webDriver, timeoutInSeconds);
+    }
+
+    /**
+     * Creates a WebDriverWait instance with the provided timeout.
+     *
+     * @param timeoutInSeconds the wait timeout in seconds
+     * @return a new WebDriverWait instance
+     */
+    protected WebDriverWait getWait(final int timeoutInSeconds) {
+        return new WebDriverWait(webDriver, timeoutInSeconds);
+    }
+
+    /**
+     * Find an element based on the provided locator.
+     *
+     * @param locator the By locator
+     * @return the WebElement if found, otherwise throws an exception
+     */
+    protected WebElement findElement(final By locator) {
+        return webDriver.findElement(locator);
+    }
+
+    /**
+     * Find elements based on the provided locator.
+     *
+     * @param locator the By locator
+     * @return the list of WebElement if any found, otherwise throws an exception
+     */
+    protected List<WebElement> findElements(final By locator) {
+        return webDriver.findElements(locator);
+    }
+
+    /**
+     * Find an element 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 WebElement if found, otherwise throws an exception
+     */
+    protected WebElement findSubElement(final WebElement element, final String xpath) {
+        return findSubElement(element, By.xpath(xpath));
+    }
+
+    /**
+     * Find an element inside the provided element using the provided By locator.
+     *
+     * @param element the parent element
+     * @param locator the By locator to search for the internal element
+     * @return the WebElement if found, otherwise throws an exception
+     */
+    protected WebElement findSubElement(final WebElement element, final By locator) {
+        return element.findElement(locator);
+    }
+
+    /**
+     * Find elements inside the provided element using the provided By locator.
+     *
+     * @param element the parent element
+     * @param locator the By locator to search for the internal element
+     * @return the list of WebElement if any found, otherwise throws an exception
+     */
+    protected List<WebElement> findSubElements(final WebElement element, final By locator) {
+        return element.findElements(locator);
+    }
+
+    /**
+     * Waits for element visibility with the default timeout.
+     *
+     * @param xpath the xpath expression to search for the element
+     * @return the WebElement if visible before timeout, otherwise throws an exception
+     */
+    protected WebElement waitForElementVisibility(final String xpath) {
+        return waitForElementVisibility(By.xpath(xpath));
+    }
+
+    /**
+     * Waits for element visibility with the default timeout.
+     *
+     * @param locator the By locator to search for the element
+     * @return the WebElement if visible before timeout, otherwise throws an exception
+     */
+    protected WebElement waitForElementVisibility(final By locator) {
+        return getWait(timeoutInSeconds)
+            .until(ExpectedConditions.visibilityOfElementLocated(locator));
+    }
+
+    /**
+     * Waits for element visibility with the provided timeout.
+     *
+     * @param locator the By locator to search for the element
+     * @param timeoutInSeconds the wait timeout in seconds
+     * @return the WebElement if visible before timeout, otherwise throws an exception
+     */
+    protected WebElement waitForElementVisibility(final By locator, final int timeoutInSeconds) {
+        return getWait(timeoutInSeconds)
+            .until(ExpectedConditions.visibilityOfElementLocated(locator));
+    }
+
+    /**
+     * Waits for element invisibility with the default timeout.
+     *
+     * @param locator the By locator to search for the element
+     * @return the WebElement if invisible before timeout, false otherwise
+     */
+    protected Boolean waitForElementInvisibility(final By locator) {
+        return getWait(timeoutInSeconds)
+            .until(ExpectedConditions.invisibilityOfElementLocated(locator));
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OnboardHeaderComponent.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OnboardHeaderComponent.java
new file mode 100644 (file)
index 0000000..5e82f76
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.OnboardHeaderComponent.XpathSelector.MAIN_DIV;
+import static org.openecomp.sdc.ci.tests.pages.OnboardHeaderComponent.XpathSelector.ONBOARD_TAB_DIV;
+import static org.openecomp.sdc.ci.tests.pages.OnboardHeaderComponent.XpathSelector.WORKSPACE_TAB_DIV;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+/**
+ * Handles the Onboard Header Component UI test actions
+ */
+public class OnboardHeaderComponent extends AbstractPageObject {
+
+    private WebElement wrappingElement;
+
+    public OnboardHeaderComponent(final WebDriver webDriver) {
+        super(webDriver);
+    }
+
+    @Override
+    public void isLoaded() {
+        wrappingElement = getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(MAIN_DIV.getXpath())));
+        getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(WORKSPACE_TAB_DIV.getXpath())));
+        getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(ONBOARD_TAB_DIV.getXpath())));
+    }
+
+    /**
+     * Clicks on the workspace tab.
+     */
+    public void clickOnWorkspaceTab() {
+        wrappingElement.findElement(By.xpath(WORKSPACE_TAB_DIV.getXpath()));
+    }
+
+    /**
+     * Clicks on the workspace tab.
+     */
+    public void clickOnOnboardTab() {
+        wrappingElement.findElement(By.xpath(ONBOARD_TAB_DIV.getXpath()));
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        MAIN_DIV("onboard-header", "//div[contains(@class, '%s')]"),
+        WORKSPACE_TAB_DIV("onboard-workspace-tab", "//div[@data-test-id='%s']"),
+        ONBOARD_TAB_DIV("onboard-onboard-tab", "//div[@data-test-id='%s']");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OnboardHomePage.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OnboardHomePage.java
new file mode 100644 (file)
index 0000000..22e4c17
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.OnboardHomePage.XpathSelector.ADD_NEW_VLM_BTN;
+import static org.openecomp.sdc.ci.tests.pages.OnboardHomePage.XpathSelector.ADD_NEW_VSP_BTN;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+/**
+ * Handles the Onboard Home Page UI test actions
+ */
+public class OnboardHomePage extends AbstractPageObject {
+
+    private final OnboardHeaderComponent onboardHeaderComponent;
+    private WebElement createNewVspBtn;
+
+    public OnboardHomePage(final WebDriver webDriver,
+                           final OnboardHeaderComponent onboardHeaderComponent) {
+        super(webDriver);
+        this.onboardHeaderComponent = onboardHeaderComponent;
+    }
+
+    @Override
+    public void isLoaded() {
+        onboardHeaderComponent.isLoaded();
+        createNewVspBtn = getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(ADD_NEW_VSP_BTN.getXpath())));
+        getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(ADD_NEW_VLM_BTN.getXpath())));
+    }
+
+    /**
+     * Clicks on the button create new vsp.
+     *
+     * @return returns the next vsp creation page object
+     */
+    public VspCreationModal clickOnCreateNewVsp() {
+        createNewVspBtn.click();
+        return new VspCreationModal(webDriver);
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        ADD_NEW_VSP_BTN("catalog-add-new-vsp", "//div[@data-test-id='%s']"),
+        ADD_NEW_VLM_BTN("catalog-add-new-vlm", "//div[@data-test-id='%s']");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/PageObject.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/PageObject.java
new file mode 100644 (file)
index 0000000..63b3b53
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+/**
+ * Represents represents a page or component in a html page
+ */
+@FunctionalInterface
+public interface PageObject {
+
+    /**
+     * Checks if the Page Object is loaded on the browser. Any problem during the checking should throw
+     * a custom RuntimeException.
+     */
+    void isLoaded();
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceCreatePage.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceCreatePage.java
new file mode 100644 (file)
index 0000000..5c9ec97
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.hamcrest.Matchers.equalToIgnoringCase;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.openecomp.sdc.ci.tests.pages.ResourceCreatePage.XpathSelector.FORM_LIFE_CYCLE_STATE;
+
+import org.openecomp.sdc.ci.tests.datatypes.LifeCycleStateEnum;
+import org.openecomp.sdc.ci.tests.utilities.LoaderHelper;
+import org.openecomp.sdc.ci.tests.utilities.NotificationHelper;
+import org.openecomp.sdc.ci.tests.utilities.NotificationHelper.NotificationType;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles the Resource Create Page UI actions
+ */
+public class ResourceCreatePage extends AbstractPageObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCreatePage.class);
+    private final LoaderHelper loaderHelper;
+    private final NotificationHelper notificationHelper;
+    private WebElement createBtn;
+
+    public ResourceCreatePage(final WebDriver webDriver, final LoaderHelper loaderHelper,
+                              final NotificationHelper notificationHelper) {
+        super(webDriver);
+        this.loaderHelper = loaderHelper;
+        this.notificationHelper = notificationHelper;
+        timeoutInSeconds = 5;
+    }
+
+    @Override
+    public void isLoaded() {
+        LOGGER.debug("Waiting for element visibility with xpath '{}'", FORM_LIFE_CYCLE_STATE.getXpath());
+        final WebElement lifeCycleState = waitForElementVisibility(FORM_LIFE_CYCLE_STATE.getXpath());
+        assertThat("Life cycle state should be as expected",
+            lifeCycleState.getText(), is(equalToIgnoringCase(LifeCycleStateEnum.IN_DESIGN.getValue())));
+        createBtn = getWait()
+            .until(ExpectedConditions.elementToBeClickable(By.xpath(XpathSelector.CREATE_BTN.getXpath())));
+    }
+
+    /**
+     * Creates the resource and wait for success notification.
+     */
+    public void createResource() {
+        createBtn.click();
+        loaderHelper.waitForLoader(60);
+        notificationHelper.waitForNotification(NotificationType.SUCCESS, 60);
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        CREATE_BTN("create/save", "//button[@data-tests-id='%s']"),
+        FORM_LIFE_CYCLE_STATE("formlifecyclestate", "//span[@data-tests-id='%s']");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceLeftSideMenu.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceLeftSideMenu.java
new file mode 100644 (file)
index 0000000..5153107
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.ResourceLeftSideMenu.XpathSelector.MAIN_DIV;
+import static org.openecomp.sdc.ci.tests.pages.ResourceLeftSideMenu.XpathSelector.PROPERTIES_ASSIGNMENT_MENU;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+/**
+ * Handles the Resource Page Left Side Menu UI actions
+ */
+public class ResourceLeftSideMenu extends AbstractPageObject {
+
+    private WebElement wrappingElement;
+
+    public ResourceLeftSideMenu(final WebDriver webDriver) {
+        super(webDriver);
+        timeoutInSeconds = 5;
+    }
+
+    @Override
+    public void isLoaded() {
+        wrappingElement = getWrappingElement();
+    }
+
+    /**
+     * Gets the enclosing element of the menu.
+     *
+     * @return the enclosing element
+     */
+    public WebElement getWrappingElement() {
+        return getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.className(MAIN_DIV.getId())));
+    }
+
+    /**
+     * Clicks on the properties assignment menu item.
+     *
+     * @return the next page object
+     */
+    public ResourcePropertiesAssignmentPage clickOnPropertiesAssignmentMenuItem() {
+        wrappingElement.findElement(By.xpath(PROPERTIES_ASSIGNMENT_MENU.getXpath())).click();
+        return new ResourcePropertiesAssignmentPage(webDriver);
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        MAIN_DIV("w-sdc-left-sidebar", "//div[@class='%s']"),
+        PROPERTIES_ASSIGNMENT_MENU("Properties AssignmentLeftSideMenu", "//div[@data-tests-id='%s']/button");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourcePropertiesAssignmentPage.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourcePropertiesAssignmentPage.java
new file mode 100644 (file)
index 0000000..433d79e
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage.XpathSelector.MAIN_DIV;
+import static org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage.XpathSelector.NO_DATA_MESSAGE;
+import static org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage.XpathSelector.PROPERTIES_TABLE;
+import static org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage.XpathSelector.SOFTWARE_VERSION_INPUT;
+import static org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage.XpathSelector.SOFTWARE_VERSION_PROPERTY_CHECKBOX;
+import static org.openecomp.sdc.ci.tests.pages.ResourcePropertiesAssignmentPage.XpathSelector.TITLE_DIV;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+/**
+ * Handles the Resource Properties Assignment Page UI actions
+ */
+public class ResourcePropertiesAssignmentPage extends AbstractPageObject {
+
+    private WebElement wrappingElement;
+
+    public ResourcePropertiesAssignmentPage(final WebDriver webDriver) {
+        super(webDriver);
+    }
+
+    @Override
+    public void isLoaded() {
+        wrappingElement = getWait(5)
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(MAIN_DIV.getXpath())));
+        getWait(5)
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(TITLE_DIV.getXpath())));
+    }
+
+    /**
+     * Gets the software_version property values.
+     *
+     * @return the list of software versions found
+     */
+    public List<String> getSoftwareVersionProperty() {
+        waitPropertiesToLoad();
+        final By swVersionCheckboxLocator = By.xpath(SOFTWARE_VERSION_PROPERTY_CHECKBOX.getXpath());
+        getWait(5).until(ExpectedConditions.visibilityOfElementLocated(swVersionCheckboxLocator));
+
+        final List<String> softwareVersionList = new ArrayList<>();
+        final List<WebElement> elements = wrappingElement.findElements(By.xpath(SOFTWARE_VERSION_INPUT.getXpath()));
+        for (final WebElement element : elements) {
+            softwareVersionList.add(element.getAttribute("value"));
+        }
+
+        return softwareVersionList;
+    }
+
+    /**
+     * Waits for the properties loading.
+     */
+    private void waitPropertiesToLoad() {
+        getWait(5)
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(PROPERTIES_TABLE.getXpath())));
+        getWait(5)
+            .until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(NO_DATA_MESSAGE.getXpath())));
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        MAIN_DIV("w-sdc-main-right-container", "//div[@class='%s']"),
+        TITLE_DIV("tab-title", "//div[contains(@class,'%s') and contains(text(), 'Properties Assignment')]"),
+        PROPERTIES_TABLE("properties-table", "//div[contains(@class,'%s')]"),
+        NO_DATA_MESSAGE("no-data", "//div[contains(@class,'%s') and text()='No data to display']"),
+        SOFTWARE_VERSION_PROPERTY_CHECKBOX("software_versions", "//checkbox[@data-tests-id='%s']"),
+        SOFTWARE_VERSION_INPUT("value-prop-software_versions.", "//input[starts-with(@data-tests-id,'%s')]");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/SoftwareProductOnboarding.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/SoftwareProductOnboarding.java
new file mode 100644 (file)
index 0000000..169ded4
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.ATTACHMENT_VIEW;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.BNT_SUBMIT;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.FILE_INPUT;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.NAV_BAR_GROUP_ITEM_ATTACHMENT;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.NAV_BAR_GROUP_NAME_XPATH;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.ONBOARDING_LOADER_DIV;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.PAGE_MAIN_DIV;
+import static org.openecomp.sdc.ci.tests.pages.SoftwareProductOnboarding.XpathSelector.SELECTED_NAV_BAR_GROUP_ITEM;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SoftwareProductOnboarding extends AbstractPageObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareProductOnboarding.class);
+    private static final String DIV_CLASS_XPATH_FORMAT = "//div[@class='%s']";
+    private static final String DIV_DATA_TEST_ID_XPATH_FORMAT = "//div[@data-test-id='%s']";
+    private final VspCommitModal vspCommitModal;
+    private WebElement wrappingElement;
+
+    public SoftwareProductOnboarding(final WebDriver webDriver,
+                                     final VspCommitModal vspCommitModal) {
+        super(webDriver);
+        this.vspCommitModal = vspCommitModal;
+        timeoutInSeconds = 5;
+    }
+
+    @Override
+    public void isLoaded() {
+        wrappingElement = getWrappingElement();
+    }
+
+    public String getResourceName() {
+        return wrappingElement.findElement(By.xpath(NAV_BAR_GROUP_NAME_XPATH.getXpath())).getText();
+    }
+
+    public void uploadFile(final String resourceFilePath) {
+        LOGGER.debug("Uploading file '{}'", resourceFilePath);
+        setInputValue(FILE_INPUT, resourceFilePath);
+    }
+
+    public void attachmentScreenIsLoaded() {
+        final String attachmentViewXpath = String.format("%s%s", PAGE_MAIN_DIV.getXpath(), ATTACHMENT_VIEW.getXpath());
+        waitForElementVisibility(By.xpath(attachmentViewXpath));
+        waitForElementInvisibility(By.xpath(ONBOARDING_LOADER_DIV.getXpath()));
+        final WebElement selectedNavBarGroupItem =
+            findSubElement(wrappingElement, SELECTED_NAV_BAR_GROUP_ITEM.getXpath());
+        final String selectedNavBarGroupItemTestId = selectedNavBarGroupItem.getAttribute("data-test-id");
+        assertThat("Attachment menu should be selected", selectedNavBarGroupItemTestId,
+            is(NAV_BAR_GROUP_ITEM_ATTACHMENT.getId()));
+    }
+
+    public void submit() {
+        findSubElement(wrappingElement, BNT_SUBMIT.getXpath()).click();
+        vspCommitModal.isLoaded();
+        vspCommitModal.fillCommentWithDefaulMessage();
+        vspCommitModal.submit();
+    }
+
+    public WebElement getWrappingElement() {
+        LOGGER.debug("Finding element with xpath '{}'", PAGE_MAIN_DIV.getXpath());
+        return waitForElementVisibility(PAGE_MAIN_DIV.getXpath());
+
+    }
+
+    public void setInputValue(final XpathSelector inputTestId, final String value) {
+        findSubElement(wrappingElement, inputTestId.getXpath()).sendKeys(value);
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        PAGE_MAIN_DIV("software-product-view", DIV_CLASS_XPATH_FORMAT),
+        UPLOAD_CSAR("upload-btn", "//input[@data-test-id='%s']"),
+        FILE_INPUT("fileInput", "//input[@name='%s']"),
+        NAV_BAR_GROUP_ITEM_ATTACHMENT("navbar-group-item-SOFTWARE_PRODUCT_ATTACHMENTS", DIV_DATA_TEST_ID_XPATH_FORMAT),
+        BNT_SUBMIT("vc-submit-btn", DIV_DATA_TEST_ID_XPATH_FORMAT),
+        NAV_BAR_GROUP_NAME_XPATH("navbar-group-name", DIV_DATA_TEST_ID_XPATH_FORMAT),
+        SELECTED_NAV_BAR_GROUP_ITEM("navigation-group-item-name selected", DIV_CLASS_XPATH_FORMAT),
+        ONBOARDING_LOADER_DIV("onboarding-loader-backdrop", DIV_CLASS_XPATH_FORMAT),
+        ATTACHMENT_VIEW("vsp-attachments-view", DIV_CLASS_XPATH_FORMAT);
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/TopNavComponent.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/TopNavComponent.java
new file mode 100644 (file)
index 0000000..d16270f
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.TopNavComponent.XpathSelector.ARROW_DROPDOWN;
+import static org.openecomp.sdc.ci.tests.pages.TopNavComponent.XpathSelector.MAIN_MENU_ONBOARD_BTN;
+import static org.openecomp.sdc.ci.tests.pages.TopNavComponent.XpathSelector.NAV;
+import static org.openecomp.sdc.ci.tests.pages.TopNavComponent.XpathSelector.REPOSITORY_ICON;
+import static org.openecomp.sdc.ci.tests.pages.TopNavComponent.XpathSelector.SUB_MENU_BUTTON_HOME;
+
+import java.util.List;
+import org.openecomp.sdc.ci.tests.execute.setup.DriverFactory;
+import org.openecomp.sdc.ci.tests.utilities.GeneralUIUtils;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles the Top Navigation Component UI actions
+ */
+public class TopNavComponent extends AbstractPageObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(TopNavComponent.class);
+
+    private WebElement wrappingElement;
+    private By navLocator = By.xpath(NAV.getXpath());
+
+    public TopNavComponent(final WebDriver webDriver) {
+        super(webDriver);
+        timeoutInSeconds = 5;
+    }
+
+    @Override
+    public void isLoaded() {
+        wrappingElement = getWrappingElement();
+    }
+
+    /**
+     * Gets the enclosing element of the component.
+     *
+     * @return the enclosing element
+     */
+    public WebElement getWrappingElement() {
+        LOGGER.debug("Finding element with xpath '{}'", NAV.getXpath());
+        return waitForElementVisibility(navLocator);
+    }
+
+    /**
+     * Clicks on home link inside the first breadcrumb arrow.
+     */
+    public void clickOnHome() {
+        hoverToBreadcrumbArrow(0);
+        final By homeButtonLocator = By.xpath(SUB_MENU_BUTTON_HOME.getXpath());
+        getWait().until(ExpectedConditions.visibilityOfElementLocated(homeButtonLocator));
+        getWait().until(ExpectedConditions.elementToBeClickable(homeButtonLocator)).click();
+        getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(REPOSITORY_ICON.getXpath())));
+    }
+
+    /**
+     * Clicks on the VSP repository icon.
+     *
+     * @return the next page object
+     */
+    public VspRepositoryModalComponent clickOnRepositoryIcon() {
+        wrappingElement.findElement(By.xpath(REPOSITORY_ICON.getXpath())).click();
+        return new VspRepositoryModalComponent(webDriver);
+    }
+
+    /**
+     * Clicks on the Onboard button.
+     *
+     * @return the next page object
+     */
+    public OnboardHomePage clickOnOnboard() {
+        wrappingElement.findElement(By.xpath(MAIN_MENU_ONBOARD_BTN.getXpath())).click();
+        return new OnboardHomePage(DriverFactory.getDriver(), new OnboardHeaderComponent(DriverFactory.getDriver()));
+    }
+
+    /**
+     * Hover to a breadcrumb arrow of the given position.
+     *
+     * @param arrowPosition the position of the arrow from left to right
+     * @return the hovered breadcrumb arrow element
+     */
+    public WebElement hoverToBreadcrumbArrow(final int arrowPosition) {
+        final Actions actions = new Actions(GeneralUIUtils.getDriver());
+        final List<WebElement> arrowElementList = getWait()
+            .until(
+                ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath(ARROW_DROPDOWN.getXpath())));
+        final WebElement selectedArrowElement = arrowElementList.get(arrowPosition);
+        actions.moveToElement(selectedArrowElement).perform();
+        return selectedArrowElement;
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        NAV("top-nav", "//nav[@class='%s']"),
+        SUB_MENU_BUTTON_HOME("sub-menu-button-home", "//*[@data-tests-id='%s']"),
+        ARROW_DROPDOWN("triangle-dropdown", "//li[contains(@class, '%s')]"),
+        MAIN_MENU_ONBOARD_BTN("main-menu-button-onboard", "//a[@data-tests-id='%s']"),
+        REPOSITORY_ICON("repository-icon", "//div[@data-tests-id='%s']");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspCommitModal.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspCommitModal.java
new file mode 100644 (file)
index 0000000..7a6aa7f
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.VspCommitModal.XpathSelector.COMMIT_AND_SUBMIT_BTN;
+import static org.openecomp.sdc.ci.tests.pages.VspCommitModal.XpathSelector.COMMIT_COMMENT_TXT;
+import static org.openecomp.sdc.ci.tests.pages.VspCommitModal.XpathSelector.MODAL_CANCEL_BTN;
+import static org.openecomp.sdc.ci.tests.pages.VspCommitModal.XpathSelector.MODAL_DIV;
+import static org.openecomp.sdc.ci.tests.pages.VspCommitModal.XpathSelector.SUCCESS_MODAL_DIV;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles the VSP Commit Modal UI actions
+ */
+public class VspCommitModal extends AbstractPageObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(VspCommitModal.class);
+
+    private WebElement wrappingElement;
+
+    public VspCommitModal(final WebDriver webDriver) {
+        super(webDriver);
+    }
+
+    public void isLoaded() {
+        LOGGER.debug("Finding element with xpath '{}'", MODAL_DIV.getXpath());
+        wrappingElement = waitForElementVisibility(MODAL_DIV.getXpath());
+    }
+
+    /**
+     * Fills the comment text area with a default message.
+     */
+    public void fillCommentWithDefaulMessage() {
+        final WebElement commentTxt = wrappingElement.findElement(By.xpath(COMMIT_COMMENT_TXT.getXpath()));
+        commentTxt.sendKeys("First VSP version");
+    }
+
+    /**
+     * Clicks on the modal submit and confirms success.
+     */
+    public void submit() {
+        final WebElement commitAndSubmitBtn = wrappingElement.findElement(By.xpath(COMMIT_AND_SUBMIT_BTN.getXpath()));
+        commitAndSubmitBtn.click();
+        confirmSuccess();
+    }
+
+    /**
+     * Confirms the success of the modal submission.
+     */
+    private void confirmSuccess() {
+        final WebElement successModal = getWait()
+            .until(ExpectedConditions.visibilityOfElementLocated(By.xpath(SUCCESS_MODAL_DIV.getXpath())));
+        successModal.findElement(By.xpath(MODAL_CANCEL_BTN.getXpath())).click();
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        MODAL_DIV("sdc-modal-type-custom", "//div[contains(@class, '%s')]"),
+        COMMIT_AND_SUBMIT_BTN("form-submit-button", "//button[@data-test-id='%s']"),
+        COMMIT_COMMENT_TXT("commit-comment-text", "//textarea[@data-test-id='%s']"),
+        SUCCESS_MODAL_DIV("sdc-modal-type-info", "//div[contains(@class, '%s')]"),
+        MODAL_CANCEL_BTN("sdc-modal-cancel-button", "//button[@data-test-id='%s']");
+
+        private final String id;
+        private final String xpath;
+
+        XpathSelector(final String id, final String xpath) {
+            this.id = id;
+            this.xpath = xpath;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpath, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspCreationModal.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspCreationModal.java
new file mode 100644 (file)
index 0000000..efd26b9
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.openecomp.sdc.ci.tests.pages.VspCreationModal.XpathSelector.METHOD_RADIO;
+import static org.openecomp.sdc.ci.tests.pages.VspCreationModal.XpathSelector.MODAL_XPATH;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.Select;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles the VSP Creation Modal UI actions
+ */
+public class VspCreationModal extends AbstractPageObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(VspCreationModal.class);
+
+    private WebElement wrappingElement;
+
+    public VspCreationModal(final WebDriver webDriver) {
+        super(webDriver);
+        timeoutInSeconds = 5;
+    }
+
+    @Override
+    public void isLoaded() {
+        LOGGER.debug("Finding element with xpath '{}'", MODAL_XPATH.getXpath());
+        wrappingElement = waitForElementVisibility(MODAL_XPATH.getXpath());
+    }
+
+    /**
+     * Fills the creation form for the given vsp name.
+     *
+     * @param vspName the name of the Vendor Software Product
+     */
+    public void fillCreationForm(final String vspName) {
+        fillName(vspName);
+        selectVendorFirstVendor();
+        selectCategory("resourceNewCategory.network l4+.common network resources");
+        fillDescription(vspName);
+        selectNetworkPackageOnboardingProcedure();
+    }
+
+    /**
+     * Clicks on the create button.
+     *
+     * @return the next page object
+     */
+    public SoftwareProductOnboarding clickOnCreate() {
+        clickElement(XpathSelector.CREATE_BTN);
+        return new SoftwareProductOnboarding(webDriver, new VspCommitModal(webDriver));
+    }
+
+    /**
+     * Fills the VSP name.
+     *
+     * @param vspName the VSP name
+     */
+    public void fillName(final String vspName) {
+        setInputValue(XpathSelector.NAME_TXT, vspName);
+    }
+
+    /**
+     * Fills the VSP description.
+     *
+     * @param description the VSP description
+     */
+    public void fillDescription(final String description) {
+        setInputValue(XpathSelector.DESCRIPTION_TXT, description);
+    }
+
+    /**
+     * Selects the first vendor in the vendor list.
+     */
+    public void selectVendorFirstVendor() {
+        setSelectIndex(XpathSelector.VENDOR_SELECT, 1);
+    }
+
+    /**
+     * Selects a category in the category list based on the option value.
+     *
+     * @param categoryOptionValue the option value
+     */
+    public void selectCategory(final String categoryOptionValue) {
+        setSelectValue(XpathSelector.CATEGORY_SELECT, categoryOptionValue);
+    }
+
+    /**
+     * Selects the network package onboarding procedure option.
+     */
+    public void selectNetworkPackageOnboardingProcedure() {
+        wrappingElement.findElement(By.xpath(METHOD_RADIO.getXpath())).click();
+    }
+
+    private void setInputValue(final XpathSelector inputTestId, final String value) {
+        findSubElement(wrappingElement, By.xpath(inputTestId.getXpath())).sendKeys(value);
+    }
+
+    private void setSelectIndex(final XpathSelector inputTestId, final int index) {
+        new Select(findSubElement(wrappingElement, By.xpath(inputTestId.getXpath()))).selectByIndex(index);
+    }
+
+    private void setSelectValue(final XpathSelector inputTestId, final String value) {
+        new Select(findSubElement(wrappingElement, By.xpath(inputTestId.getXpath()))).selectByValue(value);
+    }
+
+    private void clickElement(final XpathSelector elementTestId) {
+        wrappingElement.findElement(By.xpath(elementTestId.getXpath())).click();
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        MODAL_XPATH("software-product-creation-page", "//div[@class='%s']"),
+        NAME_TXT("new-vsp-name", "//input[@data-test-id='%s']"),
+        VENDOR_SELECT("new-vsp-vendor", "//select[@data-test-id='%s']"),
+        CATEGORY_SELECT("new-vsp-category", "//select[@data-test-id='%s']"),
+        DESCRIPTION_TXT("new-vsp-description", "//textarea[@data-test-id='%s']"),
+        METHOD_RADIO("new-vsp-creation-procedure-heat", "//input[@data-test-id='%s']/parent::label"),
+        CREATE_BTN("form-submit-button", "//*[@data-test-id='%s']");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspRepositoryModalComponent.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspRepositoryModalComponent.java
new file mode 100644 (file)
index 0000000..b7611c6
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.pages;
+
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+import static org.openecomp.sdc.ci.tests.pages.VspRepositoryModalComponent.XpathSelector.IMPORT_VSP_BTN;
+import static org.openecomp.sdc.ci.tests.pages.VspRepositoryModalComponent.XpathSelector.MODAL_DIV;
+import static org.openecomp.sdc.ci.tests.pages.VspRepositoryModalComponent.XpathSelector.RESULTS_CONTAINER_DIV;
+import static org.openecomp.sdc.ci.tests.pages.VspRepositoryModalComponent.XpathSelector.SEARCH_TXT;
+
+import java.util.List;
+import org.openecomp.sdc.ci.tests.utilities.GeneralUIUtils;
+import org.openecomp.sdc.ci.tests.utilities.LoaderHelper;
+import org.openecomp.sdc.ci.tests.utilities.NotificationHelper;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles the VSP Repository Modal UI actions
+ */
+public class VspRepositoryModalComponent extends AbstractPageObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(VspRepositoryModalComponent.class);
+
+    private WebElement wrappingElement;
+
+    public VspRepositoryModalComponent(final WebDriver webDriver) {
+        super(webDriver);
+        timeoutInSeconds = 5;
+    }
+
+    @Override
+    public void isLoaded() {
+        wrappingElement = getWrappingElement();
+        GeneralUIUtils.ultimateWait();
+        final List<WebElement> vspResultList = wrappingElement
+            .findElements(By.className(RESULTS_CONTAINER_DIV.getId()));
+        assertThat("VSP Repository should contain at least one result", vspResultList, is(not(empty())));
+    }
+
+    /**
+     * Clicks on the Import Vsp button of the given repository item position in the list.
+     *
+     * @param listPosition the position of the element in the VSP list, starting from 1
+     * @return the next page object
+     */
+    public ResourceCreatePage clickOnImportVsp(final int listPosition) {
+        final List<WebElement> vspResultList =
+            findSubElements(wrappingElement, By.className(RESULTS_CONTAINER_DIV.getId()));
+        vspResultList.get(listPosition).click();
+        findSubElement(wrappingElement, By.xpath(IMPORT_VSP_BTN.getXpath())).click();
+        return new ResourceCreatePage(webDriver, new LoaderHelper(), new NotificationHelper());
+    }
+
+    /**
+     * Searches for a VSP in the repository list.
+     *
+     * @param vspName the VSP name to search
+     */
+    public void searchForVSP(final String vspName) {
+        final WebElement searchTxtElement = findSubElement(wrappingElement, By.xpath(SEARCH_TXT.getXpath()));
+        searchTxtElement.sendKeys(vspName);
+        GeneralUIUtils.ultimateWait();
+    }
+
+    /**
+     * Gets the enclosing element of the modal.
+     *
+     * @return the enclosing element
+     */
+    public WebElement getWrappingElement() {
+        LOGGER.debug("Finding element with xpath '{}'", MODAL_DIV.getXpath());
+        return waitForElementVisibility(MODAL_DIV.getXpath());
+    }
+
+    /**
+     * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
+     */
+    public enum XpathSelector {
+        MODAL_DIV("modalOnboarding", "//div[@modal='%s']"),
+        SEARCH_TXT("onboarding-search", "//input[@data-tests-id='%s']"),
+        IMPORT_VSP_BTN("import-csar", "//span[@data-tests-id='%s']"),
+        RESULTS_CONTAINER_DIV("flex-container", "//div[contains(@class,'%s']");
+
+        private final String id;
+        private final String xpathFormat;
+
+        XpathSelector(final String id, final String xpathFormat) {
+            this.id = id;
+            this.xpathFormat = xpathFormat;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpathFormat, id);
+        }
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/LoaderHelper.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/LoaderHelper.java
new file mode 100644 (file)
index 0000000..494c20a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.utilities;
+
+import org.openecomp.sdc.ci.tests.execute.setup.DriverFactory;
+import org.openqa.selenium.By;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+public class LoaderHelper {
+
+    private final By locator = By.className("tlv-loader");
+
+    public void waitForLoader(final int timeout) {
+        waitForLoaderVisibility(5);
+        waitForLoaderInvisibility(timeout);
+    }
+
+    private void waitForLoaderVisibility(final int timeout) {
+        getWait(timeout)
+            .until(ExpectedConditions.visibilityOfElementLocated(locator));
+    }
+
+    private void waitForLoaderInvisibility(int timeout) {
+        getWait(timeout).until(ExpectedConditions.invisibilityOfElementLocated(locator));
+    }
+
+    private WebDriverWait getWait(final int timeout) {
+        return new WebDriverWait(DriverFactory.getDriver(), timeout);
+    }
+
+}
diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/NotificationHelper.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/NotificationHelper.java
new file mode 100644 (file)
index 0000000..89ff4e7
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 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.openecomp.sdc.ci.tests.utilities;
+
+import static org.openecomp.sdc.ci.tests.utilities.NotificationHelper.XpathSelector.MAIN_CONTAINER_DIV;
+import static org.openecomp.sdc.ci.tests.utilities.NotificationHelper.XpathSelector.MESSAGE_CONTENT_DIV;
+import static org.openecomp.sdc.ci.tests.utilities.NotificationHelper.XpathSelector.MESSAGE_SUCCESS_DIV;
+
+import org.openecomp.sdc.ci.tests.execute.setup.DriverFactory;
+import org.openqa.selenium.By;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NotificationHelper {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(NotificationHelper.class);
+
+    public void waitForNotification(final NotificationType notificationType, final int timeout) {
+        final By messageLocator = getMessageLocator(notificationType);
+        waitForVisibility(messageLocator, timeout);
+        waitForInvisibility(messageLocator, timeout);
+    }
+
+    private By getMessageLocator(final NotificationType notificationType) {
+        return By.xpath(getMessageXpath(notificationType));
+    }
+
+    private String getMessageXpath(final NotificationType notificationType) {
+        if (notificationType == NotificationType.SUCCESS) {
+            return String.format("%s%s%s", MAIN_CONTAINER_DIV.getXpath(), MESSAGE_CONTENT_DIV.getXpath(), MESSAGE_SUCCESS_DIV.getXpath());
+        }
+
+        LOGGER.warn("Xpath for NotificationType {} not yet implemented. Returning empty Xpath.", notificationType);
+        return "";
+    }
+
+    private void waitForVisibility(By messageLocator, final int timeout) {
+        getWait(timeout)
+            .until(ExpectedConditions.visibilityOfElementLocated(messageLocator));
+    }
+
+    private void waitForInvisibility(By messageLocator, int timeout) {
+        getWait(timeout)
+            .until(ExpectedConditions.invisibilityOfElementLocated(messageLocator));
+    }
+
+    private WebDriverWait getWait(final int timeout) {
+        return new WebDriverWait(DriverFactory.getDriver(), timeout);
+    }
+
+    public enum XpathSelector {
+        MAIN_CONTAINER_DIV("notification-container", "//div[@class='%s']"),
+        MESSAGE_CONTENT_DIV("msg-content", "//div[@class='%s']"),
+        MESSAGE_SUCCESS_DIV("message", "//div[contains(@class, '%s') and contains(text(),'successfully')]");
+
+        private final String id;
+        private final String xpath;
+
+        XpathSelector(String id, String xpath) {
+            this.id = id;
+            this.xpath = xpath;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public String getXpath() {
+            return String.format(xpath, id);
+        }
+    }
+
+    public enum NotificationType {
+        SUCCESS;
+    }
+
+}
index 245524d..0ba4a17 100644 (file)
@@ -7,27 +7,23 @@
 
   <test name="uiSanity">
     <classes>
-
       <class name="org.openecomp.sdc.ci.tests.execute.sanity.Vf">
         <methods>
           <include name="changeInstanceNameInVfTest"/>
         </methods>
       </class>
-
       <class name="org.openecomp.sdc.ci.tests.execute.sanity.Service">
         <methods>
           <include name="updateService"/>
         </methods>
       </class>
-
-
       <class name="org.openecomp.sdc.ci.tests.execute.sanity.OnboardingFlowsUi">
         <methods>
           <include name="onapOnboardVNFflow"/>
           <include name="onapOnboardVSPValidationsSanityFlow"/>
+          <include name="onboardPNFSoftwareInformationFlow"/>
         </methods>
       </class>
-
     </classes>
   </test>
 </suite>