diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-11-09 16:58:27 +0100 |
---|---|---|
committer | Eric Hartmann <hartmann.eric@gmail.Com> | 2017-11-14 13:10:17 +0100 |
commit | a7b805384a46f7a700d3917757899e251f2f8207 (patch) | |
tree | fa66217a3ac072ea894378a7c555c73f70afb7ab /server | |
parent | fca6f8677bd699540b6c9e5df98427b8f932e18b (diff) | |
download | sonarqube-a7b805384a46f7a700d3917757899e251f2f8207.tar.gz sonarqube-a7b805384a46f7a700d3917757899e251f2f8207.zip |
Move pageobjects to new module sonar-qa-util
Diffstat (limited to 'server')
40 files changed, 2711 insertions, 0 deletions
diff --git a/server/pom.xml b/server/pom.xml index 99a700f2a58..5b27942fb00 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -23,6 +23,7 @@ <module>sonar-ce</module> <module>sonar-plugin-bridge</module> <module>sonar-web</module> + <module>sonar-qa-util</module> </modules> <profiles> diff --git a/server/sonar-qa-util/pom.xml b/server/sonar-qa-util/pom.xml new file mode 100644 index 00000000000..a9534332a89 --- /dev/null +++ b/server/sonar-qa-util/pom.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.sonarsource.sonarqube</groupId> + <artifactId>server</artifactId> + <version>7.0-SNAPSHOT</version> + <relativePath>..</relativePath> + </parent> + <artifactId>sonar-qa-util</artifactId> + <name>SonarQube :: Utilities for QA Tests</name> + + <properties> + <sonar.coverage.exclusions>src/main/java/**/*</sonar.coverage.exclusions> + </properties> + + <dependencies> + <dependency> + <groupId>com.codeborne</groupId> + <artifactId>selenide</artifactId> + <version>4.4.3</version> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + </dependency> + <dependency> + <groupId>org.sonarsource.orchestrator</groupId> + <artifactId>sonar-orchestrator</artifactId> + <version>${orchestrator.version}</version> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <!-- required for selenide --> + <version>21.0</version> + </dependency> + + <dependency> + <groupId>com.google.code.findbugs</groupId> + <artifactId>jsr305</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> + +</project> diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/SelenideConfig.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/SelenideConfig.java new file mode 100644 index 00000000000..155ded5ee56 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/SelenideConfig.java @@ -0,0 +1,70 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util; + +import com.codeborne.selenide.Configuration; +import com.codeborne.selenide.WebDriverRunner; +import com.sonar.orchestrator.Orchestrator; +import java.util.stream.Collectors; +import org.openqa.selenium.WebDriver; + +import static java.util.Arrays.stream; + +public class SelenideConfig { + + private enum Browser { + firefox("(v46 and lower)"), + marionette("(recent Firefox, require Geckodriver)"), + chrome("(require Chromedriver)"); + + private final String label; + + Browser(String label) { + this.label = label; + } + + static Browser of(String s) { + try { + return Browser.valueOf(s); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid browser: " + s + ". Supported values are " + + stream(values()).map(b -> b.name() + " " + b.label).collect(Collectors.joining(", "))); + } + } + } + + public static WebDriver configure(Orchestrator orchestrator) { + String browserKey = orchestrator.getConfiguration().getString("orchestrator.browser", Browser.firefox.name()); + Browser browser = Browser.of(browserKey); + Configuration.browser = browser.name(); + Configuration.baseUrl = orchestrator.getServer().getUrl(); + Configuration.timeout = 8_000; + Configuration.reportsFolder = "target/screenshots"; + Configuration.screenshots = true; + Configuration.captureJavascriptErrors = true; + Configuration.savePageSource = true; + Configuration.browserSize = "1280x1024"; + return getWebDriver(); + } + + static WebDriver getWebDriver() { + return WebDriverRunner.getWebDriver(); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/package-info.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/package-info.java new file mode 100644 index 00000000000..696f5531c1d --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/package-info.java @@ -0,0 +1,23 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@ParametersAreNonnullByDefault +package org.sonarqube.qa.util; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/BackgroundTaskItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/BackgroundTaskItem.java new file mode 100644 index 00000000000..0c86d3293b1 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/BackgroundTaskItem.java @@ -0,0 +1,65 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class BackgroundTaskItem { + + private final SelenideElement elt; + + public BackgroundTaskItem(SelenideElement elt) { + this.elt = elt; + } + + public SelenideElement getComponent() { + return elt.$("td:nth-child(2)"); + } + + public BackgroundTaskItem openActions() { + elt.$(".js-task-action > .dropdown-toggle").click(); + elt.$(".js-task-action > .dropdown-menu").shouldBe(Condition.visible); + return this; + } + + public BackgroundTaskItem openScannerContext() { + elt.$(".js-task-show-scanner-context").click(); + Selenide.$(".js-task-scanner-context").shouldBe(Condition.visible); + return this; + } + + public BackgroundTaskItem assertScannerContextContains(String text) { + Selenide.$(".js-task-scanner-context").should(Condition.hasText(text)); + return this; + } + + public BackgroundTaskItem openErrorStacktrace() { + elt.$(".js-task-show-stacktrace").click(); + Selenide.$(".js-task-stacktrace").shouldBe(Condition.visible); + return this; + } + + public BackgroundTaskItem assertErrorStacktraceContains(String text) { + Selenide.$(".js-task-stacktrace").should(Condition.hasText(text)); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/BackgroundTasksPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/BackgroundTasksPage.java new file mode 100644 index 00000000000..a14bc2cebff --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/BackgroundTasksPage.java @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import java.util.List; +import java.util.stream.Collectors; +import org.openqa.selenium.By; + +public class BackgroundTasksPage { + + public BackgroundTasksPage() { + Selenide.$(By.cssSelector(".background-tasks")).should(Condition.exist); + } + + public ElementsCollection getTasks() { + return Selenide.$$(".background-tasks > tbody > tr"); + } + + public List<BackgroundTaskItem> getTasksAsItems() { + return getTasks() + .stream() + .map(BackgroundTaskItem::new) + .collect(Collectors.toList()); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/EncryptionPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/EncryptionPage.java new file mode 100644 index 00000000000..0e3bac79722 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/EncryptionPage.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class EncryptionPage extends Navigation { + + public EncryptionPage() { + Selenide.$("#encryption-page").should(Condition.exist); + } + + public SelenideElement generationForm() { + return Selenide.$("#generate-secret-key-form"); + } + + public SelenideElement newSecretKey() { + return Selenide.$("#secret-key"); + } + + public String encryptValue(String value) { + Selenide.$("#encryption-form-value").val(value); + Selenide.$("#encryption-form").submit(); + return Selenide.$("#encrypted-value").shouldBe(Condition.visible).val(); + } + + public EncryptionPage generateNewKey() { + Selenide.$("#encryption-new-key-form").submit(); + Selenide.$("#generate-secret-key-form").shouldBe(Condition.visible); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/LoginPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/LoginPage.java new file mode 100644 index 00000000000..b210e01fb2e --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/LoginPage.java @@ -0,0 +1,64 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import org.openqa.selenium.By; + +public class LoginPage { + + public LoginPage() { + Selenide.$("#login_form").should(Condition.exist); + } + + public Navigation submitCredentials(String login) { + return submitCredentials(login, login, Navigation.class); + } + + public Navigation submitCredentials(String login, String password) { + return submitCredentials(login, password, Navigation.class); + } + + public Navigation useOAuth2() { + Selenide.$(".oauth-providers a").click(); + return Selenide.page(Navigation.class); + } + + public LoginPage submitWrongCredentials(String login, String password) { + Selenide.$("#login").val(login); + Selenide.$("#password").val(password); + Selenide.$(By.name("commit")).click(); + return Selenide.page(LoginPage.class); + } + + public SelenideElement getErrorMessage() { + return Selenide.$(".process-spinner-failed"); + } + + private <T> T submitCredentials(String login, String password, Class<T> expectedResultPage) { + Selenide.$("#login").val(login); + Selenide.$("#password").val(password); + Selenide.$(By.name("commit")).click(); + Selenide.$("#login").should(Condition.disappear); + return Selenide.page(expectedResultPage); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/MarketplacePage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/MarketplacePage.java new file mode 100644 index 00000000000..908bad3b3e9 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/MarketplacePage.java @@ -0,0 +1,60 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class MarketplacePage { + + public MarketplacePage() { + Selenide.$("#marketplace-page").should(Condition.exist); + } + + public MarketplacePage hasPendingPlugins(String text) { + Selenide.$(".js-pending").should(Condition.exist).shouldHave(Condition.text(text)); + return this; + } + + public MarketplacePage hasPluginsCount(int count) { + Selenide.$$("#marketplace-plugins>ul>li").shouldHaveSize(count); + return this; + } + + public MarketplacePage hasPluginWithText(String name, String text) { + getPlugin(name).shouldHave(Condition.text(text)); + return this; + } + + public MarketplacePage searchPlugin(String search) { + Selenide.$("#marketplace-search input.search-box-input").should(Condition.exist).sendKeys(search); + return this; + } + + public MarketplacePage uninstallPlugin(String name) { + getPlugin(name).$("button.js-uninstall").click(); + return this; + } + + private SelenideElement getPlugin(String name) { + return Selenide.$$(".js-plugin-name").findBy(Condition.text(name)).should(Condition.exist).parent().parent().parent(); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/Navigation.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/Navigation.java new file mode 100644 index 00000000000..67cea197772 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/Navigation.java @@ -0,0 +1,265 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import com.codeborne.selenide.WebDriverRunner; +import com.sonar.orchestrator.Orchestrator; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.function.Consumer; +import javax.annotation.Nullable; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.html5.WebStorage; +import org.sonarqube.qa.util.SelenideConfig; +import org.sonarqube.qa.util.pageobjects.issues.IssuesPage; +import org.sonarqube.qa.util.pageobjects.measures.MeasuresPage; +import org.sonarqube.qa.util.pageobjects.organization.MembersPage; +import org.sonarqube.qa.util.pageobjects.projects.ProjectsPage; +import org.sonarqube.qa.util.pageobjects.settings.SettingsPage; + +public class Navigation { + + public Navigation() { + Selenide.$("#content").shouldBe(Condition.exist); + } + + public static Navigation create(Orchestrator orchestrator) { + WebDriver driver = SelenideConfig.configure(orchestrator); + driver.manage().deleteAllCookies(); + clearStorage(d -> d.getLocalStorage().clear()); + clearStorage(d -> d.getSessionStorage().clear()); + clearStorage(d -> Selenide.clearBrowserLocalStorage()); + return Selenide.open("/", Navigation.class); + } + + private static void clearStorage(Consumer<WebStorage> cleaner) { + try { + cleaner.accept((WebStorage) WebDriverRunner.getWebDriver()); + } catch (Exception e) { + // ignore, it may occur when the first test opens browser. No pages are loaded + // and local/session storages are not available yet. + // Example with Chrome: "Failed to read the 'localStorage' property from 'Window': Storage is disabled inside 'data:' URLs." + } + } + + public Navigation openHome() { + return open("/", Navigation.class); + } + + public ProjectsPage openProjects() { + return open("/projects", ProjectsPage.class); + } + + public ProjectsPage openProjects(String organization) { + return open("/organizations/" + organization + "/projects", ProjectsPage.class); + } + + public ProjectsPage openProjectsWithQuery(String query) { + return open("/projects?" + query, ProjectsPage.class); + } + + public IssuesPage openIssues() { + return open("/issues", IssuesPage.class); + } + + public IssuesPage openIssues(String organization) { + return open("/organizations/" + organization + "/issues", IssuesPage.class); + } + + public IssuesPage openComponentIssues(String component) { + return open("/component_issues?id=" + component, IssuesPage.class); + } + + public ProjectDashboardPage openProjectDashboard(String projectKey) { + // TODO encode projectKey + String url = "/dashboard?id=" + projectKey; + return open(url, ProjectDashboardPage.class); + } + + public ProjectLinksPage openProjectLinks(String projectKey) { + // TODO encode projectKey + String url = "/project/links?id=" + projectKey; + return open(url, ProjectLinksPage.class); + } + + public QualityGatePage openQualityGates() { + String url = "/quality_gates"; + return open(url, QualityGatePage.class); + } + + public QualityGatePage openQualityGates(String organization) { + String url = "/organizations/" + organization + "/quality_gates"; + return open(url, QualityGatePage.class); + } + + public ProjectQualityGatePage openProjectQualityGate(String projectKey) { + // TODO encode projectKey + String url = "/project/quality_gate?id=" + projectKey; + return open(url, ProjectQualityGatePage.class); + } + + public ProjectKeyPage openProjectKey(String projectKey) { + // TODO encode projectKey + String url = "/project/key?id=" + projectKey; + return open(url, ProjectKeyPage.class); + } + + public ProjectActivityPage openProjectActivity(String projectKey) { + // TODO encode projectKey + String url = "/project/activity?id=" + projectKey; + return open(url, ProjectActivityPage.class); + } + + public MeasuresPage openProjectMeasures(String projectKey) { + // TODO encode projectKey + String url = "/component_measures?id=" + projectKey; + return open(url, MeasuresPage.class); + } + + public ProjectCodePage openCode(String projectKey) { + // TODO encode projectKey + String url = "/code?id=" + projectKey; + return open(url, ProjectCodePage.class); + } + + public ProjectCodePage openCode(String projectKey, String selected) { + // TODO encode projectKey and selected + String url = "/code?id=" + projectKey + "&selected=" + selected; + return open(url, ProjectCodePage.class); + } + + public MembersPage openOrganizationMembers(String orgKey) { + String url = "/organizations/" + orgKey + "/members"; + return open(url, MembersPage.class); + } + + public QualityProfilePage openQualityProfile(String language, String name, String organization) { + String profileUrl = "/quality_profiles/show?language=" + language + "&name=" + name; + return open("/organizations/" + organization + profileUrl, QualityProfilePage.class); + } + + public BackgroundTasksPage openBackgroundTasksPage() { + return open("/background_tasks", BackgroundTasksPage.class); + } + + public SettingsPage openSettings(@Nullable String projectKey) throws UnsupportedEncodingException { + String url = projectKey != null ? "/project/settings?id=" + URLEncoder.encode(projectKey, "UTF-8") : "/settings"; + return open(url, SettingsPage.class); + } + + public EncryptionPage openEncryption() { + return open("/settings/encryption", EncryptionPage.class); + } + + public SystemInfoPage openSystemInfo() { + return open("/admin/system", SystemInfoPage.class); + } + + public MarketplacePage openMarketplace() { + return open("/admin/marketplace", MarketplacePage.class); + } + + public NotificationsPage openNotifications() { + return open("/account/notifications", NotificationsPage.class); + } + + public ProjectPermissionsPage openProjectPermissions(String projectKey) { + String url = "/project_roles?id=" + projectKey; + return open(url, ProjectPermissionsPage.class); + } + + public ProjectsManagementPage openProjectsManagement() { + return open("/projects_admin", ProjectsManagementPage.class); + } + + public LoginPage openLogin() { + return open("/sessions/login", LoginPage.class); + } + + public void open(String relativeUrl) { + Selenide.open(relativeUrl); + } + + public <P> P open(String relativeUrl, Class<P> pageObjectClassClass) { + return Selenide.open(relativeUrl, pageObjectClassClass); + } + + public Navigation shouldBeLoggedIn() { + loggedInDropdown().should(Condition.visible); + return this; + } + + public Navigation shouldNotBeLoggedIn() { + logInLink().should(Condition.visible); + return this; + } + + public LoginPage logIn() { + logInLink().click(); + return Selenide.page(LoginPage.class); + } + + public Navigation logOut() { + SelenideElement dropdown = loggedInDropdown(); + // click must be on the <a> but not on the dropdown <li> + // for compatibility with phantomjs + dropdown.find(".dropdown-toggle").click(); + dropdown.find(By.linkText("Log out")).click(); + return this; + } + + public RulesPage openRules() { + return open("/coding_rules", RulesPage.class); + } + + public SelenideElement clickOnQualityProfiles() { + return Selenide.$(By.linkText("Quality Profiles")); + } + + public SelenideElement getRightBar() { + return Selenide.$("#global-navigation .navbar-right"); + } + + public SelenideElement getFooter() { + return Selenide.$("#footer"); + } + + public SelenideElement getErrorMessage() { + return Selenide.$("#error"); + } + + private SelenideElement logInLink() { + return Selenide.$(By.linkText("Log in")); + } + + private SelenideElement loggedInDropdown() { + return Selenide.$(".js-user-authenticated"); + } + + public Navigation shouldBeRedirectedToLogin() { + Selenide.$("#login_form").should(Condition.visible); + return this; + } + +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/NotificationsPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/NotificationsPage.java new file mode 100644 index 00000000000..bd4911a94c6 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/NotificationsPage.java @@ -0,0 +1,118 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; + +public class NotificationsPage extends Navigation { + + private final String EMAIL = "EmailNotificationChannel"; + + public NotificationsPage() { + Selenide.$("#account-page").shouldHave(Condition.text("Overall notifications")); + } + + public NotificationsPage shouldHaveGlobalNotification(String type) { + return shouldHaveGlobalNotification(type, EMAIL); + } + + public NotificationsPage shouldHaveGlobalNotification(String type, String channel) { + return shouldBeChecked(globalCheckboxSelector(type, channel)); + } + + public NotificationsPage shouldNotHaveGlobalNotification(String type) { + return shouldNotHaveGlobalNotification(type, EMAIL); + } + + public NotificationsPage shouldNotHaveGlobalNotification(String type, String channel) { + return shouldNotBeChecked(globalCheckboxSelector(type, channel)); + } + + public NotificationsPage shouldHaveProjectNotification(String project, String type, String channel) { + return shouldBeChecked(projectCheckboxSelector(project, type, channel)); + } + + public NotificationsPage shouldNotHaveProjectNotification(String project, String type, String channel) { + return shouldNotBeChecked(projectCheckboxSelector(project, type, channel)); + } + + public NotificationsPage addGlobalNotification(String type) { + return addGlobalNotification(type, EMAIL); + } + + public NotificationsPage addGlobalNotification(String type, String channel) { + shouldNotHaveGlobalNotification(type, channel); + toggleCheckbox(globalCheckboxSelector(type, channel)); + shouldHaveGlobalNotification(type, channel); + return this; + } + + public NotificationsPage removeGlobalNotification(String type) { + return removeGlobalNotification(type, EMAIL); + } + + public NotificationsPage removeGlobalNotification(String type, String channel) { + shouldHaveGlobalNotification(type, channel); + toggleCheckbox(globalCheckboxSelector(type, channel)); + shouldNotHaveGlobalNotification(type, channel); + return this; + } + + public NotificationsPage addProjectNotification(String project, String type, String channel) { + shouldNotHaveProjectNotification(project, type, channel); + toggleCheckbox(projectCheckboxSelector(project, type, channel)); + shouldHaveProjectNotification(project, type, channel); + return this; + } + + public NotificationsPage removeProjectNotification(String project, String type, String channel) { + shouldHaveProjectNotification(project, type, channel); + toggleCheckbox(projectCheckboxSelector(project, type, channel)); + shouldNotHaveProjectNotification(project, type, channel); + return this; + } + + private String globalCheckboxSelector(String type, String channel) { + return "#global-notification-" + type + "-" + channel; + } + + private String projectCheckboxSelector(String project, String type, String channel) { + return "#project-notification-" + project + "-" + type + "-" + channel; + } + + private NotificationsPage shouldBeChecked(String selector) { + Selenide.$(selector) + .shouldBe(Condition.visible) + .shouldHave(Condition.cssClass("icon-checkbox-checked")); + return this; + } + + private NotificationsPage shouldNotBeChecked(String selector) { + Selenide.$(selector) + .shouldBe(Condition.visible) + .shouldNotHave(Condition.cssClass("icon-checkbox-checked")); + return this; + } + + private void toggleCheckbox(String selector) { + Selenide.$(selector).click(); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectActivityPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectActivityPage.java new file mode 100644 index 00000000000..ad8206cd47d --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectActivityPage.java @@ -0,0 +1,60 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import java.util.List; +import java.util.stream.Collectors; + +public class ProjectActivityPage { + + public ProjectActivityPage() { + Selenide.$("#project-activity").should(Condition.exist); + } + + public ElementsCollection getAnalyses() { + return Selenide.$$(".project-activity-analysis"); + } + + public List<ProjectAnalysisItem> getAnalysesAsItems() { + return getAnalyses() + .stream() + .map(ProjectAnalysisItem::new) + .collect(Collectors.toList()); + } + + public ProjectAnalysisItem getLastAnalysis() { + return new ProjectAnalysisItem(Selenide.$(".project-activity-analysis")); + } + + public ProjectAnalysisItem getFirstAnalysis() { + return new ProjectAnalysisItem(Selenide.$$(".project-activity-analysis").last()); + } + + public ProjectActivityPage assertFirstAnalysisOfTheDayHasText(String day, String text) { + Selenide.$("#project-activity") + .find(".project-activity-day[data-day=\"" + day + "\"]") + .find(".project-activity-analysis") + .should(Condition.hasText(text)); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectAnalysisItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectAnalysisItem.java new file mode 100644 index 00000000000..2f6d4449c4d --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectAnalysisItem.java @@ -0,0 +1,102 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class ProjectAnalysisItem { + + private final SelenideElement elt; + + public ProjectAnalysisItem(SelenideElement elt) { + this.elt = elt; + } + + public ProjectAnalysisItem shouldHaveEventWithText(String text) { + elt.find(".project-activity-events").shouldHave(Condition.text(text)); + return this; + } + + public ProjectAnalysisItem shouldHaveDeleteButton() { + elt.find(".js-analysis-actions").click(); + elt.find(".js-delete-analysis").shouldBe(Condition.visible); + return this; + } + + public ProjectAnalysisItem shouldNotHaveDeleteButton() { + elt.find(".js-analysis-actions").click(); + elt.find(".js-delete-analysis").shouldNotBe(Condition.visible); + return this; + } + + public void delete() { + elt.find(".js-analysis-actions").click(); + elt.find(".js-delete-analysis").click(); + + SelenideElement modal = Selenide.$(".modal"); + modal.shouldBe(Condition.visible); + modal.find("button[type=\"submit\"]").click(); + + elt.shouldNotBe(Condition.visible); + } + + public ProjectAnalysisItem addCustomEvent(String name) { + elt.find(".js-analysis-actions").click(); + elt.find(".js-add-event").click(); + + SelenideElement modal = Selenide.$(".modal"); + modal.shouldBe(Condition.visible); + modal.find("input").setValue(name); + modal.find("button[type=\"submit\"]").click(); + + elt.find(".project-activity-event:first-child").shouldHave(Condition.text(name)); + return this; + } + + public ProjectAnalysisItem changeFirstEvent(String newName) { + SelenideElement firstEvent = elt.find(".project-activity-event:first-child"); + firstEvent.find(".js-change-event").click(); + + SelenideElement modal = Selenide.$(".modal"); + modal.shouldBe(Condition.visible); + modal.find("input").setValue(newName); + modal.find("button[type=\"submit\"]").click(); + + firstEvent.shouldHave(Condition.text(newName)); + return this; + } + + public ProjectAnalysisItem deleteFirstEvent() { + int eventsCount = elt.findAll(".project-activity-event").size(); + + SelenideElement firstEvent = elt.find(".project-activity-event:first-child"); + firstEvent.find(".js-delete-event").click(); + + SelenideElement modal = Selenide.$(".modal"); + modal.shouldBe(Condition.visible); + modal.find("button[type=\"submit\"]").click(); + + elt.findAll(".project-activity-event").shouldHaveSize(eventsCount - 1); + + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectCodePage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectCodePage.java new file mode 100644 index 00000000000..42bb86748a2 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectCodePage.java @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; + +public class ProjectCodePage { + + public ProjectCodePage() { + } + + public ProjectCodePage openFirstComponent() { + Selenide.$$(".code-name-cell a").first().click(); + return this; + } + + public ProjectCodePage search(String query) { + Selenide.$(".code-search .search-box-input").val(query); + return this; + } + + public ProjectCodePage shouldHaveComponent(String name) { + Selenide.$(".code-components").shouldHave(Condition.text(name)); + return this; + } + + public ProjectCodePage shouldHaveCode(String code) { + Selenide.$(".code-components .source-viewer").shouldHave(Condition.text(code)); + return this; + } + + public ProjectCodePage shouldHaveBreadcrumbs(String... breadcrumbs) { + for (String breadcrumb : breadcrumbs) { + Selenide.$(".code-breadcrumbs").shouldHave(Condition.text(breadcrumb)); + } + return this; + } + + public ProjectCodePage shouldSearchResult(String name) { + Selenide.$(".code-search-with-results").shouldHave(Condition.text(name)); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectDashboardPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectDashboardPage.java new file mode 100644 index 00000000000..4db286489dd --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectDashboardPage.java @@ -0,0 +1,107 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import java.util.Arrays; +import org.openqa.selenium.By; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class ProjectDashboardPage { + + public ProjectDashboardPage() { + Selenide.$(".overview").shouldBe(Condition.visible); + } + + public SelenideElement getLinesOfCode() { + SelenideElement element = Selenide.$("#overview-ncloc"); + element.shouldBe(Condition.visible); + return element; + } + + public SelenideElement getLanguageDistribution() { + SelenideElement element = Selenide.$("#overview-language-distribution"); + element.shouldBe(Condition.visible); + return element; + } + + public SelenideElement getOverviewMeasure(String measure) { + ElementsCollection measures = Selenide.$$(".overview-domain-measure"); + SelenideElement element = measures.find(Condition.text(measure)).shouldBe(Condition.visible); + return element; + } + + private SelenideElement getTagsMeta() { + SelenideElement element = Selenide.$(".overview-meta-tags"); + element.shouldBe(Condition.visible); + return element; + } + + public ProjectDashboardPage shouldHaveTags(String... tags) { + String tagsList = String.join(", ", Arrays.asList(tags)); + this.getTagsMeta().$(".tags-list > span").should(Condition.hasText(tagsList)); + return this; + } + + public ProjectDashboardPage shouldNotBeEditable() { + SelenideElement tagsElem = this.getTagsMeta(); + tagsElem.$("button").shouldNot(Condition.exist); + tagsElem.$("div.multi-select").shouldNot(Condition.exist); + return this; + } + + public ProjectDashboardPage shouldBeEditable() { + SelenideElement tagsElem = this.getTagsMeta(); + tagsElem.$("button").shouldBe(Condition.visible); + return this; + } + + public ProjectDashboardPage openTagEditor() { + SelenideElement tagsElem = this.getTagsMeta(); + tagsElem.$("button").shouldBe(Condition.visible).click(); + tagsElem.$("div.multi-select").shouldBe(Condition.visible); + return this; + } + + public SelenideElement getTagAtIdx(Integer idx) { + SelenideElement tagsElem = this.getTagsMeta(); + tagsElem.$("div.multi-select").shouldBe(Condition.visible); + return tagsElem.$$("ul.menu a").get(idx); + } + + public ProjectDashboardPage sendKeysToTagsInput(CharSequence... charSequences) { + SelenideElement tagsInput = this.getTagsMeta().find("input"); + tagsInput.sendKeys(charSequences); + return this; + } + + public ProjectDashboardPage hasQualityGateLink(String name, String link) { + SelenideElement elem = Selenide.$$(".overview-meta-card") + .findBy(Condition.text("Quality Gate")).should(Condition.exist) + .find(By.linkText(name)).should(Condition.exist); + assertThat(elem.attr("href")).endsWith(link); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectKeyPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectKeyPage.java new file mode 100644 index 00000000000..5a3e5ec678b --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectKeyPage.java @@ -0,0 +1,100 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class ProjectKeyPage { + + public ProjectKeyPage() { + Selenide.$("#project-key").should(Condition.exist); + } + + public ProjectKeyPage assertSimpleUpdate() { + Selenide.$("#update-key-new-key").shouldBe(Condition.visible); + Selenide.$("#update-key-submit").shouldBe(Condition.visible); + return this; + } + + public ProjectKeyPage trySimpleUpdate(String newKey) { + Selenide.$("#update-key-new-key").val(newKey); + Selenide.$("#update-key-submit").click(); + Selenide.$("#update-key-confirm").click(); + return this; + } + + public ProjectKeyPage openFineGrainedUpdate() { + Selenide.$("#update-key-tab-fine").click(); + Selenide.$("#project-key-fine-grained-update").shouldBe(Condition.visible); + return this; + } + + public ProjectKeyPage tryFineGrainedUpdate(String key, String newKey) { + SelenideElement form = Selenide.$(".js-fine-grained-update[data-key=\"" + key + "\"]"); + form.shouldBe(Condition.visible); + + form.$("input").val(newKey); + form.$("button").click(); + + Selenide.$("#update-key-confirm").click(); + return this; + } + + public ProjectKeyPage assertBulkChange() { + Selenide.$("#bulk-update-replace").shouldBe(Condition.visible); + Selenide.$("#bulk-update-by").shouldBe(Condition.visible); + Selenide.$("#bulk-update-see-results").shouldBe(Condition.visible); + return this; + } + + public ProjectKeyPage simulateBulkChange(String replace, String by) { + Selenide.$("#bulk-update-replace").val(replace); + Selenide.$("#bulk-update-by").val(by); + Selenide.$("#bulk-update-see-results").click(); + + Selenide.$("#bulk-update-simulation").shouldBe(Condition.visible); + return this; + } + + public ProjectKeyPage assertBulkChangeSimulationResult(String oldKey, String newKey) { + SelenideElement row = Selenide.$("#bulk-update-results").$("[data-key=\"" + oldKey + "\"]"); + row.$(".js-old-key").should(Condition.hasText(oldKey)); + row.$(".js-new-key").should(Condition.hasText(newKey)); + return this; + } + + public ProjectKeyPage assertDuplicated(String oldKey) { + SelenideElement row = Selenide.$("#bulk-update-results").$("[data-key=\"" + oldKey + "\"]"); + row.$(".js-new-key").$(".badge-danger").shouldBe(Condition.visible); + return this; + } + + public ProjectKeyPage confirmBulkUpdate() { + Selenide.$("#bulk-update-confirm").click(); + return this; + } + + public ProjectKeyPage assertSuccessfulBulkUpdate() { + Selenide.$("#project-key-bulk-update").$(".alert.alert-success").shouldBe(Condition.visible); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectLinkItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectLinkItem.java new file mode 100644 index 00000000000..7444ca554ac --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectLinkItem.java @@ -0,0 +1,52 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.SelenideElement; +import org.openqa.selenium.NoSuchElementException; + +public class ProjectLinkItem { + + private final SelenideElement elt; + + public ProjectLinkItem(SelenideElement elt) { + this.elt = elt; + } + + public SelenideElement getName() { + return elt.$(".js-name"); + } + + public SelenideElement getType() { + try { + return elt.$(".js-type"); + } catch (NoSuchElementException e) { + return null; + } + } + + public SelenideElement getUrl() { + return elt.$(".js-url"); + } + + public SelenideElement getDeleteButton() { + return elt.$(".js-delete-button"); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectLinksPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectLinksPage.java new file mode 100644 index 00000000000..8f9e8860f5a --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectLinksPage.java @@ -0,0 +1,44 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import java.util.List; +import java.util.stream.Collectors; + +public class ProjectLinksPage { + + public ProjectLinksPage() { + Selenide.$("#project-links").should(Condition.exist); + } + + public ElementsCollection getLinks() { + return Selenide.$$("#project-links tr[data-name]"); + } + + public List<ProjectLinkItem> getLinksAsItems() { + return getLinks() + .stream() + .map(ProjectLinkItem::new) + .collect(Collectors.toList()); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectPermissionsPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectPermissionsPage.java new file mode 100644 index 00000000000..0fabc151b7d --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectPermissionsPage.java @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; + +public class ProjectPermissionsPage { + + public ProjectPermissionsPage() { + Selenide.$("#project-permissions-page").should(Condition.exist); + } + + public ProjectPermissionsPage shouldBePublic() { + Selenide.$("#visibility-public .icon-radio.is-checked").shouldBe(Condition.visible); + return this; + } + + public ProjectPermissionsPage shouldBePrivate() { + Selenide.$("#visibility-private .icon-radio.is-checked").shouldBe(Condition.visible); + return this; + } + + public ProjectPermissionsPage turnToPublic() { + Selenide.$("#visibility-public").click(); + Selenide.$("#confirm-turn-to-public").click(); + shouldBePublic(); + return this; + } + + public ProjectPermissionsPage turnToPrivate() { + Selenide.$("#visibility-private").click(); + shouldBePrivate(); + return this; + } + + public ProjectPermissionsPage shouldNotAllowPrivate() { + Selenide.$("#visibility-private").shouldHave(Condition.cssClass("text-muted")); + Selenide.$(".upgrade-organization-box").shouldBe(Condition.visible); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectQualityGatePage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectQualityGatePage.java new file mode 100644 index 00000000000..0cf3904c640 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectQualityGatePage.java @@ -0,0 +1,44 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class ProjectQualityGatePage { + + public ProjectQualityGatePage() { + Selenide.$("#project-quality-gate").should(Condition.exist); + } + + public SelenideElement getSelectedQualityGate() { + return Selenide.$(".Select-value-label"); + } + + public void assertNotSelected() { + Selenide.$(".Select-placeholder").should(Condition.exist); + Selenide.$(".Select-value-label").shouldNot(Condition.exist); + } + + public void setQualityGate(String name) { + Selenide.$(".Select-input input").val(name).pressEnter(); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectsManagementPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectsManagementPage.java new file mode 100644 index 00000000000..529c98abb25 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/ProjectsManagementPage.java @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; + +public class ProjectsManagementPage { + + public ProjectsManagementPage() { + Selenide.$("#projects-management-page").should(Condition.exist); + } + + public ProjectsManagementPage shouldHaveProjectsCount(int count) { + Selenide.$$("#projects-management-page-projects tbody tr").shouldHaveSize(count); + return this; + } + + public ProjectsManagementPage shouldHaveProject(String key) { + Selenide.$("#projects-management-page-projects").shouldHave(Condition.text(key)); + return this; + } + + public ProjectsManagementPage createProject(String key, String name, String visibility) { + Selenide.$("#create-project").click(); + Selenide.$("#create-project-name").val(key); + Selenide.$("#create-project-key").val(name); + Selenide.$("#visibility-" + visibility).click(); + Selenide.$("#create-project-submit").submit(); + return this; + } + + public ProjectsManagementPage bulkApplyPermissionTemplate(String template) { + Selenide.$(".js-bulk-apply-permission-template").click(); + Selenide.$(".modal .Select-value").click(); + Selenide.$$(".modal .Select-option").findBy(Condition.text(template)).click(); + Selenide.$(".modal-foot button").click(); + Selenide.$(".modal-body .alert-success").shouldBe(Condition.visible); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityGatePage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityGatePage.java new file mode 100644 index 00000000000..2f8f1669123 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityGatePage.java @@ -0,0 +1,54 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; + +public class QualityGatePage { + public QualityGatePage() { + Selenide.$("#quality-gates-page").shouldBe(Condition.visible); + } + + public QualityGatePage countQualityGates(Integer count) { + Selenide.$$("#quality-gates-page .list-group-item").shouldHaveSize(count); + return this; + } + + public QualityGatePage canCreateQG() { + Selenide.$("#quality-gate-add").should(Condition.exist).shouldBe(Condition.visible); + return this; + } + + public QualityGatePage canNotCreateQG() { + Selenide.$("#quality-gate-add").shouldNot(Condition.exist); + return this; + } + + public QualityGatePage displayIntro() { + Selenide.$(".search-navigator-intro").should(Condition.exist).shouldBe(Condition.visible); + return this; + } + + public QualityGatePage displayQualityGateDetail(String qualityGateName) { + Selenide.$(".layout-page-main-header").shouldHave(Condition.text(qualityGateName)); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java new file mode 100644 index 00000000000..88b009687b0 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java @@ -0,0 +1,54 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; + +public class QualityProfilePage { + public QualityProfilePage() { + Selenide.$("#quality-profile").shouldBe(Condition.visible); + } + + public QualityProfilePage shouldHaveMissingSonarWayRules(Integer nbRules) { + Selenide.$(".quality-profile-rules-sonarway-missing") + .shouldBe(Condition.visible) + .$("a").shouldHave(Condition.text(nbRules.toString())); + return this; + } + + public RulesPage showMissingSonarWayRules() { + Selenide.$(".quality-profile-rules-sonarway-missing") + .shouldBe(Condition.visible).$("a").click(); + Selenide.$(".coding-rules").shouldBe(Condition.visible); + return Selenide.page(RulesPage.class); + } + + public QualityProfilePage shouldHaveAssociatedProject(String projectName) { + Selenide.$(".js-profile-project").shouldHave(Condition.text(projectName)); + return this; + } + + public QualityProfilePage shouldAllowToChangeProjects() { + Selenide.$(".js-change-projects").shouldBe(Condition.visible).click(); + Selenide.$("#profile-projects .select-list-list").shouldBe(Condition.visible); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RuleDetails.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RuleDetails.java new file mode 100644 index 00000000000..035a66f3019 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RuleDetails.java @@ -0,0 +1,39 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class RuleDetails { + + private final SelenideElement elt; + + public RuleDetails(SelenideElement elt) { + this.elt = elt; + } + + public RuleDetails shouldBeActivatedOn(String profileName) { + Selenide.$("#coding-rules-detail-quality-profiles").shouldHave(Condition.text(profileName)); + return this; + } + +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RuleItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RuleItem.java new file mode 100644 index 00000000000..7b5d818bc25 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RuleItem.java @@ -0,0 +1,41 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.SelenideElement; + +public class RuleItem { + + private final SelenideElement elt; + + public RuleItem(SelenideElement elt) { + this.elt = elt; + } + + public SelenideElement getTitle() { + return elt.$(".coding-rule-title"); + } + + public SelenideElement getMetadata() { + return elt.$(".coding-rule-meta"); + } + + +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RulesPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RulesPage.java new file mode 100644 index 00000000000..6b2916e5240 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/RulesPage.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import org.openqa.selenium.By; + +public class RulesPage extends Navigation { + + public RulesPage() { + Selenide.$(By.cssSelector(".coding-rules")).should(Condition.exist); + } + + public int getTotal() { + // warning - number is localized + return Integer.parseInt(Selenide.$("#coding-rules-total").text()); + } + + public ElementsCollection getSelectedFacetItems(String facetName) { + SelenideElement facet = Selenide.$(".search-navigator-facet-box[data-property='"+ facetName+"']").shouldBe(Condition.visible); + return facet.$$(".js-facet.active"); + } + + public RulesPage shouldHaveTotalRules(Integer total) { + Selenide.$("#coding-rules-total").shouldHave(Condition.text(total.toString())); + return this; + } + + public RulesPage openFacet(String facet) { + Selenide.$(".search-navigator-facet-box[data-property=\"" + facet + "\"] .js-facet-toggle").click(); + return this; + } + + public RulesPage selectFacetItemByText(String facet, String itemText) { + Selenide.$$(".search-navigator-facet-box[data-property=\"" + facet + "\"] .js-facet") + .findBy(Condition.text(itemText)).click(); + return this; + } + + public RuleDetails openFirstRule() { + Selenide.$$(".js-rule").first().click(); + Selenide.$(".coding-rules-details").shouldBe(Condition.visible); + return new RuleDetails(Selenide.$(".coding-rules-details")); + } + +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/SystemInfoPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/SystemInfoPage.java new file mode 100644 index 00000000000..5b93e2b457a --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/SystemInfoPage.java @@ -0,0 +1,46 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.CollectionCondition; +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class SystemInfoPage { + public SystemInfoPage() { + Selenide.$(".page-title").should(Condition.exist).shouldHave(Condition.text("System Info")); + } + + public SystemInfoPage shouldHaveCard(String title) { + Selenide.$$(".system-info-health-card-title").find(Condition.text(title)).should(Condition.exist); + return this; + } + + public SystemInfoPage shouldHaveCards(String... titles) { + Selenide.$$(".system-info-health-card-title").shouldHave(CollectionCondition.texts(titles)); + return this; + } + + public SystemInfoPageItem getCardItem(String card) { + SelenideElement cardTitle = Selenide.$$(".system-info-health-card-title").find(Condition.text(card)).should(Condition.exist); + return new SystemInfoPageItem(cardTitle.parent().parent()); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/SystemInfoPageItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/SystemInfoPageItem.java new file mode 100644 index 00000000000..55d9c84092e --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/SystemInfoPageItem.java @@ -0,0 +1,85 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.SelenideElement; + +public class SystemInfoPageItem { + private final SelenideElement elt; + + public SystemInfoPageItem(SelenideElement elt) { + this.elt = elt; + } + + public SystemInfoPageItem shouldHaveHealth() { + elt.$(".system-info-health-info .status-indicator").should(Condition.exist); + return this; + } + + public SystemInfoPageItem shouldHaveSection(String section) { + ensureOpen(); + elt.$$("h4").findBy(Condition.text(section)).should(Condition.exist); + return this; + } + + public SystemInfoPageItem shouldNotHaveSection(String section) { + ensureOpen(); + elt.$$("h4").findBy(Condition.text(section)).shouldNot(Condition.exist); + return this; + } + + public SystemInfoPageItem shouldHaveMainSection() { + ensureOpen(); + elt.$$(".system-info-section").get(0).find("h4").shouldNot(Condition.exist); + return this; + } + + public SystemInfoPageItem shouldHaveField(String field) { + ensureOpen(); + elt.$$(".system-info-section-item-name").findBy(Condition.text(field)).should(Condition.exist); + return this; + } + + public SystemInfoPageItem shouldNotHaveField(String field) { + ensureOpen(); + elt.$$(".system-info-section-item-name").findBy(Condition.exactText(field)).shouldNot(Condition.exist); + return this; + } + + public SystemInfoPageItem shouldHaveFieldWithValue(String field, String value) { + ensureOpen(); + SelenideElement fieldElem = elt.$$(".system-info-section-item-name").findBy(Condition.text(field)).should(Condition.exist); + fieldElem.parent().parent().$$("td").shouldHaveSize(2).get(1).shouldHave(Condition.text(value)); + return this; + } + + public SystemInfoPageItem ensureOpen() { + if(!isOpen()) { + elt.click(); + elt.$(".boxed-group-inner").should(Condition.exist); + } + return this; + } + + private boolean isOpen() { + return elt.$(".boxed-group-inner").exists(); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/issues/Issue.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/issues/Issue.java new file mode 100644 index 00000000000..d4e2713112e --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/issues/Issue.java @@ -0,0 +1,64 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.issues; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class Issue { + + private final SelenideElement elt; + + public Issue(SelenideElement elt) { + this.elt = elt; + } + + public Issue shouldAllowAssign() { + elt.find(".js-issue-assign").shouldBe(Condition.visible); + return this; + } + + public Issue shouldAllowChangeType() { + elt.find(".js-issue-set-type").shouldBe(Condition.visible); + return this; + } + + public Issue shouldNotAllowAssign() { + elt.find(".js-issue-assign").shouldNotBe(Condition.visible); + return this; + } + + public Issue shouldNotAllowChangeType() { + elt.find(".js-issue-set-type").shouldNotBe(Condition.visible); + return this; + } + + public Issue assigneeSearchResultCount(String query, Integer count) { + SelenideElement assignLink = elt.find(".js-issue-assign"); + assignLink.click(); + SelenideElement popupMenu = Selenide.$(".bubble-popup ul.menu").shouldBe(Condition.visible); + Selenide.$(".bubble-popup input.search-box-input").shouldBe(Condition.visible).val("").sendKeys(query); + popupMenu.$("li a[data-text='Not assigned']").shouldNot(Condition.exist); + popupMenu.$$("li").shouldHaveSize(count); + assignLink.click(); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/issues/IssuesPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/issues/IssuesPage.java new file mode 100644 index 00000000000..92755921f37 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/issues/IssuesPage.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.issues; + +import com.codeborne.selenide.CollectionCondition; +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import java.util.List; +import java.util.stream.Collectors; + +public class IssuesPage { + + public IssuesPage() { + Selenide.$(".issues").should(Condition.exist); + } + + private ElementsCollection getIssuesElements() { + return Selenide.$$(".issues .issue"); + } + + private ElementsCollection getIssuesPathComponents() { + return Selenide.$$(".issues-workspace-list-component"); + } + + public List<Issue> getIssues() { + return getIssuesElements() + .stream() + .map(Issue::new) + .collect(Collectors.toList()); + } + + public IssuesPage issuesCount(Integer count) { + this.getIssuesElements().shouldHaveSize(count); + return this; + } + + public Issue getFirstIssue() { + getIssuesElements().shouldHave(CollectionCondition.sizeGreaterThan(0)); + return new Issue(getIssuesElements().first()); + } + + public IssuesPage componentsShouldContain(String path) { + this.getIssuesPathComponents().forEach(element -> element.shouldHave(Condition.text(path))); + return this; + } + + public IssuesPage componentsShouldNotContain(String path) { + this.getIssuesPathComponents().forEach(element -> element.shouldNotHave(Condition.text(path))); + return this; + } + + public IssuesPage bulkChangeOpen() { + Selenide.$("#issues-bulk-change").shouldBe(Condition.visible).click(); + Selenide.$("#bulk-change-form").shouldBe(Condition.visible); + return this; + } + + public IssuesPage bulkChangeAssigneeSearchCount(String query, Integer count) { + Selenide.$("#issues-bulk-change-assignee .Select-input input").val(query); + Selenide.$$("#issues-bulk-change-assignee .Select-option").shouldHaveSize(count); + Selenide.$("#issues-bulk-change-assignee .Select-input input").pressEscape(); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasureContent.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasureContent.java new file mode 100644 index 00000000000..4f3da0472e5 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasureContent.java @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.measures; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.SelenideElement; + +public class MeasureContent { + private final SelenideElement elt; + + public MeasureContent(SelenideElement elt) { + this.elt = elt; + } + + public MeasureContent shouldHaveTitle(String title) { + this.elt.$(".measure-details-header .measure-details-metric").should(Condition.exist).shouldHave(Condition.text(title)); + return this; + } + + public MeasureContent shouldHaveHeaderValue(String value) { + this.elt.$(".measure-details-header .measure-details-value").should(Condition.exist).shouldHave(Condition.text(value)); + return this; + } + + public MeasureContent shouldHaveFile(String path) { + this.getFiles().find(Condition.text(path)).should(Condition.exist); + return this; + } + + public MeasureContent drillDown(String item) { + this.getFiles().find(Condition.text(item)).should(Condition.exist).find("a").click(); + return this; + } + + public MeasureContent shouldDisplayCode() { + this.elt.$(".source-line-code").should(Condition.exist); + return this; + } + + private ElementsCollection getFiles() { + return this.elt.$$(".measure-details-component-row"); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasuresPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasuresPage.java new file mode 100644 index 00000000000..de052a403de --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/measures/MeasuresPage.java @@ -0,0 +1,97 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.measures; + +import com.codeborne.selenide.CollectionCondition; +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import org.openqa.selenium.Keys; + +public class MeasuresPage { + public MeasuresPage() { + Selenide.$("#component-measures").should(Condition.exist); + } + + public MeasuresPage displayBubbleChart(String title) { + SelenideElement bubblechart = Selenide.$("#component-measures .measure-overview-bubble-chart"); + bubblechart.$(".measure-overview-bubble-chart-title").shouldHave(Condition.text(title)); + return this; + } + + public MeasuresPage measureHasValue(String measure, Integer value) { + SelenideElement sidebar = this.getSideBar(); + sidebar.$("#measure-" + measure + "-name").should(Condition.exist); + sidebar.$("#measure-" + measure + "-value").should(Condition.exist).shouldHave(Condition.text(value.toString())); + return this; + } + + public MeasuresPage measureHasLeak(String measure, Integer value) { + SelenideElement sidebar = this.getSideBar(); + sidebar.$("#measure-" + measure + "-name").should(Condition.exist); + sidebar.$("#measure-" + measure + "-leak").should(Condition.exist).shouldHave(Condition.text(value.toString())); + return this; + } + + public MeasuresPage breadcrumbsShouldHave(String item) { + Selenide.$(".layout-page-header-panel .measure-breadcrumbs").shouldHave(Condition.text(item)); + return this; + } + + public MeasuresPage breadcrumbsShouldNotHave(String item) { + Selenide.$(".layout-page-header-panel .measure-breadcrumbs").shouldNotHave(Condition.text(item)); + return this; + } + + public MeasuresPage backShortcut() { + Selenide.$(".layout-page-header-panel").sendKeys(Keys.LEFT); + return this; + } + + public MeasuresPage switchView(String view) { + SelenideElement select = Selenide.$(".measure-view-select").should(Condition.exist); + select.click(); + select.$(".Select-menu-outer").should(Condition.exist) + .$$(".Select-option").shouldHave(CollectionCondition.sizeGreaterThan(1)) + .find(Condition.text(view)).should(Condition.exist).click(); + return this; + } + + public MeasuresPage openFacet(String facet) { + SelenideElement facetBox = Selenide.$$(".search-navigator-facet-box").find(Condition.text(facet)); + if(!facetBox.find("search-navigator-facet-list").isDisplayed()) { + facetBox.$(".search-navigator-facet-header a").should(Condition.exist).click(); + } + return this; + } + + public MeasureContent openMeasureContent(String measure) { + SelenideElement sidebar = this.getSideBar(); + SelenideElement facetItem = sidebar.$("#measure-" + measure + "-name"); + facetItem.click(); + MeasureContent content = new MeasureContent(Selenide.$("#component-measures .measure-details-content").should(Condition.exist)); + content.shouldHaveTitle(facetItem.getText()); + return content; + } + + private SelenideElement getSideBar() { + return Selenide.$("#component-measures .layout-page-side").should(Condition.exist); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/organization/MemberItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/organization/MemberItem.java new file mode 100644 index 00000000000..fd02dfb1f11 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/organization/MemberItem.java @@ -0,0 +1,94 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonarqube.qa.util.pageobjects.organization; + +import com.codeborne.selenide.CollectionCondition; +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class MemberItem { + private final SelenideElement elt; + + public MemberItem(SelenideElement elt) { + this.elt = elt; + } + + public MemberItem shouldBeNamed(String login, String name) { + ElementsCollection tds = this.elt.$$("td"); + tds.get(1).$("strong").shouldHave(Condition.text(name)); + tds.get(1).$("span").shouldHave(Condition.text(login)); + return this; + } + + public MemberItem shouldHaveGroups(Integer groups) { + ElementsCollection tds = this.elt.$$("td"); + tds.get(2).should(Condition.exist); + tds.get(2).shouldHave(Condition.text(groups.toString())); + return this; + } + + public MemberItem shouldNotHaveActions() { + this.elt.$$("td").shouldHave(CollectionCondition.sizeLessThan(3)); + return this; + } + + public MemberItem removeMembership() { + ElementsCollection tds = this.elt.$$("td"); + tds.shouldHave(CollectionCondition.sizeGreaterThan(3)); + SelenideElement actionTd = tds.get(3); + actionTd.$("button").should(Condition.exist).click(); + actionTd.$$(".dropdown-menu > li").get(2).shouldBe(Condition.visible).click(); + SelenideElement modal = getModal("Remove user"); + modal.$("button.button-red").shouldBe(Condition.visible).click(); + return this; + } + + public MemberItem manageGroupsOpen() { + ElementsCollection tds = this.elt.$$("td"); + tds.shouldHave(CollectionCondition.sizeGreaterThan(3)); + SelenideElement actionTd = tds.get(3); + actionTd.$("button").should(Condition.exist).click(); + actionTd.$$(".dropdown-menu > li").get(0).shouldBe(Condition.visible).click(); + getModal("Manage groups"); + return this; + } + + public MemberItem manageGroupsSelect(String group) { + SelenideElement modal = getModal("Manage groups"); + modal.$$("li").find(Condition.text(group)).shouldBe(Condition.visible).click(); + return this; + } + + public MemberItem manageGroupsSave() { + SelenideElement modal = getModal("Manage groups"); + modal.$("button[type='submit']").shouldBe(Condition.visible).click(); + return this; + } + + private SelenideElement getModal(String title) { + Selenide.$(".modal-head").should(Condition.exist).shouldHave(Condition.text(title)); + SelenideElement form = Selenide.$(".ReactModalPortal form"); + form.should(Condition.exist); + return form; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/organization/MembersPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/organization/MembersPage.java new file mode 100644 index 00000000000..21816aea1c1 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/organization/MembersPage.java @@ -0,0 +1,81 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonarqube.qa.util.pageobjects.organization; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; + +public class MembersPage { + + public MembersPage() { + Selenide.$(".navbar-tabs a.active").shouldBe(Condition.visible).shouldHave(Condition.text("Members")); + } + + public ElementsCollection getMembers() { + return Selenide.$$("table.data tr"); + } + + public MemberItem getMembersByIdx(Integer idx) { + return new MemberItem(getMembers().get(idx)); + } + + public MembersPage shouldHaveTotal(int total) { + Selenide.$(".panel-vertical > span > strong").shouldHave(Condition.text(String.valueOf(total))); + return this; + } + + public MembersPage searchForMember(String query) { + Selenide.$(".page .search-box-input").shouldBe(Condition.visible).val("").sendKeys(query); + return this; + } + + public MembersPage canAddMember() { + Selenide.$(".page-actions").shouldBe(Condition.visible); + return this; + } + + public MembersPage canNotAddMember() { + Selenide.$(".page-actions").shouldNot(Condition.exist); + return this; + } + + public MembersPage addMember(String login) { + this.canAddMember(); + Selenide.$(".page-actions button").click(); + + SelenideElement modal = this.getModal("Add user"); + SelenideElement input = modal.$(".Select-input input"); + input.val(login); + modal.$("div.Select-option.is-focused").should(Condition.exist); + input.pressEnter(); + modal.$("button[type='submit']").click(); + return this; + } + + private SelenideElement getModal(String title) { + Selenide.$(".modal-head").should(Condition.exist).shouldHave(Condition.text(title)); + SelenideElement form = Selenide.$(".ReactModalPortal form"); + form.should(Condition.exist); + return form; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/package-info.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/package-info.java new file mode 100644 index 00000000000..bc9f94356e3 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/package-info.java @@ -0,0 +1,23 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@ParametersAreNonnullByDefault +package org.sonarqube.qa.util.pageobjects; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/FacetItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/FacetItem.java new file mode 100644 index 00000000000..74425419c26 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/FacetItem.java @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.projects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.SelenideElement; + +public class FacetItem { + + private final SelenideElement elt; + + public FacetItem(SelenideElement elt) { + this.elt = elt; + } + + public FacetItem shouldHaveValue(String key, String value) { + this.elt.$(".facet[data-key=\"" + key + "\"] .facet-stat").shouldHave(Condition.text(value)); + return this; + } + + public void selectValue(String key) { + this.elt.$(".facet[data-key=\"" + key + "\"]").click(); + } + + public FacetItem selectOptionItem(String value) { + SelenideElement selectInput = this.elt.$(".Select-input input"); + selectInput.val(value); + this.elt.$("div.Select-option.is-focused").should(Condition.exist); + selectInput.pressEnter(); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/ProjectItem.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/ProjectItem.java new file mode 100644 index 00000000000..45ef2cb62ec --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/ProjectItem.java @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.projects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.SelenideElement; + +public class ProjectItem { + + private final SelenideElement elt; + + public ProjectItem(SelenideElement elt) { + this.elt = elt; + } + + public ProjectItem shouldHaveMeasure(String metricKey, String value) { + this.elt.$(".project-card-measure[data-key=\"" + metricKey + "\"]").shouldHave(Condition.text(value)); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/ProjectsPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/ProjectsPage.java new file mode 100644 index 00000000000..cc55ce2d619 --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/projects/ProjectsPage.java @@ -0,0 +1,116 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.projects; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.ElementsCollection; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import com.codeborne.selenide.WebDriverRunner; +import org.assertj.core.api.Assertions; + +public class ProjectsPage { + + public ProjectsPage() { + Selenide.$("#projects-page").shouldBe(Condition.visible); + } + + public ElementsCollection getProjects() { + return Selenide.$$(".projects-list > .boxed-group"); + } + + public ElementsCollection getFacets() { + return Selenide.$$(".search-navigator-facet-box"); + } + + public ProjectItem getProjectByKey(String projectKey) { + SelenideElement element = getProjects().find(Condition.attribute("data-key", projectKey)); + return new ProjectItem(element); + } + + public ProjectItem getProjectByIdx(Integer idx) { + return new ProjectItem(getProjects().get(idx)); + } + + public FacetItem getFacetByProperty(String facetProperty) { + SelenideElement element = getFacets().find(Condition.attribute("data-key", facetProperty)); + return new FacetItem(element); + } + + public ProjectsPage shouldHaveTotal(int total) { + // warning - number is localized + Selenide.$("#projects-total").shouldHave(Condition.text(String.valueOf(total))); + return this; + } + + public ProjectsPage shouldDisplayAllProjects() { + Assertions.assertThat(WebDriverRunner.url()).endsWith("/projects"); + return this; + } + + public ProjectsPage shouldDisplayAllProjectsWidthSort(String sort) { + Assertions.assertThat(WebDriverRunner.url()).endsWith("/projects?sort=" + sort); + return this; + } + + public ProjectsPage shouldDisplayFavoriteProjects() { + Assertions.assertThat(WebDriverRunner.url()).endsWith("/projects/favorite"); + return this; + } + + public ProjectsPage selectAllProjects() { + Selenide.$("#all-projects").click(); + return shouldDisplayAllProjects(); + } + + public ProjectsPage selectFavoriteProjects() { + Selenide.$("#favorite-projects").click(); + return shouldDisplayFavoriteProjects(); + } + + public ProjectsPage searchProject(String search) { + SelenideElement searchInput = Selenide.$(".projects-topbar-item-search input"); + searchInput.setValue("").sendKeys(search); + return this; + } + + public ProjectsPage changePerspective(String perspective) { + SelenideElement sortSelect = getOpenTopBar().$(".js-projects-perspective-select"); + sortSelect.$(".Select-value").should(Condition.exist).click(); + sortSelect.$(".Select-option[title='" + perspective + "']").should(Condition.exist).click(); + return this; + } + + public ProjectsPage sortProjects(String sort) { + SelenideElement sortSelect = getOpenTopBar().$(".js-projects-sorting-select"); + sortSelect.$(".Select-value").should(Condition.exist).click(); + sortSelect.$(".Select-option[title='" + sort + "']").should(Condition.exist).click(); + return this; + } + + public ProjectsPage invertSorting() { + getOpenTopBar().$(".js-projects-sorting-invert").should(Condition.exist).click(); + return this; + } + + private SelenideElement getOpenTopBar() { + return Selenide.$(".projects-topbar-items").should(Condition.exist); + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/settings/PropertySetInput.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/settings/PropertySetInput.java new file mode 100644 index 00000000000..fb5de082a9c --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/settings/PropertySetInput.java @@ -0,0 +1,47 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.settings; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.SelenideElement; + +public class PropertySetInput { + + private final SelenideElement elt; + + public PropertySetInput(SelenideElement elt) { + this.elt = elt; + } + + public PropertySetInput setFieldValue(int index, String fieldKey, String value) { + elt.findAll("input[name$=\"[" + fieldKey + "]\"]").get(index).val(value); + return this; + } + + public PropertySetInput setFieldValue(String fieldKey, String value) { + return setFieldValue(0, fieldKey, value); + } + + public PropertySetInput save() { + elt.find(".js-save-changes").click(); + elt.find(".js-save-changes").shouldNot(Condition.exist); + return this; + } +} diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/settings/SettingsPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/settings/SettingsPage.java new file mode 100644 index 00000000000..1bc4e646d5d --- /dev/null +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/settings/SettingsPage.java @@ -0,0 +1,80 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonarqube.qa.util.pageobjects.settings; + +import com.codeborne.selenide.Condition; +import com.codeborne.selenide.Selenide; +import com.codeborne.selenide.SelenideElement; +import org.openqa.selenium.By; + +public class SettingsPage { + + public SettingsPage() { + Selenide.$("#settings-page").shouldBe(Condition.visible); + } + + public SettingsPage assertMenuContains(String categoryName) { + Selenide.$(".side-tabs-menu").$(By.linkText(categoryName)).shouldBe(Condition.visible); + return this; + } + + public SettingsPage assertSettingDisplayed(String settingKey) { + Selenide.$(".settings-definition[data-key='" + settingKey + "']").shouldBe(Condition.visible); + return this; + } + + public SettingsPage assertSettingNotDisplayed(String settingKey) { + Selenide.$(".settings-definition[data-key='" + settingKey + "']").shouldNotBe(Condition.visible); + return this; + } + + public SettingsPage openCategory(String categoryName) { + Selenide.$(".side-tabs-menu").$(By.linkText(categoryName)).click(); + return this; + } + + public SettingsPage assertStringSettingValue(String settingKey, String value) { + Selenide.$("input[name=\"settings[" + settingKey + "]\"]").shouldHave(Condition.exactValue(value)); + return this; + } + + public SettingsPage assertBooleanSettingValue(String settingKey, boolean value) { + SelenideElement toggle = Selenide.$("button[name=\"settings[" + settingKey + "]\"]"); + if (value) { + toggle.shouldHave(Condition.cssClass("boolean-toggle-on")); + } else { + toggle.shouldNotHave(Condition.cssClass("boolean-toggle-on")); + } + return this; + } + + public SettingsPage setStringValue(String settingKey, String value) { + SelenideElement setting = Selenide.$(".settings-definition[data-key=\"" + settingKey + "\"]"); + setting.find("input").val(value); + setting.find(".js-save-changes").click(); + setting.find(".js-save-changes").shouldNot(Condition.exist); + return this; + } + + public PropertySetInput getPropertySetInput(String settingKey) { + SelenideElement setting = Selenide.$(".settings-definition[data-key=\"" + settingKey + "\"]"); + return new PropertySetInput(setting); + } +} |