aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authormarian.vaclavik@telekom.com <marian.vaclavik@telekom.com>2023-07-31 10:59:39 +0200
committermarian.vaclavik@telekom.com <marian.vaclavik@telekom.com>2023-08-08 09:50:35 +0200
commit1c4023ccc06e633233ed642eb9d1ac85e82feaf0 (patch)
treed1b42076f13075d4bc7255120a5934f753774559 /src
parentc38f1100b43a48a9f86bc50c2e560ae94d15956a (diff)
Initial upload of E2E test project.HEADmontrealmaster
Issue-ID: PORTALNG-35 Change-Id: I606b3f265dfdb98d7eb9cfd8ab021e2895ee5152 Signed-off-by: marian.vaclavik@telekom.com <marian.vaclavik@telekom.com>
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/onap/portalng/e2e/RunUiTests.java58
-rw-r--r--src/main/java/org/onap/portalng/e2e/helpers/BeforeAfter.java31
-rw-r--r--src/main/java/org/onap/portalng/e2e/helpers/CommonUtils.java34
-rw-r--r--src/main/java/org/onap/portalng/e2e/helpers/ConfigFileReader.java62
-rw-r--r--src/main/java/org/onap/portalng/e2e/helpers/SerenitySessionVariable.java51
-rw-r--r--src/main/java/org/onap/portalng/e2e/helpers/UiSessionVariables.java24
-rw-r--r--src/main/java/org/onap/portalng/e2e/hooks/Hooks.java41
-rw-r--r--src/main/java/org/onap/portalng/e2e/hooks/SelenideConfiguration.java55
-rw-r--r--src/main/java/org/onap/portalng/e2e/pages/LoginPage.java39
-rw-r--r--src/main/java/org/onap/portalng/e2e/pages/MainPage.java34
-rw-r--r--src/main/java/org/onap/portalng/e2e/pages/PageWithTable.java31
-rw-r--r--src/main/java/org/onap/portalng/e2e/pages/PopUpDialogPage.java32
-rw-r--r--src/main/java/org/onap/portalng/e2e/pages/UserAdministrationPage.java84
-rw-r--r--src/main/java/org/onap/portalng/e2e/step_definitions/common/CommonStepDef.java43
-rw-r--r--src/main/java/org/onap/portalng/e2e/step_definitions/login/LoginStepDef.java65
-rw-r--r--src/main/java/org/onap/portalng/e2e/step_definitions/main/MainStepDef.java46
-rw-r--r--src/main/java/org/onap/portalng/e2e/step_definitions/user_administration/UserAdministrationStepDef.java132
-rw-r--r--src/main/java/org/onap/portalng/e2e/steps/common/CommonSteps.java92
-rw-r--r--src/main/java/org/onap/portalng/e2e/steps/common/TableSteps.java95
-rw-r--r--src/main/java/org/onap/portalng/e2e/steps/login/LoginSteps.java61
-rw-r--r--src/main/java/org/onap/portalng/e2e/steps/main/MainSteps.java42
-rw-r--r--src/main/java/org/onap/portalng/e2e/steps/user_administration/UserAdministrationSteps.java282
-rw-r--r--src/main/java/org/onap/portalng/e2e/types/Button.java27
-rw-r--r--src/main/java/org/onap/portalng/e2e/types/Page.java27
-rw-r--r--src/main/java/org/onap/portalng/e2e/types/UserRole.java36
-rw-r--r--src/main/resources/test-local.properties20
-rw-r--r--src/main/resources/test-remote.properties20
-rw-r--r--src/test/resources/cucumber.properties20
-rw-r--r--src/test/resources/features/login.feature32
-rw-r--r--src/test/resources/features/user_administration.feature121
30 files changed, 1737 insertions, 0 deletions
diff --git a/src/main/java/org/onap/portalng/e2e/RunUiTests.java b/src/main/java/org/onap/portalng/e2e/RunUiTests.java
new file mode 100644
index 0000000..159d575
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/RunUiTests.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e;
+
+import com.codeborne.selenide.Configuration;
+import com.codeborne.selenide.logevents.SelenideLogger;
+import io.cucumber.junit.CucumberOptions;
+import io.qameta.allure.selenide.AllureSelenide;
+import net.serenitybdd.cucumber.CucumberWithSerenity;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+
+@RunWith(CucumberWithSerenity.class)
+@CucumberOptions(
+ glue = {"org.onap.portalng.e2e.step_definitions"},
+ plugin = {"pretty", "io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm"},
+ stepNotifications = true,
+ monochrome = true,
+ features = {"src/test/resources/features"},
+ snippets = CucumberOptions.SnippetType.CAMELCASE)
+public class RunUiTests {
+
+ @BeforeClass
+ public static void setupAllureReports() {
+
+ SelenideLogger.addListener("AllureSelenide", new AllureSelenide()
+ .screenshots(true)
+ .savePageSource(false)
+ );
+ Configuration.headless = true;
+ Configuration.browser = "chrome";
+ Configuration.holdBrowserOpen = false;
+ Configuration.reportsFolder = "target/surefire-reports";
+ }
+
+ @AfterClass
+ public static void tear() {
+ SelenideLogger.removeListener("AllureSelenide");
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/helpers/BeforeAfter.java b/src/main/java/org/onap/portalng/e2e/helpers/BeforeAfter.java
new file mode 100644
index 0000000..5649fe1
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/helpers/BeforeAfter.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.helpers;
+
+import io.cucumber.java.After;
+import org.onap.portalng.e2e.steps.user_administration.UserAdministrationSteps;
+
+public class BeforeAfter {
+
+ @After("@delete_user")
+ public void deleteUserAfterTest() {
+ UserAdministrationSteps.deleteUser(UiSessionVariables.USERNAME.get());
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/helpers/CommonUtils.java b/src/main/java/org/onap/portalng/e2e/helpers/CommonUtils.java
new file mode 100644
index 0000000..a316439
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/helpers/CommonUtils.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.helpers;
+
+import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.SelenideElement;
+
+import static com.codeborne.selenide.Condition.visible;
+
+public class CommonUtils {
+ public static void checkTextOfElement(SelenideElement element, String text) {
+ element.shouldHave(Condition.text(text));
+ }
+ public static void checkPresenceOfElement(SelenideElement element) {
+ element.shouldBe(visible);
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/helpers/ConfigFileReader.java b/src/main/java/org/onap/portalng/e2e/helpers/ConfigFileReader.java
new file mode 100644
index 0000000..681b191
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/helpers/ConfigFileReader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.helpers;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+public class ConfigFileReader {
+
+ private final Properties properties;
+ private String propertyFileName= "test-local.properties";
+
+
+ public ConfigFileReader(String fileName) {
+ if(fileName != null) this.propertyFileName = fileName;
+ BufferedReader reader;
+ try {
+ ClassLoader classLoader = this.getClass().getClassLoader();
+ try{
+ reader = new BufferedReader(new FileReader(classLoader.getResource(propertyFileName).getFile()));
+ }catch (FileNotFoundException fileNotFoundException){
+ fileNotFoundException.printStackTrace();
+ throw new FileNotFoundException("Configuration file not found. Check your PORTAL_ENV variable.");
+ }
+ properties = new Properties();
+ try {
+ properties.load(reader);
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new RuntimeException("Configuration.properties not found at " + propertyFileName + "Check your PORTAL_ENV variable.");
+ }
+ }
+
+ public Properties getProperties() {
+ if (properties != null) return properties;
+ else throw new RuntimeException("Properties file: " + propertyFileName + " not found. Check your PORTAL_ENV variable.");
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/helpers/SerenitySessionVariable.java b/src/main/java/org/onap/portalng/e2e/helpers/SerenitySessionVariable.java
new file mode 100644
index 0000000..77ebef7
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/helpers/SerenitySessionVariable.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.helpers;
+
+import net.serenitybdd.core.Serenity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+public interface SerenitySessionVariable {
+
+ Logger log = LoggerFactory.getLogger(SerenitySessionVariable.class);
+
+ String name();
+ default <T> T get() {
+ final Optional<T> maybe = getOptional();
+ if (!maybe.isPresent()) {
+ throw new NoSuchElementException("No value present for: " + name());
+ }
+ return maybe.get();
+ }
+
+ default <T> Optional<T> getOptional() {
+ final T value = Serenity.sessionVariableCalled(this);
+ return Optional.ofNullable(value);
+ }
+
+ default <T> void set(T value) {
+ log.info("Setting {} to {}", this, value);
+ Serenity.setSessionVariable(this).to(value);
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/helpers/UiSessionVariables.java b/src/main/java/org/onap/portalng/e2e/helpers/UiSessionVariables.java
new file mode 100644
index 0000000..b7d6bf5
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/helpers/UiSessionVariables.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.helpers;
+
+public enum UiSessionVariables implements SerenitySessionVariable {
+ USERNAME
+}
diff --git a/src/main/java/org/onap/portalng/e2e/hooks/Hooks.java b/src/main/java/org/onap/portalng/e2e/hooks/Hooks.java
new file mode 100644
index 0000000..76f7b75
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/hooks/Hooks.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.hooks;
+
+import com.codeborne.selenide.Configuration;
+import com.codeborne.selenide.WebDriverRunner;
+import io.cucumber.java.AfterAll;
+import io.cucumber.java.Before;
+
+public class Hooks {
+ @Before
+ public void BeforeScenario() {
+ SelenideConfiguration.getBrowser();
+ Configuration.holdBrowserOpen = true;
+ Configuration.baseUrl = SelenideConfiguration.getBaseUrl();
+ Configuration.reportsFolder = "target/surefire-reports";
+ }
+
+ @AfterAll
+ public static void AfterAll() {
+ WebDriverRunner.closeWindow();
+ SelenideConfiguration.closeSession();
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/hooks/SelenideConfiguration.java b/src/main/java/org/onap/portalng/e2e/hooks/SelenideConfiguration.java
new file mode 100644
index 0000000..b9788a8
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/hooks/SelenideConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.hooks;
+
+import com.codeborne.selenide.Configuration;
+import com.codeborne.selenide.WebDriverRunner;
+import org.onap.portalng.e2e.helpers.ConfigFileReader;
+
+import java.util.Properties;
+
+import static java.lang.Boolean.parseBoolean;
+
+public class SelenideConfiguration {
+
+ private static final String REPORTS_FOLDER = "target";
+ private static final Properties testProperties = new ConfigFileReader(System.getenv("PORTAL_ENV")).getProperties();
+
+ public static String getBaseUrl() {
+ if (System.getenv("PORTAL_BASE_URL") != null) {
+ testProperties.setProperty("baseUrl", System.getenv("PORTAL_BASE_URL"));
+ }
+ return testProperties.getProperty("baseUrl");
+ }
+
+ public static void getBrowser() {
+ String browser = System.getProperty("selenide.browser", "chrome");
+ boolean headless = parseBoolean(System.getProperty("selenide.headless", "false"));
+
+ Configuration.browser = browser;
+ Configuration.headless = headless;
+ Configuration.screenshots = true;
+ Configuration.reportsFolder = REPORTS_FOLDER;
+ }
+
+ public static void closeSession() {
+ WebDriverRunner.closeWebDriver();
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/pages/LoginPage.java b/src/main/java/org/onap/portalng/e2e/pages/LoginPage.java
new file mode 100644
index 0000000..6e57cfe
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/pages/LoginPage.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.pages;
+
+import org.openqa.selenium.By;
+
+public class LoginPage {
+
+ public static final By SIGN_IN_BTN = By.id("kc-login");
+ public static final By USERNAME_LBL = By.xpath("//label[contains(text(),'Username or email')]");
+ public static final By PASSWORD_LBL = By.xpath("//label[contains(text(),'Password')]");
+ public static final By USERNAME_INPUT = By.id("username");
+ public static final By PASSWORD_INPUT = By.id("password");
+
+ public static final By CURRENT_PAGE_SPAN = By.xpath("//span[@aria-current='page']");
+ public static final By CURRENT_PAGE_HEADING_TITLE = By.xpath("//h2[@class='qa_title']");
+
+ public static final By DROPDOWN_MENU = By.id("dropdownMenu");
+ public static final By LOGOUT_BUTTON = By.xpath("//button[contains(text(), \"Logout\")]");
+ public static final By INPUT_ERROR_SPAN = By.id("input-error");
+
+}
diff --git a/src/main/java/org/onap/portalng/e2e/pages/MainPage.java b/src/main/java/org/onap/portalng/e2e/pages/MainPage.java
new file mode 100644
index 0000000..3d91bb9
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/pages/MainPage.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.pages;
+
+import org.openqa.selenium.By;
+
+public class MainPage {
+
+ public static final By NAV_LINKS = By.xpath("//a[@class='nav-link']");
+ public static final By SPINNER = By.xpath("//div[contains(@class, 'loading-spinner')]");
+
+ public static final By DASHBOARD_BTN = By.className("qa_menu_home");
+ public static final By APP_STARTER_BTN = By.className("qa_menu_app_starter");
+ public static final By USERS_BTN = By.className("qa_menu_users");
+
+}
+
diff --git a/src/main/java/org/onap/portalng/e2e/pages/PageWithTable.java b/src/main/java/org/onap/portalng/e2e/pages/PageWithTable.java
new file mode 100644
index 0000000..941c63f
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/pages/PageWithTable.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.pages;
+
+import org.openqa.selenium.By;
+
+public class PageWithTable {
+
+ public static final By PAGINATION = By.xpath("//ul[contains(@class, 'pagination')]");
+ public static final By NEXT_PAGE = By.xpath("//ul[contains(@class, 'pagination')]//li[last()-1]");
+ public static final By TABLE_ROWS = By.xpath("//table//tbody/tr");
+ public static final By ROW_CELLS = By.xpath("td");
+ public static final By ROW_DELETE_BUTTON = By.xpath("td//button[contains(@class, 'qa_delete_button')]");
+}
diff --git a/src/main/java/org/onap/portalng/e2e/pages/PopUpDialogPage.java b/src/main/java/org/onap/portalng/e2e/pages/PopUpDialogPage.java
new file mode 100644
index 0000000..dcb9b9a
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/pages/PopUpDialogPage.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.pages;
+
+import org.openqa.selenium.By;
+
+public class PopUpDialogPage {
+ public static final By DIALOG_HEADER = By.className("qa_modal_header");
+ public static final By DIALOG_BODY = By.className("qa_modal_body");
+ public static final By DIALOG_APPLY_BUTTON = By.className("qa_apply_button");
+ public static final By DIALOG_CANCEL_BUTTON = By.className("qa_cancel_button");
+ public static final By ALERT_SUCCESS = By.className("alert-success");
+ public static final By ALERT_ERROR = By.className("alert-error");
+ public static final By ALERT_WARNING = By.className("alert-danger");
+}
diff --git a/src/main/java/org/onap/portalng/e2e/pages/UserAdministrationPage.java b/src/main/java/org/onap/portalng/e2e/pages/UserAdministrationPage.java
new file mode 100644
index 0000000..77fd534
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/pages/UserAdministrationPage.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.pages;
+
+import org.openqa.selenium.By;
+
+public class UserAdministrationPage {
+
+
+ //ALERT
+ public static final By ALERT_DANGER = By.className("alert-danger");
+ public static final By ALERT_SUCCESS = By.className("alert-success");
+
+ //TITLES
+ public static final By TITLE_H2 = By.tagName("h2");
+ public static final By TITLE_H4 = By.tagName("h4");
+ public static final By TITLE_H5 = By.tagName("h5");
+
+
+ //BUTTONS
+ public static final By BUTTON_CREATE = By.className("qa_create_button");
+ public static final By BUTTON_CANCEL = By.className("qa_submit_cancel");
+ public static final By BUTTON_SAVE = By.className("qa_submit_button");
+ public static final By BUTTON_EDIT = By.className("qa_edit_button");
+
+ //LABELS
+ public static final By LABEL_ID = By.xpath("//label[@for = 'id']");
+ public static final By LABEL_USERNAME = By.xpath("//label[@for = 'username']");
+ public static final By LABEL_EMAIL = By.xpath("//label[@for = 'email']");
+ public static final By LABEL_FIRST_NAME = By.xpath("//label[@for = 'firstName']");
+ public static final By LABEL_LAST_NAME = By.xpath("//label[@for = 'lastName']");
+ //INPUT
+ public static final By INPUT_ID = By.xpath("//input[@id = 'id']");
+ public static final By INPUT_USERNAME = By.xpath("//input[@id = 'username']");
+ public static final By INPUT_EMAIL = By.xpath("//input[@id = 'email']");
+ public static final By INPUT_FIRST_NAME = By.xpath("//input[@id = 'firstName']");
+ public static final By INPUT_LAST_NAME = By.xpath("//input[@id = 'lastName']");
+
+ public static final By INVALID_INPUT = By.className("ng-invalid");
+ public static final By REQUIRED_EMAIL = By.className("qa_required_email");
+ public static final By REQUIRED_USERNAME = By.className("qa_required_user_name");
+ public static final By INVALID_USERNAME = By.className("qa_invalid_user_name");
+ public static final By INVALID_EMAIL = By.className("qa_invalid_email");
+ public static final By WRONG_EMAIL_FORMAT = By.className("qa_wrong_format_email");
+
+ //FORM
+ public static final By FORM_CHECK = By.className("form-check");
+ //TABLE
+ public static final By TABLE_ROWS = By.xpath("//tbody/tr");
+
+ public static final By TITLE_LBL = By.className("qa_title");
+ public static final By USER_DATA_HEADER = By.xpath("//*[contains(text(), 'Set User Data')]");
+ public static final By ROLES_HEADER = By.xpath("//*[contains(text(), 'Set Roles')]");
+
+ public static final By AVAILABLE_ROLES = By.className("qa_available_roles");
+ public static final By ASSIGNED_ROLES = By.className("qa_assigned_roles");
+ //ROLES
+ public static final By ONAP_DESIGNER_ROLE = By.id("onap_designer");
+ public static final By ONAP_OPERATOR_ROLE = By.id("onap_operator");
+ public static final By ONAP_ADMIN_ROLE = By.id("onap_admin");
+ public static final By AVAILABLE_ROLES_HEADER = By.className("qa_available_roles");
+ public static final By ASSIGNED_ROLES_HEADER = By.className("qa_assigned_roles");
+
+ public static By roleCheckbox(String role) {
+ return By.xpath("div/input[contains(@type,checkbox) and contains(@aria-labelledby, '" + role + "')]");
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/step_definitions/common/CommonStepDef.java b/src/main/java/org/onap/portalng/e2e/step_definitions/common/CommonStepDef.java
new file mode 100644
index 0000000..bcbf3b4
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/step_definitions/common/CommonStepDef.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.step_definitions.common;
+
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import org.onap.portalng.e2e.steps.common.CommonSteps;
+import org.onap.portalng.e2e.types.Button;
+import org.onap.portalng.e2e.types.Page;
+
+public class CommonStepDef {
+
+ @Given("User clicks on {} button in main menu")
+ public void userClicksOnButtonInMainMenu(Button item) {
+ CommonSteps.userClicksOnButtonInMainMenu(item);
+ }
+ @Given("User can see {}")
+ public void userCanSeePage(Page page) {
+ CommonSteps.userCanSeePage(page);
+ }
+
+ @Then("User should see error message with text {}")
+ public void userClicksOnSubmitButtonAndErrorMessageIsDisplayed(String errorCode) {
+ CommonSteps.userClicksOnSubmitButtonAndErrorMessageIsDisplayed(errorCode);
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/step_definitions/login/LoginStepDef.java b/src/main/java/org/onap/portalng/e2e/step_definitions/login/LoginStepDef.java
new file mode 100644
index 0000000..660fd4e
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/step_definitions/login/LoginStepDef.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.step_definitions.login;
+
+import io.cucumber.java.en.And;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import org.onap.portalng.e2e.steps.login.LoginSteps;
+import org.onap.portalng.e2e.steps.main.MainSteps;
+
+public class LoginStepDef {
+ @And("User verifies presence of all elements on Sign In form")
+ public void verifySignInForm() {
+ LoginSteps.verifySignInForm();
+ }
+
+ @When("User fills log in form with USERNAME value {string} and PASSWORD value {string}")
+ public void fillFormWithUsernameAndPasswordValues(String username, String password) {
+ LoginSteps.fillFormWithUsernameAndPasswordValues(username, password);
+ }
+
+ @Then("User submits credentials with Sign In button")
+ public void submitCredentialsForLoginBySignInButton() {
+ LoginSteps.submitCredentialsForLoginBySignInButton();
+ }
+
+ @And("User checks if is signed in to the Portal")
+ public void userChecksIfSignedInToThePortal(){
+ LoginSteps.userChecksIfSignedInToThePortal();
+ }
+
+ @And("User clicks on Logout button to log out from the Portal")
+ public void userClicksOnLogoutButton(){
+ LoginSteps.userClicksOnLogoutButton();
+ }
+
+ @Then("User sees error message {string} after incorrect credentials input")
+ public void errorIsShownAfterWrongCredentialsInput(String errorMsg) {
+ LoginSteps.errorIsShownAfterWrongCredentialsInput(errorMsg);
+ }
+
+ @And("User is logged in Portal as ADMIN")
+ public void userIsLoggedInPortalAsAdmin() {
+ MainSteps.userVisitsTheIndexPage();
+ LoginSteps.fillFormWithUsernameAndPasswordValues("onap-admin", "password");
+ LoginSteps.submitCredentialsForLoginBySignInButton();
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/step_definitions/main/MainStepDef.java b/src/main/java/org/onap/portalng/e2e/step_definitions/main/MainStepDef.java
new file mode 100644
index 0000000..f088a7d
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/step_definitions/main/MainStepDef.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.step_definitions.main;
+
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.When;
+import org.onap.portalng.e2e.steps.common.CommonSteps;
+import org.onap.portalng.e2e.steps.main.MainSteps;
+import org.onap.portalng.e2e.steps.user_administration.UserAdministrationSteps;
+import org.onap.portalng.e2e.types.Page;
+
+public class MainStepDef {
+
+ @Given("User opens the Portal page")
+ public void userVisitsTheIndexPage() {
+ MainSteps.userVisitsTheIndexPage();
+ }
+
+ @Given("User visits the {} page")
+ public void userVisitsTheUsersPage(Page page) {
+ MainSteps.userClicksOnUserMenuBtn();
+ CommonSteps.userCanSeePage(page);
+ }
+
+ @When("User clicks on Create User button")
+ public void userClicksOnCreateUserButton() {
+ UserAdministrationSteps.userClicksOnCreateUserButton();
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/step_definitions/user_administration/UserAdministrationStepDef.java b/src/main/java/org/onap/portalng/e2e/step_definitions/user_administration/UserAdministrationStepDef.java
new file mode 100644
index 0000000..8d8dfec
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/step_definitions/user_administration/UserAdministrationStepDef.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.step_definitions.user_administration;
+
+import io.cucumber.java.en.And;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import org.onap.portalng.e2e.steps.main.MainSteps;
+import org.onap.portalng.e2e.steps.user_administration.UserAdministrationSteps;
+import org.onap.portalng.e2e.types.UserRole;
+
+public class UserAdministrationStepDef {
+
+ @And("User verifies Create User Form")
+ public void userVerifiesCreateUserForm() {
+ UserAdministrationSteps.userVerifiesCreateUserForm();
+ }
+
+ @And("User fills data necessary for creating the user with USERNAME value {} in the form")
+ public void userFillsDataNecessaryForCreatingTheUserInTheForm(String username) {
+ UserAdministrationSteps.userFillsDataNecessaryForCreatingTheUserInTheForm(username);
+ }
+
+ @When("User set parameter {} with value {} on User create or edit page")
+ public void userFillsSpecificValuesForUserCreation(String input, String username) {
+ UserAdministrationSteps.userFillsSpecificValuesForUserCreation(input, username);
+ }
+
+ @And("User clicks on Save button in the form")
+ public void userClicksOnSaveButtonInTheForm() {
+ UserAdministrationSteps.userClicksOnSaveButtonInTheForm();
+ }
+
+ @And("User clicks on Cancel button in the form")
+ public void userClicksOnCancelButtonInTheForm() {
+ UserAdministrationSteps.userClicksOnCancelButtonInTheForm();
+ }
+
+
+ @And("User should see {} feedback {}")
+ public void userSeeFeedback(String invalidInput, String message) {
+ UserAdministrationSteps.userSeeFeedback(invalidInput, message);
+ }
+
+ @Then("User verifies newly created User in the User List")
+ public void userVerifiesNewUserInUserList() throws InterruptedException {
+ UserAdministrationSteps.userVerifiesNewUserInUserList();
+ }
+
+ @And("User with USERNAME value {} is created")
+ public void userIsCreated(String username) {
+ MainSteps.userClicksOnUserMenuBtn();
+ UserAdministrationSteps.userClicksOnCreateUserButton();
+ UserAdministrationSteps.userVerifiesCreateUserForm();
+ UserAdministrationSteps.userFillsDataNecessaryForCreatingTheUserInTheForm(username);
+ UserAdministrationSteps.userClicksOnSaveButtonInTheForm();
+// UserAdministrationSteps.userVerifiesNewUserInUserList();
+ }
+
+ @Then("User with USERNAME {} is successfully deleted")
+ public void deleteUser(String username) {
+ UserAdministrationSteps.deleteUser(username);
+ }
+
+ @Given("User clicks on EDIT button for user with USERNAME {} on Users page")
+ public void userClickOnBtnForUser(String username) {
+ UserAdministrationSteps.clickOnEditBtn(username);
+ }
+
+ @Given("User checks presence of elements on User edit page")
+ public void userCheckAllElementsOnUpdatePage() {
+ UserAdministrationSteps.userCheckAllElementsOnEditPage();
+ }
+
+ @Given("User fills all possible values to User edit page")
+ public void userFillsValuesToEditFormPage() {
+ UserAdministrationSteps.userFillsValuesToEditFormPage();
+ }
+
+ @Given("User clicks on {} button for user on User edit page")
+ public void userClickOnBtnOnEditPage(String button) {
+ UserAdministrationSteps.userClickOnBtnOnEditPage(button);
+ }
+
+ @When("User fills EMAIL {} in User edit page")
+ public void userFillsEmailValuesForUserCreation(String email) {
+ UserAdministrationSteps.userFillsEmailValuesForUserCreation(email);
+ }
+
+ @Given("User checks {} pop-up on user page with text {}")
+ public void userChecksPopupOnUserPage(String popUpType, String text) {
+ UserAdministrationSteps.userChecksPopupOnUserPage(popUpType, text);
+ }
+
+ @When("User clicks on {} available role checkbox")
+ public void assignAvailableRolesToUser(UserRole userRole) {
+ UserAdministrationSteps.assignAvailableRolesToUser(userRole);
+ }
+
+ @When("{} role is assigned to user")
+ public void selectedRoleIsAssignedToUser(UserRole userRole) {
+ UserAdministrationSteps.verifyThatUserRoleIsAssigned(userRole);
+ }
+
+ @When("User clicks on {} assigned role checkbox")
+ public void unAssignRolesToUser(UserRole userRole) {
+ UserAdministrationSteps.unAssignRoleFromUser(userRole);
+ }
+
+ @When("{} role is unassigned from user")
+ public void selectedRoleIsUnassignedFromUser(UserRole userRole) {
+ UserAdministrationSteps.verifyThatUserRoleIsAvailable(userRole);
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/steps/common/CommonSteps.java b/src/main/java/org/onap/portalng/e2e/steps/common/CommonSteps.java
new file mode 100644
index 0000000..fa96438
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/steps/common/CommonSteps.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.steps.common;
+
+import com.codeborne.selenide.Condition;
+import org.onap.portalng.e2e.types.Button;
+import org.onap.portalng.e2e.types.Page;
+
+import java.time.Duration;
+
+import static com.codeborne.selenide.Condition.disappear;
+import static com.codeborne.selenide.Selenide.$;
+import static org.onap.portalng.e2e.helpers.CommonUtils.checkTextOfElement;
+import static org.onap.portalng.e2e.pages.MainPage.*;
+import static org.onap.portalng.e2e.pages.PopUpDialogPage.ALERT_WARNING;
+import static org.onap.portalng.e2e.pages.UserAdministrationPage.TITLE_H2;
+
+
+public class CommonSteps {
+
+ public static void spinnerShouldDisappear() {
+ try {
+ $(SPINNER).shouldBe(Condition.visible, Duration.ofSeconds(3));
+ } catch (Throwable ignored) {
+ } finally {
+ $(SPINNER).shouldBe(disappear, Duration.ofSeconds(80));
+ }
+ }
+
+ public static void userClicksOnButtonInMainMenu(Button button) {
+ switch (button) {
+ case DASHBOARD:
+ checkTextOfElement($(DASHBOARD_BTN), "Dashboard");
+ $(DASHBOARD_BTN).click();
+ break;
+ case APP_STARTER:
+ checkTextOfElement($(APP_STARTER_BTN), "App Starter");
+ $(APP_STARTER_BTN).click();
+ break;
+ case USERS:
+ checkTextOfElement($(USERS_BTN), "Users");
+ $(USERS_BTN).click();
+ break;
+ default:
+ throw new IllegalStateException("Sidebar Menu Menu button" + button + "not recognized");
+ }
+ }
+
+ public static void userCanSeePage(Page page) {
+ switch (page) {
+ case DASHBOARD:
+ spinnerShouldDisappear();
+ checkTextOfElement($(TITLE_H2), "Dashboard");
+ break;
+ case APP_STARTER_PAGE:
+ spinnerShouldDisappear();
+ checkTextOfElement($(TITLE_H2), "App Starter");
+ break;
+ case USERS_PAGE:
+ spinnerShouldDisappear();
+ checkTextOfElement($(TITLE_H2), "User Administration");
+ break;
+ case USER_EDIT_PAGE:
+ spinnerShouldDisappear();
+ checkTextOfElement($(TITLE_H2), "Edit User");
+ break;
+ default:
+ throw new IllegalStateException("Page not recognized");
+ }
+ }
+
+ public static void userClicksOnSubmitButtonAndErrorMessageIsDisplayed(String error) {
+ checkTextOfElement($(ALERT_WARNING), error);
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/steps/common/TableSteps.java b/src/main/java/org/onap/portalng/e2e/steps/common/TableSteps.java
new file mode 100644
index 0000000..182c2f6
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/steps/common/TableSteps.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.steps.common;
+
+import com.codeborne.selenide.ElementsCollection;
+import com.codeborne.selenide.Selenide;
+import com.codeborne.selenide.SelenideElement;
+import org.openqa.selenium.By;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.codeborne.selenide.Condition.*;
+import static com.codeborne.selenide.Selenide.$;
+import static com.codeborne.selenide.Selenide.$$;
+import static java.util.stream.Collectors.toList;
+import static org.onap.portalng.e2e.pages.PageWithTable.*;
+
+public class TableSteps {
+
+ public static Optional<SelenideElement> findRowWithText(String text, boolean exactMatch) {
+ return findRowsWithText(text, exactMatch, false).stream().findAny();
+ }
+
+ public static List<SelenideElement> findRowsWithText(String text, boolean exactMatch, boolean isContaining) {
+ $(TABLE_ROWS).should(exist);
+ List<SelenideElement> foundedRows = findRowsOnActivePage(text, exactMatch, isContaining);
+ while (foundedRows.isEmpty() && hasNextPage()) {
+ goToNextPage();
+ foundedRows = findRowsOnActivePage(text, exactMatch, isContaining);
+ }
+ return foundedRows;
+ }
+
+ public static boolean hasNextPage() {
+ return $(PAGINATION).exists() && $(NEXT_PAGE).has(not(cssClass("disabled")));
+ }
+
+ public static void goToNextPage() {
+ Selenide.executeJavaScript("arguments[0].click()", $(NEXT_PAGE).$(By.xpath("a")).getWrappedElement());
+ CommonSteps.spinnerShouldDisappear();
+ }
+
+
+ public static int countRowsOnAllPages() {
+ int numberOfRows = Selenide.$$(TABLE_ROWS).size();
+ while (hasNextPage()) {
+ goToNextPage();
+ numberOfRows += Selenide.$$(TABLE_ROWS).size();
+ }
+ return numberOfRows;
+ }
+
+ private static List<SelenideElement> findRowsOnActivePage(String text, boolean exactMatch, boolean isContaining) {
+ return $$(TABLE_ROWS).stream()
+ .filter(row -> {
+ ElementsCollection rowValues = row.$$(ROW_CELLS);
+ String textInRow = getTextFromCell(rowValues.first());
+ if (exactMatch) {
+ return text.equals(textInRow);
+ } else if (isContaining) {
+ return textInRow.contains(text);
+ } else {
+ return textInRow.startsWith(text);
+ }
+ }).collect(toList());
+ }
+
+ private static String getTextFromCell(SelenideElement cell) {
+ SelenideElement anchor = cell.find(By.xpath("a"));
+ if (anchor.exists()) {
+ return anchor.getText();
+ } else {
+ return cell.getText();
+ }
+ }
+
+}
diff --git a/src/main/java/org/onap/portalng/e2e/steps/login/LoginSteps.java b/src/main/java/org/onap/portalng/e2e/steps/login/LoginSteps.java
new file mode 100644
index 0000000..5d3e927
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/steps/login/LoginSteps.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.steps.login;
+
+import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.Selenide;
+import org.onap.portalng.e2e.pages.LoginPage;
+
+import static com.codeborne.selenide.Condition.text;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LoginSteps {
+
+ public static void verifySignInForm() {
+ Selenide.$(LoginPage.USERNAME_LBL).shouldHave(text("Username or email"));
+ Selenide.$(LoginPage.PASSWORD_LBL).shouldHave(Condition.text("Password"));
+ Selenide.$(LoginPage.SIGN_IN_BTN).shouldHave(Condition.value("Sign In"));
+ }
+
+ public static void fillFormWithUsernameAndPasswordValues(String username, String password) {
+ Selenide.$(LoginPage.USERNAME_INPUT).setValue(username);
+ Selenide.$(LoginPage.PASSWORD_INPUT).setValue(password);
+ }
+
+ public static void submitCredentialsForLoginBySignInButton() {
+ Selenide.$(LoginPage.SIGN_IN_BTN).click();
+ }
+
+ public static void userChecksIfSignedInToThePortal(){
+ Selenide.$(LoginPage.CURRENT_PAGE_SPAN).shouldHave(text("Dashboard"));
+ Selenide.$(LoginPage.CURRENT_PAGE_HEADING_TITLE).shouldHave(text("Dashboard"));
+ }
+
+ public static void userClicksOnLogoutButton(){
+ Selenide.$(LoginPage.DROPDOWN_MENU).click();
+ Selenide.$(LoginPage.LOGOUT_BUTTON).click();
+ }
+
+ public static void errorIsShownAfterWrongCredentialsInput(String errorMsg) {
+ assertThat(Selenide.$(LoginPage.INPUT_ERROR_SPAN).getText())
+ .describedAs("Text is not as expected")
+ .isEqualTo(errorMsg);
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/steps/main/MainSteps.java b/src/main/java/org/onap/portalng/e2e/steps/main/MainSteps.java
new file mode 100644
index 0000000..ffb0a96
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/steps/main/MainSteps.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.steps.main;
+
+import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.Configuration;
+
+import static com.codeborne.selenide.Selenide.$;
+import static com.codeborne.selenide.Selenide.open;
+import static org.onap.portalng.e2e.pages.MainPage.USERS_BTN;
+import static org.onap.portalng.e2e.pages.UserAdministrationPage.TITLE_H2;
+
+public class MainSteps {
+ public static void userVisitsTheIndexPage() {
+ open(Configuration.baseUrl);
+ }
+
+ public static void userClicksOnUserMenuBtn() {
+ $(USERS_BTN).click();
+ }
+
+ public void userCanSeeUserAdministrationPage() {
+ $(TITLE_H2).shouldHave(Condition.text("User Administration"));
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/steps/user_administration/UserAdministrationSteps.java b/src/main/java/org/onap/portalng/e2e/steps/user_administration/UserAdministrationSteps.java
new file mode 100644
index 0000000..1460e37
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/steps/user_administration/UserAdministrationSteps.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.steps.user_administration;
+
+import com.codeborne.selenide.Condition;
+import com.codeborne.selenide.Selenide;
+import com.codeborne.selenide.SelenideElement;
+import org.junit.Assert;
+import org.onap.portalng.e2e.steps.main.MainSteps;
+import org.onap.portalng.e2e.helpers.UiSessionVariables;
+import org.onap.portalng.e2e.pages.PopUpDialogPage;
+import org.onap.portalng.e2e.steps.common.CommonSteps;
+import org.onap.portalng.e2e.steps.common.TableSteps;
+import org.onap.portalng.e2e.types.Button;
+import org.onap.portalng.e2e.types.UserRole;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+import java.util.Optional;
+
+import static com.codeborne.selenide.Condition.*;
+import static com.codeborne.selenide.Selenide.$;
+import static com.codeborne.selenide.Selenide.$$;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.onap.portalng.e2e.helpers.CommonUtils.checkPresenceOfElement;
+import static org.onap.portalng.e2e.helpers.CommonUtils.checkTextOfElement;
+import static org.onap.portalng.e2e.pages.PageWithTable.ROW_DELETE_BUTTON;
+import static org.onap.portalng.e2e.pages.PopUpDialogPage.ALERT_SUCCESS;
+import static org.onap.portalng.e2e.pages.PopUpDialogPage.*;
+import static org.onap.portalng.e2e.pages.UserAdministrationPage.*;
+
+public class UserAdministrationSteps {
+
+ public static void userClicksOnCreateUserButton() {
+ $(BUTTON_CREATE).shouldHave(Condition.text("Create User"));
+ $(BUTTON_CREATE).click();
+ }
+
+ public static void userVerifiesCreateUserForm() {
+ $(TITLE_H2).shouldHave(Condition.text("Create User"));
+
+ $$(TITLE_H4).get(0).shouldHave(Condition.text("Set User Data"));
+ $$(TITLE_H4).get(1).shouldHave(Condition.text("Set Roles"));
+
+ $$(TITLE_H5).get(1).shouldHave(Condition.text("Available"));
+ $$(TITLE_H5).get(2).shouldHave(Condition.text("Assigned"));
+
+ $(LABEL_ID).shouldHave(Condition.text("ID"));
+ $(LABEL_USERNAME).shouldHave(Condition.text("Username"));
+ $(LABEL_EMAIL).shouldHave(Condition.text("Email"));
+ $(LABEL_FIRST_NAME).shouldHave(Condition.text("First Name"));
+ $(LABEL_LAST_NAME).shouldHave(Condition.text("Last Name"));
+
+ $(INPUT_ID).shouldBe(Condition.disabled);
+ }
+
+ public static void userFillsDataNecessaryForCreatingTheUserInTheForm(String username) {
+ $(INPUT_USERNAME).setValue(username);
+ $(INPUT_EMAIL).setValue(username + "@test.user");
+ $(INPUT_FIRST_NAME).setValue("E2E");
+ $(INPUT_LAST_NAME).setValue("TestUser");
+ UiSessionVariables.USERNAME.set(username);
+
+ $$(FORM_CHECK).findBy(Condition.text("onap_admin")).$("input").click();
+ }
+ public static void userFillsSpecificValuesForUserCreation(String input, String value) {
+ switch (input) {
+ case "EMAIL":
+ if (value.equals("clear")) {
+ $(INPUT_EMAIL).setValue(" ");
+ $(INPUT_EMAIL).sendKeys(Keys.BACK_SPACE);
+ } else {
+ $(INPUT_EMAIL).setValue(" ");
+ $(INPUT_EMAIL).sendKeys(Keys.BACK_SPACE);
+ $(INPUT_EMAIL).setValue(value);
+ }
+ break;
+ case "USERNAME":
+ if (value.equals("clear")) {
+ $(INPUT_USERNAME).setValue(" ");
+ $(INPUT_USERNAME).sendKeys(Keys.BACK_SPACE);
+ } else {
+ $(INPUT_USERNAME).setValue(value);
+ }
+ break;
+ case "LAST_NAME":
+ $(INPUT_LAST_NAME).setValue(value);
+ break;
+ case "FIRST_NAME":
+ $(INPUT_FIRST_NAME).setValue(value);
+ break;
+ default:
+ throw new IllegalStateException("Unexpected value: " + input);
+ }
+ }
+
+ public static void userClicksOnSaveButtonInTheForm() {
+ $(BUTTON_SAVE).click();
+ }
+
+ public static void userClicksOnCancelButtonInTheForm() {
+ $(BUTTON_CANCEL).click();
+ }
+
+ public static void userSeeFeedback(String invalidInput, String message) {
+ switch (invalidInput) {
+ case "REQUIRED_USERNAME":
+ checkTextOfElement($(REQUIRED_USERNAME), message);
+ checkPresenceOfElement($(INVALID_INPUT));
+ break;
+ case "REQUIRED_EMAIL":
+ checkTextOfElement($(REQUIRED_EMAIL), message);
+ checkPresenceOfElement($(INVALID_INPUT));
+ break;
+ case "INVALID_USERNAME":
+ checkTextOfElement($(INVALID_USERNAME), message);
+ checkPresenceOfElement($(INVALID_INPUT));
+ break;
+ case "INVALID_EMAIL":
+ checkTextOfElement($(INVALID_EMAIL), message);
+ checkPresenceOfElement($(INVALID_INPUT));
+ break;
+ case "WRONG_EMAIL_FORMAT":
+ checkTextOfElement($(WRONG_EMAIL_FORMAT), message);
+ checkPresenceOfElement($(INVALID_INPUT));
+ break;
+ default:
+ throw new IllegalArgumentException(invalidInput + " is not implemented yet");
+
+ }
+ }
+
+
+ public static void userVerifiesNewUserInUserList() throws InterruptedException {
+ Selenide.Wait().until(ExpectedConditions.visibilityOf($$(TABLE_ROWS).get(0)));
+
+ for (SelenideElement row : $$(TABLE_ROWS)) {
+ if ($(row).findAll(By.id("td")).findBy(Condition.text("e2e-test-user")).exists()) {
+ Assert.assertEquals("e2e-test-user", $(row).findAll(By.id("td")).get(0).getText());
+ Assert.assertEquals("E2e", $(row).findAll(By.id("td")).get(1).getText());
+ Assert.assertEquals("TestUser", $(row).findAll(By.id("td")).get(2).getText());
+ Assert.assertEquals("e2e@test.user", $(row).findAll(By.id("td")).get(3).getText());
+ Assert.assertEquals("onap_admin", $(row).findAll(By.id("td")).get(4).getText());
+ }
+ }
+ }
+
+ public static void deleteUser(String username) {
+ MainSteps.userClicksOnUserMenuBtn();
+
+ Optional<SelenideElement> userRow = TableSteps.findRowWithText(username, true);
+ if (userRow.isPresent()) {
+ assertThat(userRow.isPresent()).as("User cannot be deleted, user with " + username + " was not found.").isTrue();
+ userRow.get().$(ROW_DELETE_BUTTON).click();
+ $(DIALOG_HEADER).shouldHave(text("Delete User"));
+ $(DIALOG_BODY).shouldHave(text("Are you sure, that you want to delete user: " + username + " ? "));
+ $(DIALOG_APPLY_BUTTON).shouldHave(text("Delete"));
+ $(DIALOG_APPLY_BUTTON).click();
+ $$(ALERT_SUCCESS).last().shouldHave(text("User successfully deleted."));
+ userRow.get().should(not(exist));
+ }
+ }
+
+ public static void clickOnEditBtn(String username) {
+ CommonSteps.userClicksOnButtonInMainMenu(Button.USERS);
+
+ Optional<SelenideElement> userRow = TableSteps.findRowWithText(username, true);
+ assertThat(userRow.isPresent()).as("User cannot be updated, user with " + username + " was not found.").isTrue();
+ userRow.get().$(BUTTON_EDIT).click();
+ userRow.get().should(not(exist));
+ }
+
+ public static void userCheckAllElementsOnEditPage() {
+ checkTextOfElement($(TITLE_LBL), "Edit User");
+ checkPresenceOfElement($(USER_DATA_HEADER));
+ checkPresenceOfElement($(INPUT_ID));
+ checkPresenceOfElement($(INPUT_USERNAME));
+ checkPresenceOfElement($(INPUT_EMAIL));
+ checkPresenceOfElement($(INPUT_FIRST_NAME));
+ checkPresenceOfElement($(INPUT_LAST_NAME));
+ checkTextOfElement($(LABEL_ID), "ID");
+ checkTextOfElement($(LABEL_USERNAME), "Username");
+ checkTextOfElement($(LABEL_EMAIL), "Email");
+ checkTextOfElement($(LABEL_FIRST_NAME), "First Name");
+ checkTextOfElement($(LABEL_LAST_NAME), "Last Name");
+ checkPresenceOfElement($(ROLES_HEADER));
+ checkTextOfElement($(AVAILABLE_ROLES), "Available");
+ checkTextOfElement($(ASSIGNED_ROLES), "Assigned");
+ checkTextOfElement($(ONAP_DESIGNER_ROLE), "onap_designer");
+ checkTextOfElement($(ONAP_OPERATOR_ROLE), "onap_operator");
+ checkTextOfElement($(ONAP_ADMIN_ROLE), "onap_admin");
+ checkTextOfElement($(BUTTON_CANCEL), "Cancel");
+ checkTextOfElement($(BUTTON_SAVE), "Save");
+ }
+
+ public static void userFillsValuesToEditFormPage() {
+ $(INPUT_FIRST_NAME).setValue("firstName");
+ $(INPUT_LAST_NAME).setValue("lastName");
+ $(INPUT_EMAIL).setValue("e2e" + "@test.com");
+ }
+
+ public static void userClickOnBtnOnEditPage(String button) {
+ switch (button) {
+ case "Edit":
+ $(BUTTON_SAVE).click();
+ break;
+ case "Cancel":
+ $(BUTTON_CANCEL).click();
+ break;
+ default:
+ throw new IllegalArgumentException("Button was not implemented");
+ }
+ }
+
+ public static void userFillsEmailValuesForUserCreation(String email) {
+ $(INPUT_EMAIL).clear();
+ $(INPUT_EMAIL).setValue(email);
+ }
+
+ public static void userChecksPopupOnUserPage(String popUpType, String text) {
+ if (popUpType.equals("SUCCESS")) {
+ checkTextOfElement($(PopUpDialogPage.ALERT_SUCCESS), text);
+ } else if (popUpType.equals("ERROR")) {
+ checkTextOfElement($(PopUpDialogPage.ALERT_ERROR), text);
+ }
+ }
+
+ public static void assignAvailableRolesToUser(UserRole userRole) {
+ SelenideElement availableRolesBlock = $(AVAILABLE_ROLES_HEADER).parent();
+ SelenideElement availableRole = availableRolesBlock.find(userRoleCheckBox(userRole));
+ availableRole.click();
+ availableRole.should(not(exist));
+ }
+
+ public static void unAssignRoleFromUser(UserRole userRole) {
+ SelenideElement assignedRolesBlock = $(ASSIGNED_ROLES_HEADER).parent();
+ SelenideElement assignedRole = assignedRolesBlock.find(userRoleCheckBox(userRole));
+ assignedRole.click();
+ assignedRole.should(not(exist));
+ }
+
+ public static void verifyThatUserRoleIsAvailable(UserRole userRole) {
+ SelenideElement availableRolesBlock = $(AVAILABLE_ROLES_HEADER).parent();
+ availableRolesBlock.find(userRoleCheckBox(userRole)).should(exist);
+ }
+
+ public static void verifyThatUserRoleIsAssigned(UserRole userRole) {
+ SelenideElement assignedRolesBlock = $(ASSIGNED_ROLES_HEADER).parent();
+ assignedRolesBlock.find(userRoleCheckBox(userRole)).should(exist);
+ }
+
+ public static By userRoleCheckBox(UserRole userRole) {
+ switch (userRole) {
+ case ONAP_DESIGNER:
+ return roleCheckbox("onap_designer");
+ case ONAP_OPERATOR:
+ return roleCheckbox("onap_operator");
+ case ONAP_ADMIN:
+ return roleCheckbox("onap_admin");
+ default:
+ throw new IllegalArgumentException("Not recognized role");
+ }
+ }
+}
diff --git a/src/main/java/org/onap/portalng/e2e/types/Button.java b/src/main/java/org/onap/portalng/e2e/types/Button.java
new file mode 100644
index 0000000..a434b4f
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/types/Button.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.types;
+
+public enum Button {
+ DROPDOWN_MENU,
+ DASHBOARD,
+ APP_STARTER,
+ USERS
+}
diff --git a/src/main/java/org/onap/portalng/e2e/types/Page.java b/src/main/java/org/onap/portalng/e2e/types/Page.java
new file mode 100644
index 0000000..1ec1e33
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/types/Page.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.types;
+
+public enum Page {
+ DASHBOARD,
+ APP_STARTER_PAGE,
+ USERS_PAGE,
+ USER_EDIT_PAGE
+}
diff --git a/src/main/java/org/onap/portalng/e2e/types/UserRole.java b/src/main/java/org/onap/portalng/e2e/types/UserRole.java
new file mode 100644
index 0000000..e1a0871
--- /dev/null
+++ b/src/main/java/org/onap/portalng/e2e/types/UserRole.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023. Deutsche Telekom AG
+ *
+ * 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
+ *
+ */
+
+package org.onap.portalng.e2e.types;
+
+public enum UserRole {
+ ONAP_DESIGNER("onap_designer"),
+ ONAP_OPERATOR("onap_operator"),
+ ONAP_ADMIN("onap_admin");
+
+ private String value;
+
+ UserRole(final String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/resources/test-local.properties b/src/main/resources/test-local.properties
new file mode 100644
index 0000000..d1648e9
--- /dev/null
+++ b/src/main/resources/test-local.properties
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2023. Deutsche Telekom AG
+#
+# 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
+#
+#
+
+baseUrl=http://localhost \ No newline at end of file
diff --git a/src/main/resources/test-remote.properties b/src/main/resources/test-remote.properties
new file mode 100644
index 0000000..a4ea8cc
--- /dev/null
+++ b/src/main/resources/test-remote.properties
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2023. Deutsche Telekom AG
+#
+# 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
+#
+#
+
+baseUrl=https://remote-url \ No newline at end of file
diff --git a/src/test/resources/cucumber.properties b/src/test/resources/cucumber.properties
new file mode 100644
index 0000000..869613f
--- /dev/null
+++ b/src/test/resources/cucumber.properties
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2023. Deutsche Telekom AG
+#
+# 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
+#
+#
+
+cucumber.publish.quiet=true \ No newline at end of file
diff --git a/src/test/resources/features/login.feature b/src/test/resources/features/login.feature
new file mode 100644
index 0000000..5fecc34
--- /dev/null
+++ b/src/test/resources/features/login.feature
@@ -0,0 +1,32 @@
+# Copyright (c) 2023. Deutsche Telekom AG
+#
+# 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
+
+Feature: Login and Logout
+
+ Scenario: User can sign in to Portal with valid credentials
+ Given User opens the Portal page
+ And User verifies presence of all elements on Sign In form
+ When User fills log in form with USERNAME value 'onap-admin' and PASSWORD value 'password'
+ Then User submits credentials with Sign In button
+ And User checks if is signed in to the Portal
+ And User clicks on Logout button to log out from the Portal
+
+ Scenario: User cannot login to Portal with invalid username or password
+ Given User opens the Portal page
+ And User verifies presence of all elements on Sign In form
+ When User fills log in form with USERNAME value 'onap-admin' and PASSWORD value 'invalidPassword'
+ And User submits credentials with Sign In button
+ Then User sees error message 'Invalid username or password.' after incorrect credentials input
diff --git a/src/test/resources/features/user_administration.feature b/src/test/resources/features/user_administration.feature
new file mode 100644
index 0000000..3e402db
--- /dev/null
+++ b/src/test/resources/features/user_administration.feature
@@ -0,0 +1,121 @@
+# Copyright (c) 2023. Deutsche Telekom AG
+#
+# 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
+
+Feature: User Administration
+
+ @delete_user
+ Scenario: User can create a new user in Portal
+ Given User is logged in Portal as ADMIN
+ Given User visits the USERS_PAGE page
+ When User clicks on Create User button
+ And User verifies Create User Form
+ And User fills data necessary for creating the user with USERNAME value e2e-test-user in the form
+ And User clicks on Save button in the form
+ Given User visits the USERS_PAGE page
+ Then User verifies newly created User in the User List
+
+ Scenario: User can cancel user creation
+ Given User visits the USERS_PAGE page
+ When User clicks on Create User button
+ And User verifies Create User Form
+ And User clicks on Cancel button in the form
+ And User can see USERS_PAGE
+
+ Scenario: User cannot create a new user in Portal without mandatory parameters
+ Given User visits the USERS_PAGE page
+ When User clicks on Create User button
+ And User verifies Create User Form
+ And User clicks on Save button in the form
+ Then User should see REQUIRED_USERNAME feedback Required
+ And User should see REQUIRED_EMAIL feedback Cannot be empty
+
+ @delete_user
+ Scenario: User cannot be created with already existing USERNAME
+ Given User with USERNAME value e2e-test-user is created
+ And User clicks on USERS button in main menu
+ When User clicks on Create User button
+ And User fills data necessary for creating the user with USERNAME value e2e-test-user in the form
+ And User clicks on Save button in the form
+ Then User should see error message with text Error while creating user account! Error reported by "Keycloak" system: "User exists with same username" Please, try to create user with different username.
+
+ Scenario: User cannot be created with already existing EMAIL
+ Given User with USERNAME value e2e-test-user is created
+ And User clicks on USERS button in main menu
+ When User clicks on Create User button
+ And User fills data necessary for creating the user with USERNAME value e2e-test-user-2 in the form
+ And User set parameter EMAIL with value e2e-test-user@test.user on User create or edit page
+ And User clicks on Save button in the form
+ Then User should see error message with text Error while creating user account! Error reported by "Keycloak" system: "User exists with same email" Please, try to create user with different email address.
+ #deletion after test
+ Then User with USERNAME e2e-test-user is successfully deleted
+
+ Scenario: User cannot be created with USERNAME value as empty string
+ Given User clicks on USERS button in main menu
+ And User clicks on Create User button
+ When User fills data necessary for creating the user with USERNAME value "" in the form
+ And User set parameter EMAIL with value test@test.user on User create or edit page
+ And User clicks on Save button in the form
+ Then User should see INVALID_USERNAME feedback Invalid character
+
+ Scenario: User cannot be created with EMAIL value as empty string
+ Given User clicks on USERS button in main menu
+ And User clicks on Create User button
+ And User fills data necessary for creating the user with USERNAME value e2e-test-user in the form
+ When User set parameter EMAIL with value "" on User create or edit page
+ And User clicks on Save button in the form
+ Then User should see INVALID_EMAIL feedback Invalid character
+ And User should see WRONG_EMAIL_FORMAT feedback Wrong email format
+
+ Scenario: User can be deleted in Portal
+ Given User with USERNAME value e2e-test-user is created
+ Then User with USERNAME e2e-test-user is successfully deleted
+
+ @delete_user
+ Scenario: User can be edited in Portal
+ Given User with USERNAME value e2e-test-user is created
+ And User clicks on EDIT button for user with USERNAME e2e-test-user on Users page
+ And User can see USER_EDIT_PAGE
+ And User checks presence of elements on User edit page
+ And User clicks on Cancel button for user on User edit page
+ And User can see USERS_PAGE
+ And User clicks on EDIT button for user with USERNAME e2e-test-user on Users page
+ And User fills all possible values to User edit page
+ When User clicks on Edit button for user on User edit page
+ Then User checks SUCCESS pop-up on user page with text User successfully updated.
+ And User can see USERS_PAGE
+
+ Scenario: User cannot be created with already existing EMAIL
+ Given User with USERNAME value e2e-test-user-1 is created
+ And User with USERNAME value e2e-test-user-2 is created
+ And User clicks on USERS button in main menu
+ And User can see USERS_PAGE
+ And User clicks on EDIT button for user with USERNAME e2e-test-user-1 on Users page
+ And User can see USER_EDIT_PAGE
+ When User fills EMAIL e2e-test-user-2@test.user in User edit page
+ And User clicks on Edit button for user on User edit page
+ Then User should see error message with text Error, changing user account failed! Error reported by "Keycloak" system: "User exists with same username or email" Please, try to create user with different email address.
+ #deletion after
+ Then User with USERNAME e2e-test-user-1 is successfully deleted
+ Then User with USERNAME e2e-test-user-2 is successfully deleted
+
+ @delete_user
+ Scenario: User role can be assigned or unassigned on Edit page
+ Given User with USERNAME value e2e-test-user is created
+ And User clicks on EDIT button for user with USERNAME e2e-test-user on Users page
+ When User clicks on ONAP_DESIGNER available role checkbox
+ Then ONAP_DESIGNER role is assigned to user
+ And User clicks on ONAP_DESIGNER assigned role checkbox
+ Then ONAP_DESIGNER role is unassigned from user