diff options
author | marian.vaclavik@telekom.com <marian.vaclavik@telekom.com> | 2023-07-31 10:59:39 +0200 |
---|---|---|
committer | marian.vaclavik@telekom.com <marian.vaclavik@telekom.com> | 2023-08-08 09:50:35 +0200 |
commit | 1c4023ccc06e633233ed642eb9d1ac85e82feaf0 (patch) | |
tree | d1b42076f13075d4bc7255120a5934f753774559 /src | |
parent | c38f1100b43a48a9f86bc50c2e560ae94d15956a (diff) |
Issue-ID: PORTALNG-35
Change-Id: I606b3f265dfdb98d7eb9cfd8ab021e2895ee5152
Signed-off-by: marian.vaclavik@telekom.com <marian.vaclavik@telekom.com>
Diffstat (limited to 'src')
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 |