├── src ├── test-project │ ├── gradle.properties │ ├── settings.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── src │ │ ├── main │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── plugin.xml │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── redhat │ │ │ └── devtools │ │ │ └── intellij │ │ │ └── commonuitest │ │ │ ├── fixtures │ │ │ └── test │ │ │ │ ├── mainidewindow │ │ │ │ ├── toolwindowspane │ │ │ │ │ ├── openclose │ │ │ │ │ │ ├── AbstractToolWinPaneTest.java │ │ │ │ │ │ ├── ProjectExplorerPaneTest.java │ │ │ │ │ │ ├── MavenPaneTest.java │ │ │ │ │ │ └── GradlePaneTest.java │ │ │ │ │ ├── BuildViewTest.java │ │ │ │ │ ├── ToolWindowsPaneGradleTest.java │ │ │ │ │ ├── ToolWindowsPaneMavenTest.java │ │ │ │ │ ├── buildtoolpane │ │ │ │ │ │ ├── GradleBuildToolPaneTest.java │ │ │ │ │ │ └── MavenBuildToolPaneTest.java │ │ │ │ │ └── ProjectExplorerTest.java │ │ │ │ ├── menubar │ │ │ │ │ └── MenuBarTest.java │ │ │ │ └── idestatusbar │ │ │ │ │ └── IdeStatusBarTest.java │ │ │ │ └── dialogs │ │ │ │ ├── information │ │ │ │ ├── TipDialogTest.java │ │ │ │ ├── ProjectStructureDialogTest.java │ │ │ │ └── CodeWithMeDialogTest.java │ │ │ │ ├── FlatWelcomeFrameTest.java │ │ │ │ └── settings │ │ │ │ ├── SettingsDialogTest.java │ │ │ │ └── pages │ │ │ │ └── NotificationsPageTest.java │ │ │ ├── utils │ │ │ └── test │ │ │ │ └── screenshot │ │ │ │ └── ScreenshotUtilsTest.java │ │ │ └── AbstractLibraryBaseTest.java │ ├── build.gradle.kts │ └── gradlew.bat └── main │ ├── resources │ ├── accepted │ ├── evaluate_for_free_keys │ │ ├── idea202.evaluation.key │ │ ├── idea203.evaluation.key │ │ ├── idea211.evaluation.key │ │ └── idea212.evaluation.key │ ├── plist │ │ ├── 2022_1 │ │ │ └── com.apple.java.util.prefs.plist │ │ ├── ultimate_all │ │ │ └── com.apple.java.util.prefs.plist │ │ └── 2021_3_and_older │ │ │ └── com.apple.java.util.prefs.plist │ ├── prefs_xml │ │ ├── 2022_1 │ │ │ └── prefs.xml │ │ ├── 2021_3_and_older │ │ │ └── prefs.xml │ │ └── ultimate_all │ │ │ └── prefs.xml │ └── log4j2.xml │ └── java │ └── com │ └── redhat │ └── devtools │ └── intellij │ └── commonuitest │ ├── exceptions │ └── UITestException.java │ ├── utils │ ├── project │ │ └── NewProjectType.java │ ├── constants │ │ ├── ProjectLocation.java │ │ └── ButtonLabels.java │ ├── texttranformation │ │ └── TextUtils.java │ ├── steps │ │ └── SharedSteps.java │ ├── internalerror │ │ └── IdeInternalErrorUtils.java │ ├── build │ │ └── BuildUtils.java │ ├── runner │ │ └── IntelliJVersion.java │ ├── screenshot │ │ └── ScreenshotUtils.java │ └── testextension │ │ └── ScreenshotAfterTestFailExtension.java │ └── fixtures │ ├── mainidewindow │ ├── toolwindowspane │ │ ├── ToolWindowLeftToolbar.java │ │ ├── ToolWindowRightToolbar.java │ │ ├── ToolWindowToolbar.java │ │ ├── buildtoolpane │ │ │ ├── AbstractBuildToolPane.java │ │ │ ├── MavenBuildToolPane.java │ │ │ └── GradleBuildToolPane.java │ │ ├── BuildView.java │ │ └── ToolWindowPane.java │ ├── idestatusbar │ │ └── IdeStatusBar.java │ ├── menubar │ │ └── MenuBar.java │ └── MainIdeWindow.java │ └── dialogs │ ├── errors │ └── IdeFatalErrorsDialog.java │ ├── information │ ├── ProjectStructureDialog.java │ ├── TipDialog.java │ └── CodeWithMeDialog.java │ ├── settings │ ├── pages │ │ └── NotificationsPage.java │ └── SettingsDialog.java │ ├── project │ ├── NewProjectDialogWizard.java │ └── pages │ │ ├── MavenGradleNewProjectFinalPage.java │ │ ├── AbstractNewProjectFinalPage.java │ │ └── JavaNewProjectFinalPage.java │ └── navigation │ └── SearchEverywherePopup.java ├── settings.gradle.kts ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── libs.versions.toml ├── .gitattributes ├── gradle.properties ├── .github ├── dependabot.yml └── workflows │ ├── validate.yml │ ├── nightly.yml │ ├── release.yml │ └── ci.yml ├── .gitignore ├── DCO ├── gradlew.bat ├── CONTRIBUTING.md └── README.md /src/test-project/gradle.properties: -------------------------------------------------------------------------------- 1 | ideaVersion=2024.3 2 | -------------------------------------------------------------------------------- /src/main/resources/accepted: -------------------------------------------------------------------------------- 1 | rsch.send.usage.stat:1.1:0:1607789880884 -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "intellij-common-ui-test-library" 2 | -------------------------------------------------------------------------------- /src/test-project/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "test-project" 2 | includeBuild("../..") 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/test-project/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/test-project/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/evaluate_for_free_keys/idea202.evaluation.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/evaluate_for_free_keys/idea202.evaluation.key -------------------------------------------------------------------------------- /src/main/resources/evaluate_for_free_keys/idea203.evaluation.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/evaluate_for_free_keys/idea203.evaluation.key -------------------------------------------------------------------------------- /src/main/resources/evaluate_for_free_keys/idea211.evaluation.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/evaluate_for_free_keys/idea211.evaluation.key -------------------------------------------------------------------------------- /src/main/resources/evaluate_for_free_keys/idea212.evaluation.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/evaluate_for_free_keys/idea212.evaluation.key -------------------------------------------------------------------------------- /src/main/resources/plist/2022_1/com.apple.java.util.prefs.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/plist/2022_1/com.apple.java.util.prefs.plist -------------------------------------------------------------------------------- /src/main/resources/plist/ultimate_all/com.apple.java.util.prefs.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/plist/ultimate_all/com.apple.java.util.prefs.plist -------------------------------------------------------------------------------- /src/main/resources/plist/2021_3_and_older/com.apple.java.util.prefs.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/HEAD/src/main/resources/plist/2021_3_and_older/com.apple.java.util.prefs.plist -------------------------------------------------------------------------------- /src/main/resources/prefs_xml/2022_1/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /src/test-project/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /src/main/resources/prefs_xml/2021_3_and_older/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/prefs_xml/ultimate_all/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | projectVersion=0.4.6-SNAPSHOT 2 | 3 | # Gradle Releases -> https://github.com/gradle/gradle/releases 4 | gradleVersion=8.5 5 | 6 | # do not verify dependency locally by default. https://docs.gradle.org/current/userguide/dependency_verification.html#sec:disabling-verification 7 | org.gradle.dependency.verification=lenient 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Set update schedule for GitHub Actions and Gradle dependencies 2 | 3 | version: 2 4 | updates: 5 | # Updates for GitHub Actions 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | # Updates for Gradle dependencies 11 | - package-ecosystem: "gradle" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # OS X Files 26 | .DS_Store 27 | 28 | # Build files 29 | .gradle/ 30 | .idea/ 31 | build/ 32 | target/ 33 | pom.xml 34 | 35 | /src/test-project/.intellijPlatform/ 36 | /.intellijPlatform/ 37 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | # libraries 3 | remote-robot = "0.11.23" 4 | kotlin = "2.1.0" 5 | junit-jupiter = "5.12.2" 6 | 7 | # plugins 8 | sonarqube = "5.1.0.4882" 9 | 10 | [libraries] 11 | kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" } 12 | junit-jupiter-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit-jupiter" } 13 | remote-robot = { group = "com.intellij.remoterobot", name = "remote-robot", version.ref = "remote-robot" } 14 | remote-fixtures = { group = "com.intellij.remoterobot", name = "remote-fixtures", version.ref = "remote-robot" } 15 | 16 | [plugins] 17 | sonarqube = { id = "org.sonarqube", version.ref = "sonarqube" } -------------------------------------------------------------------------------- /src/test-project/src/main/resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | com.redhat.devtools.intellij.test-project 3 | Plugin display name here 4 | YourCompany 5 | 6 | 8 | most HTML tags may be used 9 | ]]> 10 | 11 | 13 | com.intellij.modules.platform 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/exceptions/UITestException.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.exceptions; 12 | 13 | /** 14 | * IntelliJ UI test library runtime exception 15 | * 16 | * @author zcervink@redhat.com 17 | */ 18 | public class UITestException extends RuntimeException { 19 | public UITestException(String errorMsg) { 20 | super(errorMsg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/project/NewProjectType.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2025 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.project; 12 | 13 | /** 14 | * Enumeration for new project type 15 | */ 16 | public enum NewProjectType { 17 | PLAIN_JAVA("Java"), 18 | MAVEN("Maven"), 19 | GRADLE("Gradle"), 20 | NEW_PROJECT("New Project"), 21 | EMPTY_PROJECT("Empty Project"); 22 | 23 | private final String projectType; 24 | 25 | NewProjectType(String projectType) { 26 | this.projectType = projectType; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return this.projectType; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/constants/ProjectLocation.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2025 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.constants; 12 | 13 | import java.io.File; 14 | import java.util.Optional; 15 | 16 | public final class ProjectLocation { 17 | // For more info on testProjectLocation please check README 18 | public static final String PROJECT_LOCATION = Optional.ofNullable(System.getProperty("testProjectLocation")) 19 | .filter(s -> !s.isEmpty()) 20 | .orElseGet(() -> System.getProperty("user.home") + File.separator + "IdeaProjects" + File.separator + "intellij-ui-test-projects"); 21 | 22 | private ProjectLocation() {} 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/ToolWindowLeftToolbar.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2024 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.DefaultXpath; 16 | import com.intellij.remoterobot.fixtures.FixtureName; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | @DefaultXpath(by = "ToolWindowLeftToolbar type", xpath = XPathDefinitions.WINDOW_LEFT_TOOLBAR) 21 | @FixtureName(name = "Tool Window Left Toolbar") 22 | public class ToolWindowLeftToolbar extends ToolWindowToolbar { 23 | 24 | public ToolWindowLeftToolbar(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 25 | super(remoteRobot, remoteComponent); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/ToolWindowRightToolbar.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2024 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.DefaultXpath; 16 | import com.intellij.remoterobot.fixtures.FixtureName; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | @DefaultXpath(by = "ToolWindowRightToolbar type", xpath = XPathDefinitions.WINDOW_RIGHT_TOOLBAR) 21 | @FixtureName(name = "Tool Window Right Toolbar") 22 | public class ToolWindowRightToolbar extends ToolWindowToolbar { 23 | 24 | public ToolWindowRightToolbar(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 25 | super(remoteRobot, remoteComponent); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /DCO: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 1 Letterman Drive 6 | Suite D4700 7 | San Francisco, CA, 94129 8 | 9 | Everyone is permitted to copy and distribute verbatim copies of this 10 | license document, but changing it is not allowed. 11 | 12 | 13 | Developer's Certificate of Origin 1.1 14 | 15 | By making a contribution to this project, I certify that: 16 | 17 | (a) The contribution was created in whole or in part by me and I 18 | have the right to submit it under the open source license 19 | indicated in the file; or 20 | 21 | (b) The contribution is based upon previous work that, to the best 22 | of my knowledge, is covered under an appropriate open source 23 | license and I have the right under that license to submit that 24 | work with modifications, whether created in whole or in part 25 | by me, under the same open source license (unless I am 26 | permitted to submit under a different license), as indicated 27 | in the file; or 28 | 29 | (c) The contribution was provided directly to me by some other 30 | person who certified (a), (b) or (c) and I have not modified 31 | it. 32 | 33 | (d) I understand and agree that this project and the contribution 34 | are public and that a record of the contribution (including all 35 | personal information I submit with it, including my sign-off) is 36 | maintained indefinitely and may be redistributed consistent with 37 | this project or the open source license(s) involved. 38 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Validate against IJ versions 2 | 3 | on: 4 | pull_request: 5 | branches: [ main ] 6 | 7 | jobs: 8 | validate_versions: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | IJ: 14 | - 2022.3 15 | - 2023.1 16 | - 2023.2 17 | - 2023.3 18 | - 2024.1 19 | - 2024.2 20 | # - 2024.3 is the current one 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up JDK 17 25 | uses: actions/setup-java@v4 26 | with: 27 | java-version: 17 28 | distribution: 'temurin' 29 | cache: 'gradle' 30 | - name: Run integration tests 31 | run: | 32 | cd src/test-project 33 | xvfb-run --server-args="-screen 0 1920x1080x24" ./gradlew integrationUITest --warning-mode none -PcommunityIdeaVersion=${{ matrix.IJ }} 34 | - name: Archiving tests reports 35 | uses: actions/upload-artifact@v4 36 | with: 37 | name: linux-test-reports-${{ matrix.IJ }} 38 | path: src/test-project/build/reports/tests/* 39 | if: always() 40 | - name: Archiving screenshots 41 | uses: actions/upload-artifact@v4 42 | with: 43 | name: linux-screenshots-${{ matrix.IJ }} 44 | path: src/test-project/build/screenshots/* 45 | if-no-files-found: ignore 46 | if: always() 47 | - name: Archiving StepLogger logs 48 | uses: actions/upload-artifact@v4 49 | with: 50 | name: linux-steplogger-logs-${{ matrix.IJ }} 51 | path: src/test-project/build/test-results/* 52 | if: always() 53 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/texttranformation/TextUtils.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.texttranformation; 12 | 13 | import com.intellij.remoterobot.fixtures.dataExtractor.RemoteText; 14 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 15 | 16 | import java.util.List; 17 | import java.util.stream.Collectors; 18 | 19 | /** 20 | * Static utilities that assist and simplify data conversion and transformation 21 | * 22 | * @author zcervink@redhat.com 23 | */ 24 | public class TextUtils { 25 | private TextUtils() { 26 | throw new UITestException("Text transformation utility class contains static utilities and cannot be instantiated."); 27 | } 28 | 29 | /** 30 | * Transform a List of RemoteText labels to one String 31 | * 32 | * @param data List of RemoteText instances 33 | * @return String containing a concatenation of all the labels in the 'data' List 34 | */ 35 | public static String listOfRemoteTextToString(List data) { 36 | return data 37 | .stream() 38 | .map(RemoteText::getText) 39 | .collect(Collectors.joining(" ")); 40 | } 41 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/openclose/AbstractToolWinPaneTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane.openclose; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 15 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 16 | import org.junit.jupiter.api.AfterAll; 17 | 18 | /** 19 | * Abstract ToolWindowsPane test 20 | * 21 | * @author zcervink@redhat.com 22 | */ 23 | abstract class AbstractToolWinPaneTest extends AbstractLibraryBaseTest { 24 | protected static final String MAVEN_PROJECT_NAME = "tool_windows_pane_java_maven_project"; 25 | protected static final String GRADLE_PROJECT_NAME = "tool_windows_pane_java_gradle_project"; 26 | protected static final String PLAIN_PROJECT_NAME = "tool_windows_pane_java_plain_project"; 27 | protected static ToolWindowPane toolWinPane; 28 | 29 | @AfterAll 30 | public static void closeCurrentProject() { 31 | CreateCloseUtils.closeProject(remoteRobot); 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/errors/IdeFatalErrorsDialog.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2020 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.errors; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * IDE Fatal Errors dialog fixture 24 | * 25 | * @author zcervink@redhat.com 26 | */ 27 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.IDE_FATAL_ERRORS_DIALOG) 28 | @FixtureName(name = "IDE Fatal Errors Dialog") 29 | public class IdeFatalErrorsDialog extends CommonContainerFixture { 30 | public IdeFatalErrorsDialog(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 31 | super(remoteRobot, remoteComponent); 32 | } 33 | 34 | /** 35 | * Click on the 'Clear all' button 36 | */ 37 | public void clearAll() { 38 | button(ButtonLabels.CLEAR_ALL_LABEL).click(); 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/information/ProjectStructureDialog.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Project Structure dialog fixture 24 | * 25 | * @author olkornii@redhat.com 26 | */ 27 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.PROJECT_STRUCTURE_DIALOG) 28 | @FixtureName(name = "Project Structure Dialog") 29 | public class ProjectStructureDialog extends CommonContainerFixture { 30 | public ProjectStructureDialog(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 31 | super(remoteRobot, remoteComponent); 32 | } 33 | 34 | /** 35 | * Cancel the 'Project Structure' 36 | */ 37 | public void cancel() { 38 | button(ButtonLabels.CANCEL_LABEL).click(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/constants/ButtonLabels.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.constants; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 14 | 15 | /** 16 | * Button labels 17 | * 18 | * @author zcervink@redhat.com 19 | */ 20 | public class ButtonLabels { 21 | public static final String CLEAR_ALL_LABEL = "Clear all"; 22 | public static final String CLOSE_LABEL = "Close"; 23 | public static final String CANCEL_LABEL = "Cancel"; 24 | public static final String OK_LABEL = "OK"; 25 | public static final String APPLY_LABEL = "Apply"; 26 | public static final String NEXT_LABEL = "Next"; 27 | public static final String PREVIOUS_LABEL = "Previous"; 28 | public static final String CREATE_LABEL = "Create"; 29 | public static final String PROJECT_STRIPE_BUTTON_LABEL = "Project"; 30 | public static final String MAVEN_STRIPE_BUTTON_LABEL = "Maven"; 31 | public static final String GRADLE_STRIPE_BUTTON_LABEL = "Gradle"; 32 | public static final String GOT_IT_LABEL = "Got It"; 33 | public static final String LEARN_LABEL = "Learn"; 34 | public static final String REMOVE_FROM_LIST_LABEL = "Remove From List"; 35 | 36 | private ButtonLabels() { 37 | throw new UITestException("Utility class with static methods."); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/steps/SharedSteps.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2024 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: mszuc@redhat.com 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.steps; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.fixtures.ComponentFixture; 15 | import com.intellij.remoterobot.search.locators.Locator; 16 | 17 | import java.time.Duration; 18 | 19 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 20 | 21 | /** 22 | * SharedSteps provides a collection of utility methods that can be used across the entire IntelliJ platform. 23 | * These methods facilitate common automation steps that can be reused in various test scenarios. 24 | */ 25 | public class SharedSteps { 26 | private SharedSteps() {} 27 | 28 | /** 29 | * Waits for a component to be visible within the IDE's UI hierarchy based on the provided XPath locator. 30 | * 31 | * @param robot The RemoteRobot instance for interaction with the IntelliJ IDEA UI. 32 | * @param duration The maximum time to wait for the component to become visible, in seconds. 33 | * @param interval The interval at which to check the component's visibility, in milliseconds. 34 | * @param xpath The XPath locator used to find the component within the UI hierarchy. 35 | */ 36 | public static void waitForComponentByXpath(RemoteRobot robot, int duration, int interval, Locator xpath) { 37 | waitFor(Duration.ofSeconds(duration), Duration.ofMillis(interval), () -> robot.findAll(ComponentFixture.class, xpath) 38 | .stream() 39 | .anyMatch(ComponentFixture::isShowing)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/information/TipDialog.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2020 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.fixtures.JCheckboxFixture; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 20 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 21 | import org.jetbrains.annotations.NotNull; 22 | 23 | /** 24 | * Tip of the Day dialog fixture 25 | * 26 | * @author zcervink@redhat.com 27 | */ 28 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.TIP_DIALOG) 29 | @FixtureName(name = "Tip Of The Day Dialog") 30 | public class TipDialog extends CommonContainerFixture { 31 | public TipDialog(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 32 | super(remoteRobot, remoteComponent); 33 | } 34 | 35 | /** 36 | * Get the 'Don't show tips' checkbox fixture 37 | * 38 | * @return checkbox fixture 39 | */ 40 | public JCheckboxFixture dontShowTipsCheckBox() { 41 | return checkBox("Don't show tips", true); 42 | } 43 | 44 | /** 45 | * Close the 'Tip of the Day' dialog by clicking on the 'Close' button 46 | */ 47 | public void close() { 48 | button(ButtonLabels.CLOSE_LABEL).click(); 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/internalerror/IdeInternalErrorUtils.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.internalerror; 12 | 13 | 14 | import com.intellij.remoterobot.RemoteRobot; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 19 | 20 | import java.time.Duration; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 25 | 26 | /** 27 | * Manage IDE internal errors 28 | * 29 | * @author zcervink@redhat.com 30 | */ 31 | public class IdeInternalErrorUtils { 32 | protected static final Logger LOGGER = Logger.getLogger(IdeInternalErrorUtils.class.getName()); 33 | 34 | private IdeInternalErrorUtils() {} 35 | 36 | /** 37 | * Clear internal IDE errors on Windows 38 | * 39 | * @param remoteRobot instance of the RemoteRobot 40 | */ 41 | public static void clearWindowsErrorsIfTheyAppear(RemoteRobot remoteRobot) { 42 | if (remoteRobot.isWin()) { 43 | try { 44 | remoteRobot.find(CommonContainerFixture.class, byXpath(XPathDefinitions.DIALOG_ROOT_PANE), Duration.ofSeconds(10)).button(ButtonLabels.CLEAR_ALL_LABEL).click(); 45 | } catch (WaitForConditionTimeoutException e) { 46 | LOGGER.log(Level.INFO, e.getMessage(), e); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/ToolWindowToolbar.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2025 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.JButtonFixture; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.time.Duration; 22 | 23 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 24 | 25 | public abstract class ToolWindowToolbar extends CommonContainerFixture { 26 | 27 | protected ToolWindowToolbar(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 28 | super(remoteRobot, remoteComponent); 29 | } 30 | 31 | public JButtonFixture stripeButton(String label) { 32 | if (label.equals(ButtonLabels.MAVEN_STRIPE_BUTTON_LABEL) || label.equals(ButtonLabels.GRADLE_STRIPE_BUTTON_LABEL)) { 33 | return button(byXpath(XPathDefinitions.toolWindowButton(label)), Duration.ofSeconds(2)); 34 | } else if (label.equals(ButtonLabels.PROJECT_STRIPE_BUTTON_LABEL)) { 35 | return button(byXpath(XPathDefinitions.TOOLTIP_TEXT_PROJECT), Duration.ofSeconds(2)); 36 | } 37 | return null; 38 | } 39 | 40 | public void clickStripeButton(String label) { 41 | stripeButton(label).click(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Publish Nightly Build 2 | 3 | on: 4 | schedule: 5 | - cron: '10 7 * * *' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | should-build-change: 10 | runs-on: ubuntu-latest 11 | outputs: 12 | repo-cache-hit: ${{ steps.cache-last-commit.outputs.cache-hit }} 13 | steps: 14 | - name: Fetch Sources 15 | uses: actions/checkout@v4 16 | - run: | 17 | git rev-parse HEAD >> lastCommit 18 | - name: Check New Changes 19 | id: cache-last-commit 20 | uses: actions/cache@v4 21 | with: 22 | path: lastCommit 23 | key: lastCommit-${{ hashFiles('lastCommit') }} 24 | 25 | release-snapshot-job: 26 | needs: should-build-change 27 | if: ${{ needs.should-build-change.outputs.repo-cache-hit != 'true' || github.event_name != 'schedule' }} 28 | name: Publish Snapshot 29 | runs-on: ubuntu-latest 30 | permissions: 31 | contents: write 32 | pull-requests: write 33 | steps: 34 | # Check out current repository 35 | - name: Fetch Sources 36 | uses: actions/checkout@v4 37 | 38 | # Set up Java environment for the next steps 39 | - name: Setup Java 40 | uses: actions/setup-java@v4 41 | with: 42 | distribution: 'temurin' 43 | java-version: 17 44 | cache: 'gradle' 45 | 46 | # Setup Gradle 47 | - name: Setup Gradle 48 | uses: gradle/actions/setup-gradle@v4 49 | 50 | # Build plugin 51 | - name: Build Plugin 52 | run: ./gradlew build 53 | 54 | # Publish to Maven repo 55 | - name: Checkout Maven Repo 56 | uses: actions/checkout@v4 57 | with: 58 | ref: repository 59 | path: build/repository 60 | 61 | - name: Deploy to Maven Repository 62 | env: 63 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 64 | run: | 65 | CURRENT_VERSION=$(grep "projectVersion=" gradle.properties | cut -d'=' -f2) 66 | ./gradlew publish 67 | 68 | git config --global user.email "action@github.com" 69 | git config --global user.name "GitHub Action Bot" 70 | pushd build/repository 71 | git add snapshots/ 72 | git commit -m "Publish ${CURRENT_VERSION} (${{github.run_number}})" 73 | git push -f origin repository -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/utils/test/screenshot/ScreenshotUtilsTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.test.screenshot; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 15 | import com.redhat.devtools.intellij.commonuitest.utils.screenshot.ScreenshotUtils; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import java.io.File; 19 | import java.time.Duration; 20 | import java.util.Arrays; 21 | import java.util.Objects; 22 | 23 | import static org.junit.jupiter.api.Assertions.assertEquals; 24 | 25 | /** 26 | * ScreenshotUtils test 27 | * 28 | * @author zcervink@redhat.com 29 | */ 30 | class ScreenshotUtilsTest extends AbstractLibraryBaseTest { 31 | 32 | private final String pathToIdeaProjectsFolder = System.getProperty("user.dir") + File.separator + "build" + File.separator + "screenshots"; 33 | 34 | @Test 35 | void takeScreenshotTest() { 36 | String comment = "to_be_removed"; 37 | remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 38 | 39 | int numberOfScreenshotBefore = getNumberOfSavedScreenshot(); 40 | ScreenshotUtils.takeScreenshot(remoteRobot, comment); 41 | int numberOfScreenshotAfter = getNumberOfSavedScreenshot(); 42 | assertEquals(numberOfScreenshotAfter, numberOfScreenshotBefore + 1, "Screenshot should be already saved but is not."); 43 | Arrays.stream(Objects.requireNonNull(new File(pathToIdeaProjectsFolder).listFiles())).filter(file -> file.getName().contains(comment)).forEach(File::delete); 44 | } 45 | 46 | private int getNumberOfSavedScreenshot() { 47 | File[] files = new File(pathToIdeaProjectsFolder).listFiles(); 48 | return files != null ? files.length : 0; 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/build/BuildUtils.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2025 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.build; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.idestatusbar.IdeStatusBar; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.BuildView; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.MavenBuildToolPane; 19 | 20 | import java.time.Duration; 21 | 22 | /** 23 | * Build project utility class 24 | */ 25 | public final class BuildUtils { 26 | 27 | private BuildUtils() {throw new UITestException("Utility class with static methods.");} 28 | 29 | /** 30 | * Build a Maven project and wait for the result to be successful 31 | * 32 | * @param remoteRobot reference to the RemoteRobot instance 33 | * @param projectName the name of the project 34 | * @param goal the maven goal 35 | */ 36 | public static void buildMavenProjectAndWaitForFinish(RemoteRobot remoteRobot, String projectName, String goal) { 37 | ToolWindowPane toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 38 | toolWinPane.openMavenBuildToolPane(); 39 | MavenBuildToolPane mavenBuildToolPane = toolWinPane.find(MavenBuildToolPane.class, Duration.ofSeconds(10)); 40 | mavenBuildToolPane.buildProject(goal, projectName); 41 | toolWinPane.find(BuildView.class, Duration.ofSeconds(5)).waitUntilBuildHasFinished(); 42 | remoteRobot.find(IdeStatusBar.class, Duration.ofSeconds(30)).waitUntilAllBgTasksFinish(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/openclose/ProjectExplorerPaneTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane.openclose; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ProjectExplorer; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 15 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 16 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 17 | import org.junit.jupiter.api.BeforeAll; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import java.time.Duration; 22 | 23 | import static org.junit.jupiter.api.Assertions.assertFalse; 24 | import static org.junit.jupiter.api.Assertions.assertTrue; 25 | 26 | /** 27 | * Project Explorer Tool Windows Pane test 28 | * 29 | * @author zcervink@redhat.com 30 | */ 31 | class ProjectExplorerPaneTest extends AbstractToolWinPaneTest { 32 | @BeforeAll 33 | static void prepareProject() { 34 | CreateCloseUtils.createNewProject(remoteRobot, PLAIN_PROJECT_NAME, NewProjectType.PLAIN_JAVA); 35 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 36 | } 37 | 38 | @BeforeEach 39 | void preparePanes() { 40 | if (toolWinPane.isPaneOpened(ProjectExplorer.class)) { 41 | toolWinPane.closeProjectExplorer(); 42 | } 43 | } 44 | 45 | @Test 46 | void projectExplorerPaneOpenCloseTest() { 47 | toolWinPane.openProjectExplorer(); 48 | assertTrue(toolWinPane.isPaneOpened(ProjectExplorer.class), "The 'Project Explorer' should be opened but is closed."); 49 | toolWinPane.closeProjectExplorer(); 50 | assertFalse(toolWinPane.isPaneOpened(ProjectExplorer.class), "The 'Project Explorer' should be closed but is opened."); 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/BuildViewTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.BuildView; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 16 | import com.redhat.devtools.intellij.commonuitest.utils.build.BuildUtils; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 18 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeAll; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.time.Duration; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertTrue; 26 | 27 | /** 28 | * Build View test 29 | * 30 | * @author zcervink@redhat.com 31 | */ 32 | class BuildViewTest extends AbstractLibraryBaseTest { 33 | private static final String PROJECT_NAME = "build_view_java_project"; 34 | private static ToolWindowPane toolWinPane; 35 | 36 | @BeforeAll 37 | static void prepareProject() { 38 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.MAVEN); 39 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 40 | } 41 | 42 | @AfterAll 43 | static void closeCurrentProject() { 44 | CreateCloseUtils.closeProject(remoteRobot); 45 | } 46 | 47 | @Test 48 | void waitForSuccessfulMavenBuildTest() { 49 | BuildUtils.buildMavenProjectAndWaitForFinish(remoteRobot, PROJECT_NAME, "verify"); 50 | BuildView buildView = toolWinPane.find(BuildView.class, Duration.ofSeconds(10)); 51 | assertTrue(buildView.isBuildSuccessful(), "The build should be successful but is not."); 52 | } 53 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/openclose/MavenPaneTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane.openclose; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.MavenBuildToolPane; 15 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 16 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 17 | import org.junit.jupiter.api.BeforeAll; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import java.time.Duration; 22 | 23 | import static org.junit.jupiter.api.Assertions.assertFalse; 24 | import static org.junit.jupiter.api.Assertions.assertTrue; 25 | 26 | /** 27 | * Maven Tool Windows Pane test 28 | * 29 | * @author zcervink@redhat.com 30 | */ 31 | class MavenPaneTest extends AbstractToolWinPaneTest { 32 | @BeforeAll 33 | static void prepareProject() { 34 | CreateCloseUtils.createNewProject(remoteRobot, MAVEN_PROJECT_NAME, NewProjectType.MAVEN); 35 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 36 | } 37 | 38 | @BeforeEach 39 | void preparePanes() { 40 | if (toolWinPane.isPaneOpened(MavenBuildToolPane.class)) { 41 | toolWinPane.closeMavenBuildToolPane(); 42 | } 43 | } 44 | 45 | @Test 46 | void mavenBuildToolPaneOpenCloseTest() { 47 | toolWinPane.openMavenBuildToolPane(); 48 | assertTrue(toolWinPane.isPaneOpened(MavenBuildToolPane.class), "The 'Maven Build Tool Pane' should be opened but is closed."); 49 | toolWinPane.closeMavenBuildToolPane(); 50 | assertFalse(toolWinPane.isPaneOpened(MavenBuildToolPane.class), "The 'Maven Build Tool Pane' should be closed but is opened."); 51 | } 52 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/openclose/GradlePaneTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane.openclose; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.GradleBuildToolPane; 15 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 16 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 17 | import org.junit.jupiter.api.BeforeAll; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | 21 | import java.time.Duration; 22 | 23 | import static org.junit.jupiter.api.Assertions.assertFalse; 24 | import static org.junit.jupiter.api.Assertions.assertTrue; 25 | 26 | /** 27 | * Gradle Tool Windows Pane test 28 | * 29 | * @author zcervink@redhat.com 30 | */ 31 | class GradlePaneTest extends AbstractToolWinPaneTest { 32 | @BeforeAll 33 | static void prepareProject() { 34 | CreateCloseUtils.createNewProject(remoteRobot, GRADLE_PROJECT_NAME, NewProjectType.GRADLE); 35 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 36 | } 37 | 38 | @BeforeEach 39 | void preparePanes() { 40 | if (toolWinPane.isPaneOpened(GradleBuildToolPane.class)) { 41 | toolWinPane.closeGradleBuildToolPane(); 42 | } 43 | } 44 | 45 | @Test 46 | void gradleBuildToolPaneOpenCloseTest() { 47 | toolWinPane.openGradleBuildToolPane(); 48 | assertTrue(toolWinPane.isPaneOpened(GradleBuildToolPane.class), "The 'Gradle Build Tool Pane' should be opened but is closed."); 49 | toolWinPane.closeGradleBuildToolPane(); 50 | assertFalse(toolWinPane.isPaneOpened(GradleBuildToolPane.class), "The 'Gradle Build Tool Pane' should be closed but is opened."); 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/runner/IntelliJVersion.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.runner; 12 | 13 | /** 14 | * Enumeration for supported versions of the IntelliJ Idea 15 | *

16 | * * @author zcervink@redhat.com 17 | */ 18 | public enum IntelliJVersion { 19 | UNSUPPORTED("unsupported.version"), 20 | COMMUNITY_V_2020_2(UNSUPPORTED.toString()), 21 | COMMUNITY_V_2020_3(UNSUPPORTED.toString()), 22 | COMMUNITY_V_2021_1(UNSUPPORTED.toString()), 23 | COMMUNITY_V_2021_2(UNSUPPORTED.toString()), 24 | COMMUNITY_V_2021_3(UNSUPPORTED.toString()), 25 | COMMUNITY_V_2022_1(UNSUPPORTED.toString()), 26 | COMMUNITY_V_2022_2(UNSUPPORTED.toString()), 27 | COMMUNITY_V_2022_3("IC-2022.3"), 28 | COMMUNITY_V_2023_1("IC-2023.1"), 29 | COMMUNITY_V_2023_2("IC-2023.2"), 30 | COMMUNITY_V_2023_3("IC-2023.3"), 31 | COMMUNITY_V_2024_1("IC-2024.1"), 32 | COMMUNITY_V_2024_2("IC-2024.2"), 33 | COMMUNITY_V_2024_3("IC-2024.3"); 34 | 35 | private final String ideaVersionStringRepresentation; 36 | private final int ideaVersionIntRepresentation; 37 | 38 | IntelliJVersion(String ideaVersionStringRepresentation) { 39 | this.ideaVersionStringRepresentation = ideaVersionStringRepresentation; 40 | if (ideaVersionStringRepresentation.equals("unsupported.version")) { 41 | this.ideaVersionIntRepresentation = 0; 42 | } else { 43 | String ideaVersionString = this.ideaVersionStringRepresentation.substring(3).replace(".", ""); 44 | this.ideaVersionIntRepresentation = Integer.parseInt(ideaVersionString); 45 | } 46 | } 47 | 48 | public static IntelliJVersion getFromStringVersion(String aVersion) { 49 | for (IntelliJVersion v : values()) { 50 | if (v.ideaVersionStringRepresentation.endsWith(aVersion)) return v; 51 | } 52 | throw new IllegalArgumentException(); 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return this.ideaVersionStringRepresentation; 58 | } 59 | 60 | public int toInt() { 61 | return this.ideaVersionIntRepresentation; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/buildtoolpane/AbstractBuildToolPane.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2025 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.JTreeFixture; 17 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.idestatusbar.IdeStatusBar; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 20 | import com.redhat.devtools.intellij.commonuitest.utils.texttranformation.TextUtils; 21 | import org.jetbrains.annotations.NotNull; 22 | 23 | import java.time.Duration; 24 | import java.util.Locale; 25 | 26 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 27 | 28 | public abstract class AbstractBuildToolPane extends CommonContainerFixture { 29 | 30 | protected final RemoteRobot remoteRobot; 31 | protected final int ideaVersionInt = UITestRunner.getIdeaVersionInt(); 32 | 33 | protected AbstractBuildToolPane(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 34 | super(remoteRobot, remoteComponent); 35 | this.remoteRobot = remoteRobot; 36 | } 37 | 38 | /** 39 | * Reload all projects 40 | */ 41 | public void reloadAllProjects() { 42 | actionButton(byXpath(XPathDefinitions.MY_ICON_REFRESH), Duration.ofSeconds(2)).click(); 43 | remoteRobot.find(IdeStatusBar.class, Duration.ofSeconds(10)).waitUntilAllBgTasksFinish(); 44 | } 45 | 46 | /** 47 | * Get the build tree fixture 48 | * 49 | * @return build tree fixture 50 | */ 51 | public JTreeFixture getBuildTree() { 52 | return find(JTreeFixture.class, JTreeFixture.Companion.byType(), Duration.ofSeconds(10)); 53 | } 54 | 55 | protected boolean isTreeVisible() { 56 | String treeContent = TextUtils.listOfRemoteTextToString(getBuildTree().findAllText()); 57 | return !treeContent.toLowerCase(Locale.ROOT).contains("nothing") && !treeContent.isEmpty(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/idestatusbar/IdeStatusBar.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2020 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.idestatusbar; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.ComponentFixture; 17 | import com.intellij.remoterobot.fixtures.DefaultXpath; 18 | import com.intellij.remoterobot.fixtures.FixtureName; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | import java.time.Duration; 23 | 24 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 25 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 26 | 27 | /** 28 | * Bottom status bar fixture 29 | * 30 | * @author zcervink@redhat.com 31 | */ 32 | @DefaultXpath(by = "IdeStatusBarImpl type", xpath = XPathDefinitions.IDE_STATUS_BAR) 33 | @FixtureName(name = "Ide Status Bar") 34 | public class IdeStatusBar extends CommonContainerFixture { 35 | 36 | public IdeStatusBar(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 37 | super(remoteRobot, remoteComponent); 38 | } 39 | 40 | /** 41 | * Create fixture for the InlineProgressPanel 42 | * 43 | * @return fixture for the InlineProgressPanel 44 | */ 45 | public ComponentFixture inlineProgressPanel() { 46 | return find(ComponentFixture.class, byXpath(XPathDefinitions.INLINE_PROGRESS_PANEL), Duration.ofSeconds(5)); 47 | } 48 | 49 | /** 50 | * Wait for 5 minutes until all the background tasks finish 51 | */ 52 | public void waitUntilAllBgTasksFinish() { 53 | waitUntilAllBgTasksFinish(300); 54 | } 55 | 56 | /** 57 | * Wait until all the background tasks finish 58 | */ 59 | public void waitUntilAllBgTasksFinish(int timeout) { 60 | waitFor(Duration.ofSeconds(timeout), Duration.ofSeconds(10), "the background tasks to finish in " + timeout + " seconds.", this::didAllBgTasksFinish); 61 | } 62 | 63 | private boolean didAllBgTasksFinish() { 64 | if (isShowing()) { 65 | return inlineProgressPanel().findAllText().isEmpty(); 66 | } 67 | return false; 68 | } 69 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/ToolWindowsPaneGradleTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.BuildView; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.GradleBuildToolPane; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 18 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeAll; 21 | import org.junit.jupiter.api.BeforeEach; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import java.time.Duration; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | /** 29 | * ToolWindowsPane Gradle test 30 | * 31 | * @author zcervink@redhat.com 32 | */ 33 | class ToolWindowsPaneGradleTest extends AbstractLibraryBaseTest { 34 | private static final String PROJECT_NAME = "tool_windows_pane_java_gradle_project"; 35 | private ToolWindowPane toolWinPane; 36 | 37 | @BeforeAll 38 | static void prepareProject() { 39 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.GRADLE); 40 | } 41 | 42 | @AfterAll 43 | static void closeCurrentProject() { 44 | CreateCloseUtils.closeProject(remoteRobot); 45 | } 46 | 47 | @BeforeEach 48 | void createToolWindowsPaneFixture() { 49 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 50 | } 51 | 52 | @Test 53 | void gradleTest() { 54 | toolWinPane.openGradleBuildToolPane(); 55 | GradleBuildToolPane gradleBuildToolPane = toolWinPane.find(GradleBuildToolPane.class, Duration.ofSeconds(10)); 56 | gradleBuildToolPane.buildProject("build"); 57 | BuildView buildView = toolWinPane.find(BuildView.class, Duration.ofSeconds(10)); 58 | buildView.waitUntilBuildHasFinished(); 59 | assertTrue(buildView.isBuildSuccessful(), "The build should be successful but is not."); 60 | } 61 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/ToolWindowsPaneMavenTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.BuildView; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.MavenBuildToolPane; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 18 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeAll; 21 | import org.junit.jupiter.api.BeforeEach; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import java.time.Duration; 25 | 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | /** 29 | * ToolWindowsPane Maven test 30 | * 31 | * @author zcervink@redhat.com 32 | */ 33 | class ToolWindowsPaneMavenTest extends AbstractLibraryBaseTest { 34 | private static final String PROJECT_NAME = "tool_windows_pane_java_maven_project"; 35 | private ToolWindowPane toolWinPane; 36 | 37 | @BeforeAll 38 | static void prepareProject() { 39 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.MAVEN); 40 | } 41 | 42 | @AfterAll 43 | static void closeCurrentProject() { 44 | CreateCloseUtils.closeProject(remoteRobot); 45 | } 46 | 47 | @BeforeEach 48 | void createToolWindowsPaneFixture() { 49 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 50 | } 51 | 52 | @Test 53 | void mavenBuildTest() { 54 | toolWinPane.openMavenBuildToolPane(); 55 | MavenBuildToolPane mavenBuildToolPane = toolWinPane.find(MavenBuildToolPane.class, Duration.ofSeconds(10)); 56 | mavenBuildToolPane.buildProject("verify", PROJECT_NAME); 57 | BuildView buildView = toolWinPane.find(BuildView.class, Duration.ofSeconds(10)); 58 | buildView.waitUntilBuildHasFinished(); 59 | assertTrue(buildView.isBuildSuccessful(), "The build should be successful but is not."); 60 | } 61 | } -------------------------------------------------------------------------------- /src/test-project/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType 2 | 3 | plugins { 4 | id("java") 5 | id("jacoco") 6 | id("org.jetbrains.intellij.platform") version ("2.6.0") 7 | } 8 | 9 | group = "com.redhat.devtools.intellij" 10 | version = "1.0-SNAPSHOT" 11 | val platformVersion = providers.gradleProperty("ideaVersion").get() 12 | 13 | java { 14 | toolchain { 15 | languageVersion = JavaLanguageVersion.of(17) 16 | } 17 | } 18 | 19 | repositories { 20 | mavenCentral() 21 | intellijPlatform { 22 | defaultRepositories() 23 | } 24 | } 25 | 26 | dependencies { 27 | intellijPlatform { 28 | create(IntelliJPlatformType.IntellijIdeaCommunity, platformVersion) 29 | } 30 | testImplementation("com.redhat.devtools.intellij:intellij-common-ui-test-library") 31 | testImplementation("org.junit.platform:junit-platform-launcher:1.10.3") 32 | testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.3") 33 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.3") 34 | } 35 | 36 | tasks { 37 | test { 38 | systemProperty("intellij_debug", "true") 39 | useJUnitPlatform() 40 | } 41 | 42 | withType { 43 | configure { 44 | isIncludeNoLocationClasses = true 45 | excludes = listOf("jdk.internal.*") 46 | } 47 | } 48 | 49 | jacocoTestReport { 50 | executionData.setFrom(fileTree(layout.buildDirectory).include("/jacoco/*.exec")) 51 | classDirectories.setFrom(instrumentCode) 52 | reports { 53 | xml.required = true 54 | } 55 | } 56 | 57 | jacocoTestCoverageVerification { 58 | classDirectories.setFrom(instrumentCode) 59 | } 60 | } 61 | 62 | val integrationUITest by intellijPlatformTesting.testIde.registering { 63 | task { 64 | systemProperty("intellij_debug", "true") 65 | val underTestVersion = findProperty("communityIdeaVersion") ?: platformVersion 66 | println("IDEA Version under test: $underTestVersion") 67 | systemProperty("communityIdeaVersion", underTestVersion) 68 | group = "verification" 69 | useJUnitPlatform() 70 | } 71 | } 72 | 73 | // https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-tasks.html#runIdeForUiTests 74 | val runIdeForUiTests by intellijPlatformTesting.runIde.registering { 75 | task { 76 | jvmArgumentProviders += CommandLineArgumentProvider { 77 | listOf( 78 | "-Djb.privacy.policy.text=", 79 | "-Djb.consents.confirmation.enabled=false", 80 | "-Didea.trust.all.projects=true", 81 | "-Dide.show.tips.on.startup.default.value=false", 82 | "-Dide.mac.message.dialogs.as.sheets=false", 83 | "-Dide.mac.file.chooser.native=false", 84 | "-Dapple.laf.useScreenMenuBar=false", 85 | ) 86 | } 87 | } 88 | plugins { 89 | robotServerPlugin() 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/information/CodeWithMeDialog.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 19 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 20 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 21 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 22 | import org.jetbrains.annotations.NotNull; 23 | 24 | import java.time.Duration; 25 | import java.util.logging.Level; 26 | import java.util.logging.Logger; 27 | 28 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 29 | 30 | /** 31 | * Code With Me dialog fixture 32 | * 33 | * @author zcervink@redhat.com 34 | */ 35 | @DefaultXpath(by = "CodeWithMe type", xpath = XPathDefinitions.CODE_WITH_ME_JPANEL) 36 | @FixtureName(name = "Code With Me Dialog") 37 | public class CodeWithMeDialog extends CommonContainerFixture { 38 | private static final Logger LOGGER = Logger.getLogger(CodeWithMeDialog.class.getName()); 39 | 40 | public CodeWithMeDialog(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 41 | super(remoteRobot, remoteComponent); 42 | } 43 | 44 | /** 45 | * Close the 'Code With Me' dialog if it appears 46 | * 47 | * @param remoteRobot reference to the RemoteRobot instance 48 | */ 49 | public static void closeCodeWithMePopupIfItAppears(RemoteRobot remoteRobot) { 50 | CodeWithMeDialog codeWithMeDialog; 51 | try { 52 | if (UITestRunner.getIdeaVersionInt() <= 20231) { 53 | codeWithMeDialog = remoteRobot.find(CodeWithMeDialog.class, byXpath("//div[@class='Wrapper']//div[@class='JPanel']"), Duration.ofSeconds(10)); 54 | } else { 55 | codeWithMeDialog = remoteRobot.find(CodeWithMeDialog.class, Duration.ofSeconds(10)); 56 | } 57 | } catch (WaitForConditionTimeoutException e) { 58 | LOGGER.log(Level.INFO, "Code With Me popup not found, nothing to close."); 59 | return; 60 | } 61 | codeWithMeDialog.findText(ButtonLabels.GOT_IT_LABEL).click(); 62 | LOGGER.log(Level.INFO, "Code With Me popup closed."); 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/settings/pages/NotificationsPage.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.settings.pages; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.fixtures.JCheckboxFixture; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | /** 23 | * Notifications page fixture 24 | * 25 | * @author zcervink@redhat.com 26 | */ 27 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.DIALOG_ROOT_PANE) 28 | @FixtureName(name = "Notifications Page") 29 | public class NotificationsPage extends CommonContainerFixture { 30 | public NotificationsPage(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 31 | super(remoteRobot, remoteComponent); 32 | } 33 | 34 | /** 35 | * Disable both balloon and system notifications 36 | * 37 | * @param value boolean value to toggle the checkboxes to 38 | */ 39 | public void toggleNotifications(boolean value) { 40 | toggleBalloonNotifications(value); 41 | toggleSystemNotifications(value); 42 | } 43 | 44 | /** 45 | * Toggle balloon notifications 46 | * 47 | * @param value boolean value to toggle the checkbox to 48 | */ 49 | public void toggleBalloonNotifications(boolean value) { 50 | displayBalloonNotificationsCheckBox().setValue(value); 51 | } 52 | 53 | /** 54 | * Toggle system notifications 55 | * 56 | * @param value boolean value to toggle the checkbox to 57 | */ 58 | public void toggleSystemNotifications(boolean value) { 59 | displaySystemNotificationsCheckBox().setValue(value); 60 | } 61 | 62 | /** 63 | * Get the 'Display balloon notifications' checkbox fixture 64 | * 65 | * @return checkbox fixture 66 | */ 67 | public JCheckboxFixture displayBalloonNotificationsCheckBox() { 68 | return checkBox("Display balloon notifications", true); 69 | } 70 | 71 | /** 72 | * Get the 'Enable system notifications' checkbox fixture 73 | * 74 | * @return checkbox fixture 75 | */ 76 | public JCheckboxFixture displaySystemNotificationsCheckBox() { 77 | return checkBox("Enable system notifications", true); 78 | } 79 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /src/test-project/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | Thank you for your interest into contributing to the IntelliJ IDEA UI test library. Contributions are essential for expansion and growth of this project. 4 | 5 | 6 | ## First Time Setup 7 | 1) Install prerequisites: 8 | * [Java Development Kit](https://adoptopenjdk.net/) 9 | 2) Fork and clone the repository 10 | 3) Import the folder as a project in JetBrains IntelliJ IDEA 11 | 12 | 13 | ## Project Structure 14 | 15 | This project is structured into 5 main parts. 16 | 17 | ### 1) Package fixtures 18 | Package fixtures contains several predefined fixtures that can be instantiated and used to access and work with the IntelliJ IDEA UI elements such as wizards, buttons, inputs and other parts of the IntelliJ IDEA IDE. 19 | 20 | ### 2) Package utils 21 | 22 | Package utils contains static methods and constants that can be useful for writing IntelliJ IDEA UI tests. There are for example methods for taking screenshots or creating new project without the need of implementing the whole process using provided fixtures. 23 | 24 | ### 3) Package exceptions 25 | 26 | Package exceptions contains predefined exceptions for handling situation such as the object that I am creating fixture for does not exist or there is un-relevant or unsupported option passed into a method. 27 | 28 | ### 4) Class UITestRunner 29 | 30 | * Class contains static methods for starting and closing IntelliJ IDEA for UI tests 31 | * Class contains public enum IdeaVersion defining supported IntelliJ IDEA versions 32 | * Class contains other public methods to work with the IntelliJ IDEA 33 | * getIdeaVersion() 34 | * getRemoteRobot() 35 | * getRemoteRobotConnection() 36 |
... 37 | 38 | ### 5) The test-project folder 39 | 40 | The test-project folder contains simple test project with JUnit 5 tests. 41 | 42 | 43 | 44 | ## Building the Library Locally 45 | 46 | For building the library locally run the following command in the root of the project. The project will be built and installed into your .m2 local repository. 47 | 48 | ``` 49 | $ ./gradlew publishToMavenLocal 50 | ``` 51 | 52 | 53 | ## Running Tests 54 | 55 | To execute the JUnit 5 tests with **Community** version of IntelliJ run the following commands: 56 | 57 | ``` 58 | $ cd ./src/test-project 59 | $ ./gradlew clean integrationUITest 60 | ``` 61 | 62 | ## Reporting Issues 63 | 64 | If you encounter a problem and know it is caused by the IntelliJ IDEA UI test library, please open an [issue report](https://github.com/redhat-developer/intellij-common-ui-test-library/issues). We really do appreciate any relevant issue report containing at least description and steps to reproduce the issue. 65 | 66 | 67 | ## License 68 | 69 | This project is distributed under the Eclipse Public License - v 2.0 license. For more information see the [LICENSE](./LICENSE) file in the root of this repository. 70 | 71 | ### Certificate of Origin 72 | 73 | By contributing to this project you agree to the Developer Certificate of 74 | Origin (DCO). This document was created by the Linux Kernel community and is a 75 | simple statement that you, as a contributor, have the legal right to make the 76 | contribution. See the [DCO](DCO) file for details. 77 | -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/dialogs/information/TipDialogTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.dialogs.information; 12 | 13 | import com.intellij.remoterobot.fixtures.JTreeFixture; 14 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 15 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information.TipDialog; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.time.Duration; 24 | import java.util.logging.Level; 25 | 26 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 27 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 28 | import static org.junit.jupiter.api.Assertions.fail; 29 | 30 | /** 31 | * Tip Dialog test 32 | * 33 | * @author zcervink@redhat.com 34 | */ 35 | class TipDialogTest extends AbstractLibraryBaseTest { 36 | private TipDialog tipDialog; 37 | 38 | @AfterAll 39 | static void cleanUp() { 40 | JTreeFixture jTreeFixture = remoteRobot.find(JTreeFixture.class, byXpath(XPathDefinitions.TREE)); 41 | jTreeFixture.findText("Projects").click(); 42 | } 43 | 44 | @BeforeEach 45 | void prepareTipDialog() { 46 | tipDialog = remoteRobot.find(FlatWelcomeFrame.class).openTipDialog(); 47 | } 48 | 49 | @Test 50 | void closeButtonTest() { 51 | remoteRobot.find(TipDialog.class, Duration.ofSeconds(5)); 52 | tipDialog.close(); 53 | try { 54 | remoteRobot.find(TipDialog.class); 55 | fail("The 'Tif of the Day' dialog should be closed but is not."); 56 | } catch (WaitForConditionTimeoutException e) { 57 | LOGGER.log(Level.INFO, e.getMessage(), e); 58 | } 59 | } 60 | 61 | @Test 62 | void dontShowTipsCheckBoxTest() { 63 | boolean checkboxStateBefore = tipDialog.dontShowTipsCheckBox().isSelected(); 64 | tipDialog.dontShowTipsCheckBox().setValue(!checkboxStateBefore); 65 | boolean checkboxStateAfter = tipDialog.dontShowTipsCheckBox().isSelected(); 66 | assertNotEquals(checkboxStateAfter, checkboxStateBefore, 67 | "The checkbox value should be '" + !checkboxStateBefore + "' but is '" + checkboxStateAfter + "'."); 68 | tipDialog.dontShowTipsCheckBox().setValue(checkboxStateBefore); 69 | tipDialog.close(); 70 | } 71 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/project/NewProjectDialogWizard.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.fixtures.JButtonFixture; 19 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 20 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 21 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 22 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 23 | import org.jetbrains.annotations.NotNull; 24 | 25 | /** 26 | * New Project dialog wizard fixture 27 | * 28 | * @author zcervink@redhat.com 29 | */ 30 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.NEW_PROJECT_DIALOG_WIZARD) 31 | @FixtureName(name = "New Project Dialog") 32 | public class NewProjectDialogWizard extends CommonContainerFixture { 33 | public NewProjectDialogWizard(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 34 | super(remoteRobot, remoteComponent); 35 | } 36 | 37 | /** 38 | * Move to the previous page of the 'New Project' dialog by clicking on the 'Previous' button 39 | */ 40 | public void previous() { 41 | clickOnButton(ButtonLabels.PREVIOUS_LABEL); 42 | } 43 | 44 | /** 45 | * Move to the next page of the 'New Project' dialog by clicking on the 'Next' button 46 | */ 47 | public void next() { 48 | clickOnButton(ButtonLabels.NEXT_LABEL); 49 | } 50 | 51 | /** 52 | * Finish the 'New Project' dialog 53 | */ 54 | public void finish() { 55 | clickOnButton(ButtonLabels.CREATE_LABEL); 56 | } 57 | 58 | /** 59 | * Close the 'New Project' dialog by clicking on the 'Cancel' button 60 | */ 61 | public void cancel() { 62 | button(ButtonLabels.CANCEL_LABEL).click(); 63 | } 64 | 65 | private void clickOnButton(String label) { 66 | JButtonFixture button; 67 | try { 68 | button = button(label); 69 | } catch (WaitForConditionTimeoutException e) { 70 | throw new UITestException("The '" + label + "' button has not been found."); 71 | } 72 | 73 | if (button.isEnabled()) { 74 | button.click(); 75 | } else { 76 | throw new UITestException("The '" + label + "' button is not enabled."); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/settings/SettingsDialog.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.settings; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.fixtures.JButtonFixture; 19 | import com.intellij.remoterobot.fixtures.JTreeFixture; 20 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 21 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 22 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 23 | import org.jetbrains.annotations.NotNull; 24 | 25 | /** 26 | * Settings dialog fixture 27 | * 28 | * @author zcervink@redhat.com 29 | */ 30 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.MY_DIALOG) 31 | @FixtureName(name = "Settings Dialog") 32 | public class SettingsDialog extends CommonContainerFixture { 33 | public SettingsDialog(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 34 | super(remoteRobot, remoteComponent); 35 | } 36 | 37 | /** 38 | * Navigate to specific 'Settings' dialog page according to given path 39 | * 40 | * @param path path to navigate to 41 | */ 42 | public void navigateTo(String... path) { 43 | if (path.length == 0) { 44 | throw new UITestException("Path is empty."); 45 | } 46 | settingsTree().expand(path); 47 | settingsTree().clickPath(path, true); 48 | } 49 | 50 | /** 51 | * Get the 'Settings' main tree fixture 52 | * 53 | * @return Settings tree fixture 54 | */ 55 | public JTreeFixture settingsTree() { 56 | return findAll(JTreeFixture.class, JTreeFixture.Companion.byType()).get(0); 57 | } 58 | 59 | /** 60 | * Finish the 'Settings' dialog by clicking on the 'OK' button 61 | */ 62 | public void ok() { 63 | JButtonFixture button = button(ButtonLabels.OK_LABEL); 64 | button.click(); 65 | } 66 | 67 | /** 68 | * Apply performed changes by clicking on the 'Apply' button 69 | */ 70 | public void apply() { 71 | JButtonFixture button = button(ButtonLabels.APPLY_LABEL); 72 | button.click(); 73 | } 74 | 75 | /** 76 | * Cancel the 'Settings' dialog by clicking on the 'Cancel' button 77 | */ 78 | public void cancel() { 79 | JButtonFixture button = button(ButtonLabels.CANCEL_LABEL); 80 | button.click(); 81 | } 82 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/project/pages/MavenGradleNewProjectFinalPage.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.pages; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.DefaultXpath; 16 | import com.intellij.remoterobot.fixtures.FixtureName; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | /** 21 | * New Project dialog maven project second page fixture 22 | * 23 | * @author zcervink@redhat.com 24 | */ 25 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.DIALOG_ROOT_PANE) 26 | @FixtureName(name = "New Project Dialog") 27 | public class MavenGradleNewProjectFinalPage extends AbstractNewProjectFinalPage { 28 | public MavenGradleNewProjectFinalPage(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 29 | super(remoteRobot, remoteComponent); 30 | } 31 | 32 | /** 33 | * Get the group ID currently inserted in the 'GroupId' input field 34 | * 35 | * @return group ID currently inserted in the input field 36 | */ 37 | public String getGroupId() { 38 | return textField("GroupId:", true).getText(); 39 | } 40 | 41 | /** 42 | * Insert the group ID into the 'GroupId' input field 43 | * 44 | * @param groupId group ID that will be set into the input field 45 | */ 46 | public void setGroupId(String groupId) { 47 | textField("GroupId:", true).setText(groupId); 48 | } 49 | 50 | /** 51 | * Get the artifact ID currently inserted in the 'ArtifactId' input field 52 | * 53 | * @return artifact ID currently inserted in the input field 54 | */ 55 | public String getArtifactId() { 56 | return textField("ArtifactId:", true).getText(); 57 | } 58 | 59 | /** 60 | * Insert the artifact ID into the 'ArtifactId' input field 61 | * 62 | * @param artifactId artifact ID that will be set into the input field 63 | */ 64 | public void setArtifactId(String artifactId) { 65 | textField("ArtifactId:", true).setText(artifactId); 66 | } 67 | 68 | /** 69 | * Get the version currently inserted in the 'Version' input field 70 | * 71 | * @return version currently inserted in the input field 72 | */ 73 | public String getVersion() { 74 | return textField("Version:", true).getText(); 75 | } 76 | 77 | /** 78 | * Insert the version into the 'Version' input field 79 | * 80 | * @param version version that will be set into the input field 81 | */ 82 | public void setVersion(String version) { 83 | textField("Version:", true).setText(version); 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/dialogs/information/ProjectStructureDialogTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.dialogs.information; 12 | 13 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 14 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information.ProjectStructureDialog; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.MainIdeWindow; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 18 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeAll; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.time.Duration; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertFalse; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | /** 29 | * TipDialog test and ProjectStructure test via SearchEverywherePopup 30 | * 31 | * @author zcervink@redhat.com, olkornii@redhat.com 32 | */ 33 | class ProjectStructureDialogTest extends AbstractLibraryBaseTest { 34 | private static final String PROJECT_NAME = "tip_dialog_java_project"; 35 | 36 | @BeforeAll 37 | static void prepareProject() { 38 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.PLAIN_JAVA); 39 | } 40 | 41 | @AfterAll 42 | static void closeProject() { 43 | CreateCloseUtils.closeProject(remoteRobot); 44 | } 45 | 46 | @Test 47 | void projectStructureDialogTest() { 48 | makeSureDialogIsVisible(); 49 | assertTrue(isDialogVisible(), "The 'Project Structure' dialog should be visible but is not."); 50 | ProjectStructureDialog projectStructureDialog = remoteRobot.find(ProjectStructureDialog.class, Duration.ofSeconds(2)); 51 | projectStructureDialog.cancel(); 52 | assertFalse(isDialogVisible(), "The 'Project Structure' dialog should be visible but is not."); 53 | } 54 | 55 | private void makeSureDialogIsVisible() { 56 | try { 57 | remoteRobot.find(ProjectStructureDialog.class, Duration.ofSeconds(10)); 58 | } catch (WaitForConditionTimeoutException e) { 59 | MainIdeWindow mainIdeWindow = remoteRobot.find(MainIdeWindow.class, Duration.ofSeconds(10)); 60 | mainIdeWindow.invokeCmdUsingSearchEverywherePopup("Project Structure"); 61 | } 62 | } 63 | 64 | private boolean isDialogVisible() { 65 | try { 66 | return remoteRobot.find(ProjectStructureDialog.class, Duration.ofSeconds(10)).isShowing(); 67 | } catch (WaitForConditionTimeoutException e) { 68 | return false; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/AbstractLibraryBaseTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.MainIdeWindow; 16 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 18 | import com.redhat.devtools.intellij.commonuitest.utils.runner.IntelliJVersion; 19 | import com.redhat.devtools.intellij.commonuitest.utils.testextension.ScreenshotAfterTestFailExtension; 20 | import org.junit.jupiter.api.AfterAll; 21 | import org.junit.jupiter.api.BeforeAll; 22 | import org.junit.jupiter.api.extension.ExtendWith; 23 | 24 | import java.time.Duration; 25 | import java.util.logging.Logger; 26 | 27 | /** 28 | * Base class for all JUnit tests in the IntelliJ common UI test library 29 | * 30 | * @author zcervink@redhat.com 31 | */ 32 | @ExtendWith(ScreenshotAfterTestFailExtension.class) 33 | public abstract class AbstractLibraryBaseTest { 34 | protected static final Logger LOGGER = Logger.getLogger(AbstractLibraryBaseTest.class.getName()); 35 | private static final IntelliJVersion communityIdeaVersion = IntelliJVersion.getFromStringVersion(System.getProperty("communityIdeaVersion")); 36 | protected static RemoteRobot remoteRobot; 37 | protected static int ideaVersionInt; 38 | private static boolean intelliJHasStarted = false; 39 | 40 | @BeforeAll 41 | static void startIntelliJ() { 42 | if (!intelliJHasStarted) { 43 | ideaVersionInt = communityIdeaVersion.toInt(); 44 | remoteRobot = UITestRunner.runIde(communityIdeaVersion); 45 | 46 | intelliJHasStarted = true; 47 | Runtime.getRuntime().addShutdownHook(new CloseIntelliJBeforeQuit()); 48 | 49 | FlatWelcomeFrame flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 50 | flatWelcomeFrame.clearWorkspace(); 51 | flatWelcomeFrame.disableNotifications(); 52 | } 53 | } 54 | 55 | @AfterAll 56 | static void finishTestRun() { 57 | FlatWelcomeFrame flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 58 | flatWelcomeFrame.clearExceptions(); 59 | flatWelcomeFrame.clearWorkspace(); 60 | } 61 | 62 | protected void prepareWorkspace(String projectName) { 63 | CreateCloseUtils.createNewProject(remoteRobot, projectName, NewProjectType.PLAIN_JAVA); 64 | MainIdeWindow mainIdeWindow = remoteRobot.find(MainIdeWindow.class, Duration.ofSeconds(10)); 65 | mainIdeWindow.closeProject(); 66 | } 67 | 68 | private static class CloseIntelliJBeforeQuit extends Thread { 69 | @Override 70 | public void run() { 71 | UITestRunner.closeIde(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/dialogs/information/CodeWithMeDialogTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.dialogs.information; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information.CodeWithMeDialog; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.NewProjectDialogWizard; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.pages.NewProjectFirstPage; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.MainIdeWindow; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.idestatusbar.IdeStatusBar; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ProjectLocation; 20 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 21 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 22 | import org.junit.jupiter.api.AfterAll; 23 | import org.junit.jupiter.api.BeforeAll; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import java.time.Duration; 27 | 28 | import static com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils.openNewProjectDialogFromWelcomeDialog; 29 | 30 | /** 31 | * Code With Me dialog test 32 | * 33 | * @author zcervink@redhat.com 34 | */ 35 | class CodeWithMeDialogTest extends AbstractLibraryBaseTest { 36 | private static final String PROJECT_NAME = "code_with_me_java_project"; 37 | 38 | @BeforeAll 39 | static void prepareProject() { 40 | NewProjectDialogWizard newProjectDialogWizard = openNewProjectDialogFromWelcomeDialog(remoteRobot); 41 | NewProjectFirstPage newProjectFirstPage = newProjectDialogWizard.find(NewProjectFirstPage.class, Duration.ofSeconds(10)); 42 | 43 | newProjectFirstPage.selectNewProjectType(NewProjectType.NEW_PROJECT); 44 | newProjectFirstPage.getProjectNameTextField().click(); // Click to gain focus on newProjectFirstPage 45 | newProjectFirstPage.setProjectName(PROJECT_NAME); 46 | newProjectFirstPage.setProjectLocation(ProjectLocation.PROJECT_LOCATION); 47 | newProjectFirstPage.setLanguage("Java"); 48 | newProjectFirstPage.setBuildSystem("IntelliJ"); 49 | newProjectFirstPage.setProjectSdkIfAvailable("17"); 50 | 51 | newProjectDialogWizard.finish(); 52 | IdeStatusBar ideStatusBar = remoteRobot.find(IdeStatusBar.class, Duration.ofSeconds(10)); 53 | ideStatusBar.waitUntilAllBgTasksFinish(); 54 | MainIdeWindow mainIdeWindow = remoteRobot.find(MainIdeWindow.class, Duration.ofSeconds(5)); 55 | mainIdeWindow.maximizeIdeWindow(); 56 | } 57 | 58 | 59 | @AfterAll 60 | static void closeCurrentProject() { 61 | CreateCloseUtils.closeProject(remoteRobot); 62 | } 63 | 64 | @Test 65 | void closeCodeWithMe() { 66 | CodeWithMeDialog.closeCodeWithMePopupIfItAppears(remoteRobot); 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/buildtoolpane/MavenBuildToolPane.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.DefaultXpath; 16 | import com.intellij.remoterobot.fixtures.FixtureName; 17 | import com.intellij.remoterobot.utils.Keyboard; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import java.awt.event.KeyEvent; 22 | import java.time.Duration; 23 | 24 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 25 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 26 | 27 | /** 28 | * Maven Build Tool Pane fixture 29 | * 30 | * @author zcervink@redhat.com 31 | */ 32 | @DefaultXpath(by = "ToolWindowsPane type", xpath = XPathDefinitions.MAVEN_TOOL_WINDOW) 33 | @FixtureName(name = "Maven Tool Window Pane") 34 | public class MavenBuildToolPane extends AbstractBuildToolPane { 35 | 36 | public MavenBuildToolPane(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 37 | super(remoteRobot, remoteComponent); 38 | } 39 | 40 | /** 41 | * Collapse all 42 | */ 43 | public void collapseAll() { 44 | if (ideaVersionInt >= 20242) { 45 | actionButton(byXpath(XPathDefinitions.MY_ICON_COLLAPSE_ALL_2024_2), Duration.ofSeconds(2)).click(); 46 | } else { 47 | actionButton(byXpath(XPathDefinitions.MY_ICON_COLLAPSE_ALL_FOR), Duration.ofSeconds(2)).click(); 48 | } 49 | } 50 | 51 | /** 52 | * Expand all 53 | */ 54 | public void expandAll() { 55 | // trick using keyboard shortcut because there is no button for this action, but the 'Expand All' shortcut works... 56 | if (!getBuildTree().getHasFocus()) { 57 | getBuildTree().click(); // be sure that the pane is selected 58 | } 59 | Keyboard keyboard = new Keyboard(remoteRobot); 60 | int current; 61 | do { 62 | current = getBuildTree().collectRows().size(); 63 | keyboard.hotKey(KeyEvent.VK_CONTROL, KeyEvent.VK_ADD); 64 | } while (getBuildTree().collectRows().size() > current); 65 | } 66 | 67 | /** 68 | * Build the project 69 | * 70 | * @param goal name of the Lifecycle goal you want to invoke (clean, validate, compile, test, package, verify, install, site, deploy) 71 | */ 72 | public void buildProject(String goal, String projectName) { 73 | waitFor(Duration.ofSeconds(30), Duration.ofSeconds(2), "the Maven tree to appear.", this::isTreeVisible); 74 | // below workaround due to https://github.com/JetBrains/intellij-ui-test-robot/issues/459 75 | expandAll(); 76 | getBuildTree().doubleClickPath(new String[]{projectName, "Lifecycle", goal}, true); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/screenshot/ScreenshotUtils.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.screenshot; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 15 | 16 | import javax.imageio.ImageIO; 17 | import java.awt.image.BufferedImage; 18 | import java.io.File; 19 | import java.io.IOException; 20 | import java.nio.file.Files; 21 | import java.nio.file.Path; 22 | import java.nio.file.Paths; 23 | import java.time.LocalDateTime; 24 | import java.time.format.DateTimeFormatter; 25 | import java.util.logging.Level; 26 | import java.util.logging.Logger; 27 | 28 | /** 29 | * Static utilities for taking screenshots 30 | * 31 | * @author zcervink@redhat.com 32 | */ 33 | public class ScreenshotUtils { 34 | static final String SCREENSHOT_LOCATION = "." + File.separator + "build" + File.separator + "screenshots" + File.separator; 35 | static final String FILETYPE = "png"; 36 | private static final Logger LOGGER = Logger.getLogger(ScreenshotUtils.class.getName()); 37 | 38 | private ScreenshotUtils() { 39 | throw new UITestException("Screenshot utility class contains static utilities and cannot be instantiated."); 40 | } 41 | 42 | /** 43 | * Take screenshot of the entire screen and save it on disk 44 | * 45 | * @param remoteRobot reference to the RemoteRobot instance 46 | * @param comment message to add at the end of the screenshot's filename 47 | */ 48 | public static void takeScreenshot(RemoteRobot remoteRobot, String comment) { 49 | try { 50 | BufferedImage screenshotBufferedImage = remoteRobot.getScreenshot(); 51 | Path path = Paths.get(SCREENSHOT_LOCATION); 52 | boolean doesScreenshotDirExists = Files.exists(path); 53 | if (!doesScreenshotDirExists) { 54 | Files.createDirectory(path); 55 | } 56 | String screenshotFilename = getTimeNow(); 57 | String screenshotComment = comment == null || comment.isEmpty() ? "" : "_" + comment.replace(" ", "_"); 58 | String screenshotPathname = SCREENSHOT_LOCATION + screenshotFilename + screenshotComment + "." + FILETYPE; 59 | File screenshotFile = new File(screenshotPathname); 60 | ImageIO.write(screenshotBufferedImage, FILETYPE, screenshotFile); 61 | } catch (IOException e) { 62 | LOGGER.log(Level.SEVERE, e.getMessage(), e); 63 | } 64 | } 65 | 66 | /** 67 | * Take screenshot of the entire screen and save it on disk 68 | * 69 | * @param remoteRobot reference to the RemoteRobot instance 70 | */ 71 | public static void takeScreenshot(RemoteRobot remoteRobot) { 72 | takeScreenshot(remoteRobot, ""); 73 | } 74 | 75 | private static String getTimeNow() { 76 | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"); 77 | LocalDateTime localTimeNow = LocalDateTime.now(); 78 | return dateTimeFormatter.format(localTimeNow); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/buildtoolpane/GradleBuildToolPane.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.DefaultXpath; 16 | import com.intellij.remoterobot.fixtures.FixtureName; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | import java.time.Duration; 21 | 22 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 23 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 24 | 25 | /** 26 | * Gradle Build Tool Pane fixture 27 | * 28 | * @author zcervink@redhat.com 29 | */ 30 | @DefaultXpath(by = "ToolWindowsPane type", xpath = XPathDefinitions.GRADLE_TOOL_WINDOW) 31 | @FixtureName(name = "Gradle Tool Window Pane") 32 | public class GradleBuildToolPane extends AbstractBuildToolPane { 33 | 34 | public GradleBuildToolPane(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 35 | super(remoteRobot, remoteComponent); 36 | } 37 | 38 | /** 39 | * Collapse all 40 | */ 41 | public void collapseAll() { 42 | if (ideaVersionInt >= 20242) { 43 | actionButton(byXpath(XPathDefinitions.MY_ICON_COLLAPSE_ALL_2024_2), Duration.ofSeconds(2)).click(); 44 | } else { 45 | actionButton(byXpath(XPathDefinitions.MY_ICON_COLLAPSE_ALL_IDE), Duration.ofSeconds(2)).click(); 46 | } 47 | } 48 | 49 | /** 50 | * Expand all 51 | */ 52 | public void expandAll() { 53 | if (ideaVersionInt >= 20242) { 54 | actionButton(byXpath(XPathDefinitions.MY_ICON_EXPAND_ALL_2024_2), Duration.ofSeconds(2)).click(); 55 | } else { 56 | actionButton(byXpath(XPathDefinitions.MY_ICON_EXPAND_ALL_IDE), Duration.ofSeconds(2)).click(); 57 | } 58 | } 59 | 60 | private Boolean isTreeExpanded() { 61 | int rows = getBuildTree().collectRows().size(); 62 | if (rows == 1) { 63 | expandAll(); 64 | return false; 65 | } 66 | return rows > 1; 67 | } 68 | 69 | /** 70 | * @param goal name of the build tasks you want to invoke (assemble, build, classes, clean, jar...) 71 | */ 72 | public void buildProject(String goal) { 73 | runGradleTask("build", goal); 74 | } 75 | 76 | /** 77 | * @param goal name of the verification tasks you want to invoke (check, test...) 78 | */ 79 | public void verifyProject(String goal) { 80 | runGradleTask("verification", goal); 81 | } 82 | 83 | private void runGradleTask(String subTask, String goal) { 84 | waitFor(Duration.ofSeconds(30), Duration.ofSeconds(1), "the Gradle tree to appear.", this::isTreeVisible); 85 | expandAll(); 86 | waitFor(Duration.ofSeconds(60), Duration.ofSeconds(1), "the Gradle tree to expand.", this::isTreeExpanded); 87 | getBuildTree().doubleClickPath(new String[]{"Tasks", subTask, goal}, true); 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/BuildView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.fixtures.JTreeFixture; 19 | import com.intellij.remoterobot.fixtures.TextEditorFixture; 20 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 21 | import com.redhat.devtools.intellij.commonuitest.utils.texttranformation.TextUtils; 22 | import org.jetbrains.annotations.NotNull; 23 | 24 | import java.time.Duration; 25 | 26 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 27 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 28 | 29 | /** 30 | * Build View fixture 31 | * 32 | * @author zcervink@redhat.com 33 | */ 34 | @DefaultXpath(by = "ToolWindowsPane type", xpath = XPathDefinitions.BUILD_VIEW) 35 | @FixtureName(name = "Build View Pane") 36 | public class BuildView extends CommonContainerFixture { 37 | private String lastBuildStatusTreeText; 38 | 39 | public BuildView(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 40 | super(remoteRobot, remoteComponent); 41 | } 42 | 43 | /** 44 | * Wait until build has finished 45 | */ 46 | public void waitUntilBuildHasFinished() { 47 | waitFor(Duration.ofSeconds(300), Duration.ofSeconds(3), "The build did not finish in 5 minutes.", this::didBuildStatusTreeTextStopChanging); 48 | } 49 | 50 | /** 51 | * Test if build is successful 52 | * 53 | * @return true if the build is successful 54 | */ 55 | public boolean isBuildSuccessful() { 56 | String runConsoleOutput = TextUtils.listOfRemoteTextToString(buildConsole().findAllText()); 57 | return runConsoleOutput.contains("BUILD SUCCESS") || runConsoleOutput.contains("exit code 0"); 58 | } 59 | 60 | /** 61 | * Get the Build Status tree fixture 62 | * 63 | * @return Build Status tree fixture 64 | */ 65 | public JTreeFixture buildStatusTree() { 66 | return find(JTreeFixture.class, byXpath(XPathDefinitions.TREE)); 67 | } 68 | 69 | /** 70 | * Get the build console 71 | * 72 | * @return build console fixture 73 | */ 74 | public TextEditorFixture buildConsole() { 75 | return textEditor(byXpath(XPathDefinitions.BUILD_VIEW_EDITOR), Duration.ofSeconds(2)); 76 | } 77 | 78 | private boolean didBuildStatusTreeTextStopChanging() { 79 | String updatedBuildStatusTreeText = getBuildStatusTreeText(); 80 | 81 | if (lastBuildStatusTreeText != null && lastBuildStatusTreeText.equals(updatedBuildStatusTreeText)) { 82 | lastBuildStatusTreeText = null; 83 | return true; 84 | } else { 85 | lastBuildStatusTreeText = updatedBuildStatusTreeText; 86 | return false; 87 | } 88 | } 89 | 90 | private String getBuildStatusTreeText() { 91 | return TextUtils.listOfRemoteTextToString(buildStatusTree().findAllText()); 92 | } 93 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/menubar/MenuBarTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.menubar; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 15 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 16 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.information.TipDialog; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.menubar.MenuBar; 19 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ProjectExplorer; 20 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 21 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 22 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 23 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 24 | import org.junit.jupiter.api.AfterAll; 25 | import org.junit.jupiter.api.BeforeAll; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import java.time.Duration; 29 | 30 | import static org.junit.jupiter.api.Assertions.assertTrue; 31 | 32 | /** 33 | * MenuBar test 34 | * 35 | * @author zcervink@redhat.com 36 | */ 37 | class MenuBarTest extends AbstractLibraryBaseTest { 38 | private static final String PROJECT_NAME = "project_view_tree_java_project"; 39 | 40 | @BeforeAll 41 | static void prepareProject() { 42 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.PLAIN_JAVA); 43 | } 44 | 45 | @AfterAll 46 | static void closeCurrentProject() { 47 | CreateCloseUtils.closeProject(remoteRobot); 48 | } 49 | 50 | @Test 51 | void openTipDialogUsingMenuBarTest() { 52 | if (UITestRunner.getIdeaVersionInt() == 20233 && remoteRobot.isLinux()) { 53 | return; // known issue, no menu bar in GHA for 2023.3 54 | } 55 | if (remoteRobot.isWin() || remoteRobot.isLinux()) { 56 | new MenuBar(remoteRobot).navigateTo("Help", "Tip of the Day"); 57 | assertTrue(isTipDialogVisible(remoteRobot), "The 'Tip of the Day' dialog should be visible but is not"); 58 | remoteRobot.find(TipDialog.class, Duration.ofSeconds(10)).button(ButtonLabels.CLOSE_LABEL).click(); 59 | } 60 | } 61 | 62 | @Test 63 | void closeAndReopenProjectTest() { 64 | CreateCloseUtils.closeProject(remoteRobot); 65 | CreateCloseUtils.openProjectFromWelcomeDialog(remoteRobot, PROJECT_NAME); 66 | 67 | ToolWindowPane toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 68 | toolWinPane.openProjectExplorer(); 69 | ProjectExplorer projectExplorer = toolWinPane.find(ProjectExplorer.class, Duration.ofSeconds(10)); 70 | assertTrue(projectExplorer.isItemPresent(PROJECT_NAME), "The project should be back open, but it is not"); 71 | } 72 | 73 | private boolean isTipDialogVisible(RemoteRobot remoteRobot) { 74 | try { 75 | remoteRobot.find(TipDialog.class, Duration.ofSeconds(10)); 76 | } catch (WaitForConditionTimeoutException e) { 77 | return false; 78 | } 79 | return true; 80 | } 81 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/buildtoolpane/GradleBuildToolPaneTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane.buildtoolpane; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.BuildView; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.GradleBuildToolPane; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 18 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeAll; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.time.Duration; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertTrue; 26 | 27 | /** 28 | * Gradle Build Tool Pane test 29 | * 30 | * @author zcervink@redhat.com 31 | */ 32 | class GradleBuildToolPaneTest extends AbstractLibraryBaseTest { 33 | private static final String PROJECT_NAME = "gradle_build_tool_pane_java_project"; 34 | private static ToolWindowPane toolWinPane; 35 | private static GradleBuildToolPane gradleBuildToolPane; 36 | 37 | @BeforeAll 38 | static void prepareProject() { 39 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.GRADLE); 40 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 41 | toolWinPane.openGradleBuildToolPane(); 42 | gradleBuildToolPane = toolWinPane.find(GradleBuildToolPane.class, Duration.ofSeconds(10)); 43 | } 44 | 45 | @AfterAll 46 | static void closeCurrentProject() { 47 | CreateCloseUtils.closeProject(remoteRobot); 48 | } 49 | 50 | @Test 51 | void buildProject() { 52 | gradleBuildToolPane.buildProject("build"); 53 | BuildView buildView = toolWinPane.find(BuildView.class, Duration.ofSeconds(10)); 54 | buildView.waitUntilBuildHasFinished(); 55 | assertTrue(buildView.isBuildSuccessful(), "The build should be successful but is not."); 56 | } 57 | 58 | @Test 59 | void reloadAllGradleProjects() { 60 | assertTrue(gradleBuildToolPane.isShowing(), "The gradle view pane should be opened but is not."); 61 | gradleBuildToolPane.reloadAllProjects(); 62 | } 63 | 64 | @Test 65 | void expandAll() { 66 | gradleBuildToolPane.collapseAll(); 67 | int itemsCountBeforeExpanding = gradleBuildToolPane.getBuildTree().collectRows().size(); 68 | gradleBuildToolPane.expandAll(); 69 | int itemsCountAfterExpanding = gradleBuildToolPane.getBuildTree().collectRows().size(); 70 | assertTrue(itemsCountAfterExpanding > itemsCountBeforeExpanding, "The 'Expand All' operation was unsuccessful."); 71 | } 72 | 73 | @Test 74 | void collapseAll() { 75 | gradleBuildToolPane.expandAll(); 76 | int itemsCountBeforeCollapsing = gradleBuildToolPane.getBuildTree().collectRows().size(); 77 | gradleBuildToolPane.collapseAll(); 78 | int itemsCountAfterCollapsing = gradleBuildToolPane.getBuildTree().collectRows().size(); 79 | assertTrue(itemsCountAfterCollapsing < itemsCountBeforeCollapsing, "The 'Collapse All' operation was unsuccessful."); 80 | } 81 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/idestatusbar/IdeStatusBarTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.idestatusbar; 12 | 13 | import com.intellij.remoterobot.fixtures.dataExtractor.RemoteText; 14 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.NewProjectDialogWizard; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.pages.NewProjectFirstPage; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.MainIdeWindow; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.idestatusbar.IdeStatusBar; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ProjectLocation; 20 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 21 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 22 | import com.redhat.devtools.intellij.commonuitest.utils.texttranformation.TextUtils; 23 | import org.junit.jupiter.api.AfterEach; 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import java.time.Duration; 28 | import java.util.List; 29 | 30 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 31 | import static org.junit.jupiter.api.Assertions.assertTrue; 32 | 33 | /** 34 | * IdeStatusBar test 35 | * 36 | * @author zcervink@redhat.com 37 | */ 38 | class IdeStatusBarTest extends AbstractLibraryBaseTest { 39 | private static final String PROJECT_NAME = "ide_status_bar_java_project"; 40 | 41 | private static kotlin.Pair isProgressbarWithLabelVisible() { 42 | IdeStatusBar ideStatusBar = remoteRobot.find(IdeStatusBar.class, Duration.ofSeconds(10)); 43 | List inlineProgressPanelContent = ideStatusBar.inlineProgressPanel().findAllText(); 44 | String inlineProgressPanelText = TextUtils.listOfRemoteTextToString(inlineProgressPanelContent); 45 | return new kotlin.Pair<>(!inlineProgressPanelText.isEmpty(), ideStatusBar); 46 | } 47 | 48 | @BeforeEach 49 | void prepareProject() { 50 | NewProjectDialogWizard newProjectDialogWizard = CreateCloseUtils.openNewProjectDialogFromWelcomeDialog(remoteRobot); 51 | NewProjectFirstPage newProjectFirstPage = newProjectDialogWizard.find(NewProjectFirstPage.class, Duration.ofSeconds(10)); 52 | 53 | newProjectFirstPage.selectNewProjectType(NewProjectType.NEW_PROJECT); 54 | newProjectFirstPage.getProjectNameTextField().click(); // Click to gain focus on newProjectFirstPage 55 | newProjectFirstPage.setProjectName(PROJECT_NAME); 56 | newProjectFirstPage.setProjectLocation(ProjectLocation.PROJECT_LOCATION); 57 | newProjectFirstPage.setBuildSystem("Maven"); 58 | 59 | newProjectDialogWizard.finish(); 60 | } 61 | 62 | @AfterEach 63 | void closeCurrentProject() { 64 | CreateCloseUtils.closeProject(remoteRobot); 65 | } 66 | 67 | @Test 68 | void progressBarTest() { 69 | IdeStatusBar ideStatusBar = waitFor(Duration.ofSeconds(30), Duration.ofMillis(250), "Wait for the appearance of progress bar in the IDE status bar.", "The progress bar in status bar did not appear in 60 seconds.", IdeStatusBarTest::isProgressbarWithLabelVisible); 70 | ideStatusBar.waitUntilAllBgTasksFinish(); 71 | MainIdeWindow mainIdeWindow = remoteRobot.find(MainIdeWindow.class, Duration.ofSeconds(2)); 72 | mainIdeWindow.maximizeIdeWindow(); 73 | assertTrue(mainIdeWindow.isShowing(), "The Main IDE Window should be open."); 74 | } 75 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/buildtoolpane/MavenBuildToolPaneTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane.buildtoolpane; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.BuildView; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.MavenBuildToolPane; 17 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 18 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 19 | import org.junit.jupiter.api.AfterAll; 20 | import org.junit.jupiter.api.BeforeAll; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.time.Duration; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertEquals; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | /** 29 | * Maven Build Tool Pane test 30 | * 31 | * @author zcervink@redhat.com 32 | */ 33 | class MavenBuildToolPaneTest extends AbstractLibraryBaseTest { 34 | private static final String PROJECT_NAME = "maven_build_tool_pane_java_project"; 35 | private static ToolWindowPane toolWinPane; 36 | private static MavenBuildToolPane mavenBuildToolPane; 37 | 38 | @BeforeAll 39 | static void prepareProject() { 40 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.MAVEN); 41 | toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 42 | toolWinPane.openMavenBuildToolPane(); 43 | mavenBuildToolPane = toolWinPane.find(MavenBuildToolPane.class, Duration.ofSeconds(10)); 44 | } 45 | 46 | @AfterAll 47 | static void closeCurrentProject() { 48 | CreateCloseUtils.closeProject(remoteRobot); 49 | } 50 | 51 | @Test 52 | void buildProject() { 53 | mavenBuildToolPane.buildProject("verify", PROJECT_NAME); 54 | BuildView buildView = toolWinPane.find(BuildView.class, Duration.ofSeconds(5)); 55 | buildView.waitUntilBuildHasFinished(); 56 | assertTrue(buildView.isBuildSuccessful(), "The build should be successful but is not."); 57 | } 58 | 59 | @Test 60 | void reloadAllMavenProjects() { 61 | assertTrue(mavenBuildToolPane.isShowing(), "The maven view pane should be opened but is not."); 62 | mavenBuildToolPane.reloadAllProjects(); 63 | } 64 | 65 | @Test 66 | void expandAll() { 67 | mavenBuildToolPane.collapseAll(); 68 | int itemsCountBeforeExpanding = mavenBuildToolPane.getBuildTree().collectRows().size(); 69 | mavenBuildToolPane.expandAll(); 70 | int itemsCountAfterExpanding = mavenBuildToolPane.getBuildTree().collectRows().size(); 71 | assertTrue(itemsCountAfterExpanding > itemsCountBeforeExpanding, "The 'Expand All' operation was unsuccessful."); 72 | } 73 | 74 | @Test 75 | void collapseAll() { 76 | mavenBuildToolPane.expandAll(); 77 | int itemsCountBeforeCollapsing = mavenBuildToolPane.getBuildTree().collectRows().size(); 78 | assertTrue(itemsCountBeforeCollapsing > 1, "The Maven tree did not expand correctly"); 79 | mavenBuildToolPane.collapseAll(); 80 | int itemsCountAfterCollapsing = mavenBuildToolPane.getBuildTree().collectRows().size(); 81 | assertEquals(1, itemsCountAfterCollapsing); 82 | assertTrue(itemsCountAfterCollapsing < itemsCountBeforeCollapsing, "The 'Collapse All' operation was unsuccessful."); 83 | } 84 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/utils/testextension/ScreenshotAfterTestFailExtension.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.utils.testextension; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 15 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.NewProjectDialogWizard; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.MainIdeWindow; 19 | import com.redhat.devtools.intellij.commonuitest.utils.screenshot.ScreenshotUtils; 20 | import org.junit.jupiter.api.extension.AfterTestExecutionCallback; 21 | import org.junit.jupiter.api.extension.ExtensionContext; 22 | 23 | import java.time.Duration; 24 | import java.util.logging.Level; 25 | import java.util.logging.Logger; 26 | 27 | import static com.intellij.remoterobot.stepsProcessing.StepWorkerKt.step; 28 | 29 | /** 30 | * ScreenshotAfterTestFailExtension takes screenshot immediately after test has failed 31 | * and perform a cleanup to ensure no dialog or windows is opened
32 | * 33 | * USAGE: Add the following annotation before every class with JUnit tests: 34 | * {@code @ExtendWith(ScreenshotAfterTestFailExtension.class)}
35 | * 36 | * @author zcervink@redhat.com 37 | */ 38 | public class ScreenshotAfterTestFailExtension implements AfterTestExecutionCallback { 39 | protected static final Logger LOGGER = Logger.getLogger(ScreenshotAfterTestFailExtension.class.getName()); 40 | 41 | /** 42 | * Take screenshot right after a test has failed and perform a cleanup to ensure no dialog or window is opened 43 | * 44 | * @param extensionContext test run data 45 | */ 46 | @Override 47 | public void afterTestExecution(ExtensionContext extensionContext) { 48 | RemoteRobot remoteRobot = UITestRunner.getRemoteRobot(); 49 | boolean testFailed = extensionContext.getExecutionException().isPresent(); 50 | if (testFailed) { 51 | if (remoteRobot == null) { 52 | LOGGER.log(Level.SEVERE, "Can't take a screenshot, remoteRobot is null!"); 53 | return; 54 | } 55 | String testClass = extensionContext.getRequiredTestClass().getName(); 56 | String testMethod = extensionContext.getRequiredTestMethod().getName(); 57 | step("Take a screenshot after a test has failed", 58 | () -> ScreenshotUtils.takeScreenshot(remoteRobot, testClass + "_" + testMethod) 59 | ); 60 | step("Return to the 'Welcome Frame' dialog", 61 | () -> cleanAfterTestFail(remoteRobot) 62 | ); 63 | } 64 | } 65 | 66 | private void cleanAfterTestFail(RemoteRobot remoteRobot) { 67 | // New Project Dialog is visible -> close it 68 | try { 69 | NewProjectDialogWizard newProjectDialogWizard = remoteRobot.find(NewProjectDialogWizard.class, Duration.ofSeconds(10)); 70 | newProjectDialogWizard.cancel(); 71 | return; 72 | } catch (WaitForConditionTimeoutException e2) { 73 | // New Project Dialog is not visible -> continue 74 | } 75 | 76 | // Flat Welcome Frame dialog is visible -> return 77 | try { 78 | remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 79 | } catch (WaitForConditionTimeoutException e) { 80 | // Main IDE Window is visible -> close it 81 | try { 82 | remoteRobot.find(MainIdeWindow.class, Duration.ofSeconds(10)).closeProject(); 83 | } catch (WaitForConditionTimeoutException e2) { 84 | // Main IDE Window is not visible -> continue 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/navigation/SearchEverywherePopup.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.navigation; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.FixtureName; 18 | import com.intellij.remoterobot.fixtures.JListFixture; 19 | import com.intellij.remoterobot.fixtures.JTextFieldFixture; 20 | import com.intellij.remoterobot.fixtures.dataExtractor.RemoteText; 21 | import com.intellij.remoterobot.utils.Keyboard; 22 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 23 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 24 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 25 | import com.redhat.devtools.intellij.commonuitest.utils.texttranformation.TextUtils; 26 | import org.jetbrains.annotations.NotNull; 27 | 28 | import java.awt.event.KeyEvent; 29 | import java.time.Duration; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 34 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 35 | 36 | /** 37 | * Search Everywhere popup fixture 38 | * 39 | * @author zcervink@redhat.com 40 | */ 41 | @DefaultXpath(by = "SearchEverywhereUI type", xpath = XPathDefinitions.SEARCH_EVERYWHERE_POPUP) 42 | @FixtureName(name = "Search Everywhere Popup") 43 | public class SearchEverywherePopup extends CommonContainerFixture { 44 | private final RemoteRobot remoteRobot; 45 | 46 | public SearchEverywherePopup(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 47 | super(remoteRobot, remoteComponent); 48 | this.remoteRobot = remoteRobot; 49 | } 50 | 51 | /** 52 | * Activate given tab 53 | * 54 | * @param tabName name of the tab in the Search Everywhere popup 55 | */ 56 | public void activateTab(String tabName) { 57 | try { 58 | button(byXpath(XPathDefinitions.label(tabName)), Duration.ofSeconds(2)).click(); 59 | } catch (WaitForConditionTimeoutException e) { 60 | throw new UITestException("The '" + tabName + "' tab cannot be found."); 61 | } 62 | } 63 | 64 | /** 65 | * Invoke a command using the search field 66 | * 67 | * @param cmdToEnter command that will be invoked using the search field 68 | */ 69 | public void invokeCmd(String cmdToEnter) { 70 | invokeSearch(cmdToEnter, true); 71 | } 72 | 73 | public void searchText(String searchString) { 74 | invokeSearch(searchString, false); 75 | } 76 | 77 | private void invokeSearch(String searchText, boolean invoke) { 78 | JTextFieldFixture searchField = textField(JTextFieldFixture.Companion.byType(), Duration.ofSeconds(2)); 79 | searchField.click(); 80 | searchField.setText(searchText); 81 | waitFor(Duration.ofSeconds(30), Duration.ofSeconds(1), "the search dialog in the Search Everywhere popup to load in 30 seconds.", () -> didSearchFinish(searchText)); 82 | if (invoke) { 83 | new Keyboard(remoteRobot).hotKey(KeyEvent.VK_ENTER); 84 | } 85 | } 86 | 87 | private boolean didSearchFinish(String cmdToInvoke) { 88 | String searchResultsString = TextUtils.listOfRemoteTextToString(getSearchResults()); 89 | return searchResultsString.toLowerCase().contains(cmdToInvoke.toLowerCase()); 90 | } 91 | 92 | private List getSearchResults() { 93 | List searchResults = jLists(JListFixture.Companion.byType()); 94 | if (searchResults.isEmpty()) { 95 | return new ArrayList<>(); 96 | } 97 | JListFixture searchResultsList = searchResults.get(0); 98 | return searchResultsList.findAllText(); 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/project/pages/AbstractNewProjectFinalPage.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.pages; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.ComponentFixture; 17 | import com.intellij.remoterobot.fixtures.DefaultXpath; 18 | import com.intellij.remoterobot.fixtures.FixtureName; 19 | import com.intellij.remoterobot.fixtures.JTextFieldFixture; 20 | import com.redhat.devtools.intellij.commonuitest.exceptions.UITestException; 21 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 22 | import org.jetbrains.annotations.NotNull; 23 | 24 | import java.util.List; 25 | 26 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 27 | import static com.redhat.devtools.intellij.commonuitest.utils.texttranformation.TextUtils.listOfRemoteTextToString; 28 | 29 | /** 30 | * New Project dialog abstract terminal page fixture 31 | * 32 | * @author zcervink@redhat.com 33 | */ 34 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.DIALOG_ROOT_PANE) 35 | @FixtureName(name = "New Project Dialog") 36 | public abstract class AbstractNewProjectFinalPage extends CommonContainerFixture { 37 | 38 | protected AbstractNewProjectFinalPage(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 39 | super(remoteRobot, remoteComponent); 40 | } 41 | 42 | /** 43 | * Get the project name for new project in the 'New Project' dialog 44 | * 45 | * @return currently set new project name 46 | */ 47 | public String getProjectName() { 48 | return textFields(byXpath(XPathDefinitions.JBTEXT_FIELD)).get(0).getText(); 49 | } 50 | 51 | /** 52 | * Set the project name for new project in the 'New Project' dialog 53 | * 54 | * @param projectName name of the new project 55 | */ 56 | public void setProjectName(String projectName) { 57 | textFields(byXpath(XPathDefinitions.JBTEXT_FIELD)).get(0).setText(projectName); 58 | } 59 | 60 | /** 61 | * Get the project location for new project in the 'New Project' dialog 62 | * 63 | * @return currently set new project location 64 | */ 65 | public String getProjectLocation() { 66 | return find(JTextFieldFixture.class, byXpath(XPathDefinitions.EXTENDABLE_TEXT_FIELD)).getText(); 67 | } 68 | 69 | /** 70 | * Set the project location for new project in the 'New Project' dialog 71 | * 72 | * @param projectLocation project location of the new project 73 | */ 74 | public void setProjectLocation(String projectLocation) { 75 | find(JTextFieldFixture.class, byXpath(XPathDefinitions.EXTENDABLE_TEXT_FIELD)).setText(projectLocation); 76 | } 77 | 78 | /** 79 | * Open the 'Advanced Settings' section 80 | */ 81 | public void openAdvanceSettings() { 82 | if (!isAdvancedSettingsOpened()) { 83 | find(ComponentFixture.class, byXpath(XPathDefinitions.COLLAPSIBLE_TITLED_SEPARATOR_NEW)).click(); 84 | } 85 | } 86 | 87 | /** 88 | * Close the 'Advanced Settings' section 89 | */ 90 | public void closeAdvanceSettings() { 91 | if (isAdvancedSettingsOpened()) { 92 | find(ComponentFixture.class, byXpath(XPathDefinitions.COLLAPSIBLE_TITLED_SEPARATOR_NEW)).click(); 93 | } 94 | } 95 | 96 | public boolean isAdvancedSettingsOpened() { 97 | List cf = findAll(ComponentFixture.class, byXpath(XPathDefinitions.COLLAPSIBLE_TITLED_SEPARATOR_NEW_SIBLINGS)); 98 | 99 | for (int i = 0; i < cf.size(); i++) { 100 | if (listOfRemoteTextToString(cf.get(i).findAllText()).contains("Advanced Settings")) { 101 | return i != cf.size() - 1; 102 | } 103 | } 104 | throw new UITestException("Wizard does not contain 'Advanced Settings' section."); 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/dialogs/project/pages/JavaNewProjectFinalPage.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.pages; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.DefaultXpath; 16 | import com.intellij.remoterobot.fixtures.FixtureName; 17 | import com.intellij.remoterobot.fixtures.JTextFieldFixture; 18 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 19 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 20 | import org.jetbrains.annotations.NotNull; 21 | 22 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 23 | 24 | /** 25 | * New Project dialog java project third page fixture 26 | * 27 | * @author zcervink@redhat.com 28 | */ 29 | @DefaultXpath(by = "MyDialog type", xpath = XPathDefinitions.DIALOG_ROOT_PANE) 30 | @FixtureName(name = "New Project Dialog") 31 | public class JavaNewProjectFinalPage extends AbstractNewProjectFinalPage { 32 | 33 | private final int ideaVersionInt = UITestRunner.getIdeaVersionInt(); 34 | 35 | public JavaNewProjectFinalPage(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 36 | super(remoteRobot, remoteComponent); 37 | } 38 | 39 | /** 40 | * Get the name of the module currently inserted in the 'Module name' input field 41 | * 42 | * @return name of the module currently inserted in the input field 43 | */ 44 | public String getModuleName() { 45 | if (ideaVersionInt >= 20242) { 46 | return find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_MODULE_NAME_2024_2_AND_NEWER)).getText(); 47 | } else { 48 | return find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_MODULE_NAME)).getText(); 49 | } 50 | } 51 | 52 | /** 53 | * Insert the name of the module into the 'Module name' input field 54 | * 55 | * @param moduleName name of the module that will be set into the input field 56 | */ 57 | public void setModuleName(String moduleName) { 58 | if (ideaVersionInt >= 20242) { 59 | find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_MODULE_NAME_2024_2_AND_NEWER)).setText(moduleName); 60 | } else { 61 | find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_MODULE_NAME)).setText(moduleName); 62 | } 63 | } 64 | 65 | /** 66 | * Get the location of the content root currently inserted in the 'Content root' input field 67 | * 68 | * @return location of the content root currently inserted in the input field 69 | */ 70 | public String getContentRoot() { 71 | return find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_CONTENT_ROOT)).getText(); 72 | } 73 | 74 | /** 75 | * Insert the location of the content root into the 'Content root' input field 76 | * 77 | * @param contentRoot location of the content root that will be set into the input field 78 | */ 79 | public void setContentRoot(String contentRoot) { 80 | find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_CONTENT_ROOT)).setText(contentRoot); 81 | } 82 | 83 | /** 84 | * Get the location of the module file currently inserted in the 'Module file location' input field 85 | * 86 | * @return location of the module file currently inserted in the input field 87 | */ 88 | public String getModuleFileLocation() { 89 | return find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_MODULE_FILE_LOCATION)).getText(); 90 | } 91 | 92 | /** 93 | * Insert the location of the module file into the 'Module file location' input field 94 | * 95 | * @param moduleFileLocation location of the module file that will be set into the input field 96 | */ 97 | public void setModuleFileLocation(String moduleFileLocation) { 98 | find(JTextFieldFixture.class, byXpath(XPathDefinitions.GET_SET_MODULE_FILE_LOCATION)).setText(moduleFileLocation); 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/dialogs/FlatWelcomeFrameTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.dialogs; 12 | 13 | import com.intellij.remoterobot.fixtures.JTreeFixture; 14 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.project.NewProjectDialogWizard; 17 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ProjectLocation; 18 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 19 | import com.redhat.devtools.intellij.commonuitest.utils.internalerror.IdeInternalErrorUtils; 20 | import org.apache.commons.io.filefilter.FileFilterUtils; 21 | import org.junit.jupiter.api.AfterEach; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import java.io.File; 25 | import java.io.FileFilter; 26 | import java.time.Duration; 27 | 28 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 29 | import static org.junit.jupiter.api.Assertions.assertEquals; 30 | import static org.junit.jupiter.api.Assertions.assertTrue; 31 | 32 | /** 33 | * FlatWelcomeFrame test 34 | * 35 | * @author zcervink@redhat.com 36 | */ 37 | class FlatWelcomeFrameTest extends AbstractLibraryBaseTest { 38 | private static final String PROJECT_NAME = "welcome_frame_java_project"; 39 | private FlatWelcomeFrame flatWelcomeFrame; 40 | 41 | @AfterEach 42 | void cleanUp() { 43 | flatWelcomeFrame.clearWorkspace(); 44 | flatWelcomeFrame.clearExceptions(); 45 | } 46 | 47 | @Test 48 | void createNewProjectLinkTest() { 49 | flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 50 | flatWelcomeFrame.createNewProject(); 51 | NewProjectDialogWizard newProjectDialogWizard = remoteRobot.find(NewProjectDialogWizard.class, Duration.ofSeconds(10)); 52 | newProjectDialogWizard.cancel(); 53 | assertTrue(flatWelcomeFrame.isShowing(), "The Welcome Window should be open."); 54 | } 55 | 56 | @Test 57 | void clearWorkspaceTest() { 58 | prepareWorkspace(PROJECT_NAME); 59 | flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 60 | flatWelcomeFrame.clearExceptions(); 61 | int projectsOnDisk = getNumberOfProjectsOnDisk(); 62 | int projectLinks = getNumberOfProjectLinks(); 63 | assertEquals(1, projectsOnDisk, "Number of projects in the IntelliJ's project folder should be 1 but is " + projectsOnDisk + "."); 64 | assertEquals(1, projectLinks, "Number of projects' links in the IntelliJ's 'Welcome Frame Dialog' should be 1 but is " + projectLinks + "."); 65 | IdeInternalErrorUtils.clearWindowsErrorsIfTheyAppear(remoteRobot); 66 | flatWelcomeFrame.clearWorkspace(); 67 | int projectCount2 = getNumberOfProjectsOnDisk(); 68 | int projectLinks2 = getNumberOfProjectLinks(); 69 | assertEquals(0, projectCount2, "Number of projects in the IntelliJ's project folder should be 0 but is " + projectCount2 + "."); 70 | assertEquals(0, projectLinks2, "Number of projects' links in the IntelliJ's 'Welcome Frame Dialog' should be 0 but is " + projectLinks2 + "."); 71 | } 72 | 73 | @Test 74 | void clearExceptionsTest() { 75 | prepareWorkspace(PROJECT_NAME); 76 | flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 77 | flatWelcomeFrame.clearExceptions(); 78 | assertTrue(flatWelcomeFrame.isShowing(), "The Welcome Window should be open."); 79 | } 80 | 81 | private int getNumberOfProjectsOnDisk() { 82 | String pathToIdeaProjectsFolder = ProjectLocation.PROJECT_LOCATION; 83 | File[] files = new File(pathToIdeaProjectsFolder).listFiles((FileFilter) FileFilterUtils.directoryFileFilter()); 84 | if (files != null) { 85 | return files.length; 86 | } else { 87 | return 0; // files is null (e.g., folder doesn't exist) 88 | } 89 | } 90 | 91 | private int getNumberOfProjectLinks() { 92 | try { 93 | JTreeFixture projects = remoteRobot.findAll(JTreeFixture.class, byXpath(XPathDefinitions.RECENT_PROJECT_PANEL_NEW_2)).get(0); 94 | return projects.findAllText().size() / 2; 95 | } catch (IndexOutOfBoundsException e) { 96 | return 0; 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | run-name: Release ${{ inputs.release_version }} 3 | 4 | #Only one job at a time 5 | concurrency: release 6 | 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | release_version: 11 | description: 'Release version' 12 | required: true 13 | type: string 14 | 15 | jobs: 16 | release: 17 | name: Publish 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | # Check out current repository 22 | - name: Fetch Sources 23 | uses: actions/checkout@v4 24 | 25 | # Set up Java environment for the next steps 26 | - name: Setup Java 27 | uses: actions/setup-java@v4 28 | with: 29 | distribution: 'temurin' 30 | java-version: 17 31 | cache: 'gradle' 32 | 33 | # Setup Gradle 34 | - name: Setup Gradle 35 | uses: gradle/actions/setup-gradle@v4 36 | 37 | - name: Set Release Version 38 | shell: bash 39 | run: | 40 | CURRENT_VERSION=$(grep "projectVersion=" gradle.properties | cut -d'=' -f2) 41 | NEW_VERSION=${{ inputs.release_version }} 42 | awk -v current="$CURRENT_VERSION" -v new="$NEW_VERSION" 'BEGIN {FS=OFS="="} $1 == "projectVersion" { $2 = new }1' gradle.properties > tmpfile && mv tmpfile gradle.properties 43 | echo "Release version: $NEW_VERSION" 44 | echo "PLUGIN_VERSION=${NEW_VERSION}" >> $GITHUB_ENV 45 | 46 | # Build plugin 47 | - name: Build Plugin 48 | run: ./gradlew assemble build 49 | 50 | - name: Tag Release 51 | env: 52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 53 | run: | 54 | git config user.email "action@github.com" 55 | git config user.name "GitHub Action" 56 | if git diff --quiet; then 57 | echo "No changes to commit." 58 | else 59 | git commit -sam "chore(skip-release): set version to ${{ inputs.release_version }}" 60 | fi 61 | git tag ${{ inputs.release_version }} 62 | git push origin ${{ inputs.release_version }} 63 | 64 | # Publish to Maven repo 65 | - name: Checkout Maven Repo 66 | uses: actions/checkout@v4 67 | with: 68 | ref: repository 69 | path: build/repository 70 | 71 | - name: Deploy to Maven Repository 72 | env: 73 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 74 | run: | 75 | CURRENT_VERSION=$(grep "projectVersion=" gradle.properties | cut -d'=' -f2) 76 | ./gradlew publish 77 | echo "Published $PLUGIN_VERSION." 78 | 79 | git config --global user.email "action@github.com" 80 | git config --global user.name "GitHub Action Bot" 81 | pushd build/repository 82 | git add releases/ 83 | git commit -m "Publish ${CURRENT_VERSION} (${{github.run_number}})" 84 | git push -f origin repository 85 | 86 | # Set next SNAPSHOT version 87 | - name: Increment Plugin Version 88 | env: 89 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 90 | run: | 91 | CURRENT_VERSION=$(grep "projectVersion=" gradle.properties | cut -d'=' -f2) 92 | IFS="-" read -ra VERSION_PARTS <<< "$CURRENT_VERSION" 93 | IFS="." read -ra VERSION_NUM <<< "${VERSION_PARTS[0]}" 94 | ((VERSION_NUM[2]+=1)) 95 | NEW_VERSION="${VERSION_NUM[0]}.${VERSION_NUM[1]}.${VERSION_NUM[2]}-SNAPSHOT" 96 | awk -v new_version="$NEW_VERSION" '/projectVersion=/{sub(/=.*/, "=" new_version)}1' gradle.properties > tmpfile && mv tmpfile gradle.properties 97 | echo "Set $NEW_VERSION in gradle.properties" 98 | git checkout -b $NEW_VERSION 99 | git commit -sam "chore(skip-release): set version to $NEW_VERSION" 100 | git push -u origin $NEW_VERSION 101 | gh pr create -B main -H $NEW_VERSION --title "chore(skip-release): set version to $NEW_VERSION" --body 'Created by Github action' 102 | 103 | - name: Simple conventional changelog 104 | uses: redhat-developer/simple-conventional-changelog@0a6db1ac3910c2cf66f2e1a530951dba1ece8540 #0.0.12 105 | id: changelog 106 | with: 107 | token: ${{ secrets.GITHUB_TOKEN }} 108 | current-tag: ${{ inputs.release_version }} 109 | types-mapping: 'feat:Features,fix:Bug Fixes,docs:Documentation,refactor:Refactoring,build:Build,chore:Other' 110 | 111 | # Create a new GitHub release 112 | - name: Create GitHub Release 113 | env: 114 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 115 | run: | 116 | gh release create ${{ inputs.release_version }} \ 117 | --title "${{ inputs.release_version }}" \ 118 | --notes "$(cat << 'EOM' 119 | ${{ steps.changelog.outputs.changelog }} 120 | EOM 121 | )" 122 | 123 | - name: Upload Release Asset 124 | env: 125 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 126 | run: gh release upload ${{ inputs.release_version }} ./build/libs/*.jar 127 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/toolwindowspane/ToolWindowPane.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.DefaultXpath; 17 | import com.intellij.remoterobot.fixtures.Fixture; 18 | import com.intellij.remoterobot.fixtures.FixtureName; 19 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 20 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 21 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.GradleBuildToolPane; 22 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.buildtoolpane.MavenBuildToolPane; 23 | import com.redhat.devtools.intellij.commonuitest.utils.constants.ButtonLabels; 24 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 25 | import org.jetbrains.annotations.NotNull; 26 | 27 | import java.time.Duration; 28 | 29 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 30 | 31 | /** 32 | * Tool Window Pane fixture 33 | * 34 | * @author zcervink@redhat.com 35 | */ 36 | @DefaultXpath(by = "ToolWindowPane type", xpath = XPathDefinitions.TOOL_WINDOW_PANE) 37 | @FixtureName(name = "Tool Window Pane") 38 | public class ToolWindowPane extends CommonContainerFixture { 39 | 40 | private final RemoteRobot remoteRobot; 41 | private final int ideaVersionInt = UITestRunner.getIdeaVersionInt(); 42 | 43 | public ToolWindowPane(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 44 | super(remoteRobot, remoteComponent); 45 | this.remoteRobot = remoteRobot; 46 | } 47 | 48 | /** 49 | * Open project explorer 50 | */ 51 | public void openProjectExplorer() { 52 | togglePane(ButtonLabels.PROJECT_STRIPE_BUTTON_LABEL, ProjectExplorer.class, true); 53 | } 54 | 55 | /** 56 | * Close project explorer 57 | */ 58 | public void closeProjectExplorer() { 59 | togglePane(ButtonLabels.PROJECT_STRIPE_BUTTON_LABEL, ProjectExplorer.class, false); 60 | } 61 | 62 | /** 63 | * Open maven build tool pane 64 | */ 65 | public void openMavenBuildToolPane() { 66 | togglePane(ButtonLabels.MAVEN_STRIPE_BUTTON_LABEL, MavenBuildToolPane.class, true); 67 | } 68 | 69 | /** 70 | * Close maven build tool pane 71 | */ 72 | public void closeMavenBuildToolPane() { 73 | togglePane(ButtonLabels.MAVEN_STRIPE_BUTTON_LABEL, MavenBuildToolPane.class, false); 74 | } 75 | 76 | /** 77 | * Open gradle build tool pane 78 | */ 79 | public void openGradleBuildToolPane() { 80 | togglePane(ButtonLabels.GRADLE_STRIPE_BUTTON_LABEL, GradleBuildToolPane.class, true); 81 | } 82 | 83 | /** 84 | * Close gradle build tool pane 85 | */ 86 | public void closeGradleBuildToolPane() { 87 | togglePane(ButtonLabels.GRADLE_STRIPE_BUTTON_LABEL, GradleBuildToolPane.class, false); 88 | } 89 | 90 | protected void togglePane(String label, Class fixtureClass, boolean openPane) { 91 | if ((!isPaneOpened(fixtureClass) && openPane) || (isPaneOpened(fixtureClass) && !openPane)) { 92 | clickOnStripeButton(label, openPane); 93 | } 94 | } 95 | 96 | public boolean isPaneOpened(Class fixtureClass) { 97 | try { 98 | return find(fixtureClass, Duration.ofSeconds(10)).isShowing(); 99 | } catch (WaitForConditionTimeoutException e) { 100 | return false; 101 | } 102 | } 103 | 104 | private void clickOnStripeButton(String label, boolean openPane) { 105 | if (ideaVersionInt >= 20242) { 106 | ToolWindowToolbar toolbar; 107 | if (isRightToolbarButton(label)) { 108 | toolbar = remoteRobot.find(ToolWindowRightToolbar.class, Duration.ofSeconds(10)); 109 | } else { 110 | toolbar = remoteRobot.find(ToolWindowLeftToolbar.class, Duration.ofSeconds(10)); 111 | } 112 | toolbar.clickStripeButton(label); 113 | } else { 114 | if (openPane) { 115 | button(byXpath(XPathDefinitions.label(label)), Duration.ofSeconds(2)).click(); 116 | } else { 117 | button(byXpath(XPathDefinitions.toolWindowButton(label)), Duration.ofSeconds(2)).click(); 118 | } 119 | } 120 | } 121 | 122 | private boolean isRightToolbarButton(String label) { 123 | return label.equals(ButtonLabels.MAVEN_STRIPE_BUTTON_LABEL) || 124 | label.equals(ButtonLabels.GRADLE_STRIPE_BUTTON_LABEL); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Main CI 2 | name: Java CI with Gradle 3 | 4 | on: 5 | push: 6 | branches: [ main ] 7 | pull_request: 8 | branches: [ main ] 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | 16 | configure_sonar: 17 | runs-on: ubuntu-latest 18 | if: github.event_name == 'pull_request' 19 | 20 | steps: 21 | - name: Save Sonar config on PR 22 | run: | 23 | mkdir -p ./prInfo 24 | echo ${{ github.event.number }} > ./prInfo/PR 25 | echo ${{ github.base_ref }} > ./prInfo/base_ref 26 | echo ${{ github.head_ref }} > ./prInfo/head_ref 27 | - uses: actions/upload-artifact@v4 28 | with: 29 | name: prInfo 30 | path: prInfo/ 31 | 32 | verify_dependencies: 33 | runs-on: ubuntu-latest 34 | if: github.event_name == 'pull_request' 35 | 36 | steps: 37 | - uses: actions/checkout@v4 38 | - name: Set up JDK 17 39 | uses: actions/setup-java@v4 40 | with: 41 | java-version: 17 42 | distribution: 'temurin' 43 | cache: 'gradle' 44 | - name: Run verification dependency 45 | run: | 46 | ./gradlew --dependency-verification strict build 47 | - name: Archiving reports 48 | uses: actions/upload-artifact@v4 49 | with: 50 | name: dependency-reports 51 | path: build/reports/dependency-verification/* 52 | if: failure() 53 | 54 | run_on_linux: 55 | runs-on: ubuntu-latest 56 | 57 | steps: 58 | - uses: actions/checkout@v4 59 | - name: Set up JDK 17 60 | uses: actions/setup-java@v4 61 | with: 62 | java-version: 17 63 | distribution: 'temurin' 64 | cache: 'gradle' 65 | - name: Run integration tests 66 | run: | 67 | cd src/test-project 68 | xvfb-run --server-args="-screen 0 1920x1080x24" ./gradlew integrationUITest --warning-mode none 69 | - name: Archiving tests reports 70 | uses: actions/upload-artifact@v4 71 | with: 72 | name: linux-test-reports 73 | path: src/test-project/build/reports/tests/* 74 | if: always() 75 | - name: Archiving screenshots 76 | uses: actions/upload-artifact@v4 77 | with: 78 | name: linux-screenshots 79 | path: src/test-project/build/screenshots/* 80 | if-no-files-found: ignore 81 | if: always() 82 | - name: Archiving StepLogger logs 83 | uses: actions/upload-artifact@v4 84 | with: 85 | name: linux-steplogger-logs 86 | path: src/test-project/build/test-results/* 87 | if: always() 88 | - name: Archiving coverage for sonar 89 | uses: actions/upload-artifact@v4 90 | if: always() 91 | with: 92 | name: sonar-coverage 93 | path: | 94 | src/test-project/build/test-results/**/*.xml 95 | src/test-project/build/jacoco/ 96 | 97 | run_on_windows: 98 | runs-on: windows-latest 99 | steps: 100 | - uses: actions/checkout@v4 101 | - name: Set up JDK 17 102 | uses: actions/setup-java@v4 103 | with: 104 | java-version: 17 105 | distribution: 'temurin' 106 | cache: 'gradle' 107 | - name: Run integration tests 108 | run: | 109 | cd src/test-project 110 | ./gradlew.bat integrationUITest --warning-mode none 111 | - name: Archiving tests reports 112 | uses: actions/upload-artifact@v4 113 | with: 114 | name: windows-test-reports 115 | path: src/test-project/build/reports/tests/* 116 | if: always() 117 | - name: Archiving screenshots 118 | uses: actions/upload-artifact@v4 119 | with: 120 | name: windows-screenshots 121 | path: src/test-project/build/screenshots/* 122 | if-no-files-found: ignore 123 | if: always() 124 | - name: Archiving StepLogger logs 125 | uses: actions/upload-artifact@v4 126 | with: 127 | name: windows-steplogger-logs 128 | path: src/test-project/build/test-results/* 129 | if: always() 130 | 131 | run_on_macos: 132 | runs-on: macos-latest 133 | steps: 134 | - uses: actions/checkout@v4 135 | - name: Set up JDK 17 136 | uses: actions/setup-java@v4 137 | with: 138 | java-version: 17 139 | distribution: 'temurin' 140 | cache: 'gradle' 141 | - name: Run integration tests 142 | run: | 143 | cd src/test-project 144 | ./gradlew integrationUITest --warning-mode none 145 | - name: Archiving tests reports 146 | uses: actions/upload-artifact@v4 147 | with: 148 | name: macos-test-reports 149 | path: src/test-project/build/reports/tests/* 150 | if: always() 151 | - name: Archiving screenshots 152 | uses: actions/upload-artifact@v4 153 | with: 154 | name: macos-screenshots 155 | path: src/test-project/build/screenshots/* 156 | if-no-files-found: ignore 157 | if: always() 158 | - name: Archiving StepLogger logs 159 | uses: actions/upload-artifact@v4 160 | with: 161 | name: macos-steplogger-logs 162 | path: src/test-project/build/test-results/* 163 | if: always() 164 | -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/menubar/MenuBar.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.menubar; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.fixtures.ActionButtonFixture; 15 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 16 | import com.intellij.remoterobot.fixtures.JButtonFixture; 17 | import com.intellij.remoterobot.fixtures.JPopupMenuFixture; 18 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 19 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 20 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 21 | 22 | import java.time.Duration; 23 | import java.util.List; 24 | import java.util.logging.Logger; 25 | 26 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 27 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 28 | 29 | /** 30 | * Top menu fixture 31 | * 32 | * @author zcervink@redhat.com 33 | */ 34 | public class MenuBar { 35 | private static final Logger LOGGER = Logger.getLogger(MenuBar.class.getName()); 36 | private final RemoteRobot remoteRobot; 37 | private final int ideaVersionInt = UITestRunner.getIdeaVersionInt(); 38 | 39 | public MenuBar(RemoteRobot remoteRobot) { 40 | this.remoteRobot = remoteRobot; 41 | } 42 | 43 | /** 44 | * Navigate to the location in main IDE menu according to the given path, perform a given mouse action on the last item in the path 45 | * 46 | * @param path path to navigate in the main menu 47 | */ 48 | public void navigateTo(String... path) { 49 | if (path.length == 0) { 50 | return; 51 | } 52 | if (ideaVersionInt >= 20242) { 53 | remoteRobot.find(ActionButtonFixture.class, byXpath(XPathDefinitions.MAIN_MENU)).click(); 54 | } 55 | 56 | if (!isVisible()) { 57 | LOGGER.severe("Main Menu is not visible."); 58 | return; 59 | } 60 | 61 | JButtonFixture mainMenuFirstItem = mainMenuItem(path[0]); 62 | if (mainMenuFirstItem != null) { 63 | if (ideaVersionInt >= 20242) { 64 | mainMenuFirstItem.moveMouse(); 65 | } else { 66 | mainMenuFirstItem.click(); 67 | } 68 | 69 | // Wait for the JPopupMenuFixture to appear 70 | waitFor(Duration.ofSeconds(5), Duration.ofSeconds(1), "JPopupMenu to appear", () -> 71 | !remoteRobot.findAll(JPopupMenuFixture.class, JPopupMenuFixture.Companion.byType()).isEmpty() 72 | ); 73 | } 74 | 75 | if (path.length == 1) { 76 | return; 77 | } 78 | 79 | for (int i = 1; i < path.length - 1; i++) { 80 | List allContextMenus = remoteRobot.findAll(JPopupMenuFixture.class, JPopupMenuFixture.Companion.byType()); 81 | JPopupMenuFixture lastContextMenu = allContextMenus.get(allContextMenus.size() - 1); 82 | lastContextMenu.findText(path[i]).moveMouse(); 83 | waitFor(Duration.ofSeconds(5), Duration.ofSeconds(1), "SubMenu to appear", () -> 84 | remoteRobot.findAll(JPopupMenuFixture.class, JPopupMenuFixture.Companion.byType()).size() > allContextMenus.size() 85 | ); 86 | } 87 | 88 | List allContextMenus = remoteRobot.findAll(JPopupMenuFixture.class, JPopupMenuFixture.Companion.byType()); 89 | JPopupMenuFixture lastContextMenu = allContextMenus.get(allContextMenus.size() - 1); 90 | lastContextMenu.findText(path[path.length - 1]).click(); 91 | } 92 | 93 | private JButtonFixture mainMenuItem(String label) { 94 | if (remoteRobot.isMac()) { 95 | return null; 96 | } 97 | return getMainMenu().button(byXpath(XPathDefinitions.label(label)), Duration.ofSeconds(5)); 98 | } 99 | 100 | public CommonContainerFixture getMainMenu() { 101 | CommonContainerFixture cf; 102 | if (remoteRobot.isLinux() && ideaVersionInt <= 20242) { 103 | cf = remoteRobot.find(CommonContainerFixture.class, byXpath(XPathDefinitions.LINUX_MAIN_MENU), Duration.ofSeconds(5)); 104 | } else if ((remoteRobot.isWin() && ideaVersionInt >= 20241) || (remoteRobot.isLinux() && ideaVersionInt > 20242)) { 105 | cf = remoteRobot.find(CommonContainerFixture.class, byXpath(XPathDefinitions.WINDOWS_MAIN_MENU_2024_1_AND_NEWER), Duration.ofSeconds(5)); 106 | } else if (remoteRobot.isWin()) { 107 | cf = remoteRobot.find(CommonContainerFixture.class, byXpath(XPathDefinitions.WINDOWS_MAIN_MENU_2022_2_TO_2023_2), Duration.ofSeconds(5)); 108 | } else { 109 | throw new IllegalStateException("Can't get main menu. System OS is %s / IdeaVersion is %d".formatted(remoteRobot.getOs(), ideaVersionInt)); 110 | } 111 | return cf; 112 | } 113 | 114 | public boolean isVisible() { 115 | // check menu already visible 116 | try { 117 | return (getMainMenu() != null); 118 | } catch (WaitForConditionTimeoutException e) { 119 | return false; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /src/main/java/com/redhat/devtools/intellij/commonuitest/fixtures/mainidewindow/MainIdeWindow.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2020 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow; 12 | 13 | import com.intellij.remoterobot.RemoteRobot; 14 | import com.intellij.remoterobot.data.RemoteComponent; 15 | import com.intellij.remoterobot.fixtures.ActionButtonFixture; 16 | import com.intellij.remoterobot.fixtures.CommonContainerFixture; 17 | import com.intellij.remoterobot.fixtures.DefaultXpath; 18 | import com.intellij.remoterobot.fixtures.FixtureName; 19 | import com.intellij.remoterobot.utils.Keyboard; 20 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 21 | import com.redhat.devtools.intellij.commonuitest.UITestRunner; 22 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 23 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.navigation.SearchEverywherePopup; 24 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.menubar.MenuBar; 25 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 26 | import com.redhat.devtools.intellij.commonuitest.utils.internalerror.IdeInternalErrorUtils; 27 | import org.jetbrains.annotations.NotNull; 28 | 29 | import java.awt.event.KeyEvent; 30 | import java.time.Duration; 31 | 32 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 33 | 34 | /** 35 | * Main IDE window fixture 36 | * 37 | * @author zcervink@redhat.com 38 | */ 39 | @DefaultXpath(by = "IdeFrameImpl type", xpath = XPathDefinitions.MAIN_IDE_WINDOW) 40 | @FixtureName(name = "Main IDE Window") 41 | public class MainIdeWindow extends CommonContainerFixture { 42 | private final RemoteRobot remoteRobot; 43 | 44 | public MainIdeWindow(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) { 45 | super(remoteRobot, remoteComponent); 46 | this.remoteRobot = remoteRobot; 47 | } 48 | 49 | /** 50 | * Maximize the main IDE window 51 | */ 52 | public void maximizeIdeWindow() { 53 | if (UITestRunner.getIdeaVersionInt() <= 20223) { 54 | return; 55 | } 56 | if (remoteRobot.isWin()) { 57 | runJs(""" 58 | const width = component.getWidth(); 59 | const height = component.getHeight(); 60 | const horizontal_offset = width-72; 61 | robot.click(component, new Point(horizontal_offset, 14), MouseButton.LEFT_BUTTON, 1); 62 | const width_after = component.getWidth(); 63 | const height_after = component.getHeight(); 64 | const horizontal_offset_after = width_after-72; 65 | if (width > width_after || height > height_after) { robot.click(component, new Point(horizontal_offset_after, 14), MouseButton.LEFT_BUTTON, 1); }"""); 66 | 67 | } else { 68 | runJs(""" 69 | const width = component.getWidth(); 70 | const height = component.getHeight(); 71 | const horizontal_offset = width/2; 72 | robot.click(component, new Point(horizontal_offset, 10), MouseButton.LEFT_BUTTON, 2); 73 | const width_after = component.getWidth(); 74 | const height_after = component.getHeight(); 75 | const horizontal_offset_after = width_after/2; 76 | if (width > width_after || height > height_after) { robot.click(component, new Point(horizontal_offset_after, 10), MouseButton.LEFT_BUTTON, 2); }"""); 77 | } 78 | } 79 | 80 | /** 81 | * Close the currently opened project 82 | */ 83 | public void closeProject() { 84 | if (UITestRunner.getIdeaVersionInt() == 20233) { 85 | invokeCmdUsingSearchEverywherePopup("Close Project"); 86 | } else { 87 | new MenuBar(remoteRobot).navigateTo("File", "Close Project"); 88 | } 89 | IdeInternalErrorUtils.clearWindowsErrorsIfTheyAppear(remoteRobot); 90 | remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)).runJs("const horizontal_offset = component.getWidth()/2;\n" + 91 | "robot.click(component, new Point(horizontal_offset, 10), MouseButton.LEFT_BUTTON, 1);"); 92 | } 93 | 94 | /** 95 | * Invoke a command using the Search Everywhere popup 96 | * 97 | * @param cmdToInvoke String representation of command which will be executed using the Search Everywhere popup 98 | */ 99 | public void invokeCmdUsingSearchEverywherePopup(String cmdToInvoke) { 100 | openSearchEverywherePopup().invokeCmd(cmdToInvoke); 101 | } 102 | 103 | private SearchEverywherePopup openSearchEverywherePopup() { 104 | try { 105 | find(ActionButtonFixture.class, byXpath("//div[@myicon='search.svg']"), Duration.ofSeconds(5)).click(); 106 | SearchEverywherePopup searchEverywherePopup = find(SearchEverywherePopup.class, Duration.ofSeconds(5)); 107 | searchEverywherePopup.activateTab("All"); 108 | return searchEverywherePopup; 109 | } catch (WaitForConditionTimeoutException e) { 110 | Keyboard keyboard = new Keyboard(remoteRobot); 111 | if (remoteRobot.isMac()) { 112 | keyboard.hotKey(KeyEvent.VK_META, KeyEvent.VK_O); 113 | } else { 114 | keyboard.hotKey(KeyEvent.VK_CONTROL, KeyEvent.VK_N); 115 | } 116 | SearchEverywherePopup searchEverywherePopup = find(SearchEverywherePopup.class, Duration.ofSeconds(10)); 117 | searchEverywherePopup.activateTab("All"); 118 | return searchEverywherePopup; 119 | } 120 | } 121 | 122 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/dialogs/settings/SettingsDialogTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.dialogs.settings; 12 | 13 | import com.intellij.remoterobot.fixtures.ComponentFixture; 14 | import com.intellij.remoterobot.fixtures.JCheckboxFixture; 15 | import com.intellij.remoterobot.fixtures.JTreeFixture; 16 | import com.intellij.remoterobot.utils.WaitForConditionTimeoutException; 17 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 19 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.settings.SettingsDialog; 20 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 21 | import org.junit.jupiter.api.AfterAll; 22 | import org.junit.jupiter.api.AfterEach; 23 | import org.junit.jupiter.api.BeforeAll; 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import java.time.Duration; 28 | import java.util.logging.Level; 29 | 30 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 31 | import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor; 32 | import static org.junit.jupiter.api.Assertions.assertTrue; 33 | import static org.junit.jupiter.api.Assertions.fail; 34 | 35 | /** 36 | * SettingsDialog test 37 | * 38 | * @author zcervink@redhat.com 39 | */ 40 | class SettingsDialogTest extends AbstractLibraryBaseTest { 41 | private static final String APPEARANCE_AND_BEHAVIOR = "Appearance & Behavior"; 42 | private static final String NOTIFICATIONS = "Notifications"; 43 | private static FlatWelcomeFrame flatWelcomeFrame; 44 | private SettingsDialog settingsDialog = null; 45 | 46 | @BeforeAll 47 | static void openSettingsDialog() { 48 | flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 49 | flatWelcomeFrame.openSettingsDialog(); 50 | } 51 | 52 | @AfterAll 53 | static void closeSettingsDialog() { 54 | remoteRobot.find(SettingsDialog.class, Duration.ofSeconds(5)).cancel(); 55 | } 56 | 57 | @BeforeEach 58 | void prepareSettingsDialogFixture() { 59 | if (settingsDialog == null) { 60 | settingsDialog = remoteRobot.find(SettingsDialog.class, Duration.ofSeconds(5)); 61 | } 62 | } 63 | 64 | @AfterEach 65 | void reopenSettingsDialogIfNeeded() { 66 | try { 67 | remoteRobot.find(SettingsDialog.class, Duration.ofSeconds(5)); 68 | } catch (WaitForConditionTimeoutException e) { 69 | flatWelcomeFrame.openSettingsDialog(); 70 | settingsDialog = remoteRobot.find(SettingsDialog.class, Duration.ofSeconds(5)); 71 | } 72 | } 73 | 74 | @Test 75 | void navigateToTest() { 76 | settingsDialog.navigateTo(APPEARANCE_AND_BEHAVIOR, NOTIFICATIONS); 77 | try { 78 | waitFor(Duration.ofSeconds(10), Duration.ofMillis(250), "The 'Notifications' settings page is not available.", () -> isSettingsPageLoaded(NOTIFICATIONS)); 79 | } catch (WaitForConditionTimeoutException e) { 80 | LOGGER.log(Level.SEVERE, e.getMessage(), e); 81 | fail("The 'Settings' dialog should display the 'Notifications' page."); 82 | } 83 | 84 | settingsDialog.navigateTo("Keymap"); 85 | try { 86 | waitFor(Duration.ofSeconds(10), Duration.ofMillis(250), "The 'Keymap' settings page is not available.", () -> isSettingsPageLoaded("Keymap")); 87 | } catch (WaitForConditionTimeoutException e) { 88 | LOGGER.log(Level.SEVERE, e.getMessage(), e); 89 | fail("The 'Settings' dialog should display the 'Keymap' page."); 90 | } 91 | } 92 | 93 | @Test 94 | void settingsTreeTest() { 95 | JTreeFixture settingsTree = settingsDialog.settingsTree(); 96 | assertTrue(settingsTree.hasText(APPEARANCE_AND_BEHAVIOR), "The Settings tree does not contain the 'Appearance & Behavior' item."); 97 | } 98 | 99 | @Test 100 | void okTest() { 101 | settingsDialog.ok(); 102 | Duration timeout = Duration.ofSeconds(5); 103 | try { 104 | remoteRobot.find(SettingsDialog.class, timeout); 105 | fail("The 'Settings' dialog should be closed but is not."); 106 | } catch (WaitForConditionTimeoutException e) { 107 | LOGGER.log(Level.INFO, e.getMessage(), e); 108 | } 109 | } 110 | 111 | @Test 112 | void applyTest() { 113 | settingsDialog = remoteRobot.find(SettingsDialog.class, Duration.ofSeconds(5)); 114 | settingsDialog.navigateTo(APPEARANCE_AND_BEHAVIOR, NOTIFICATIONS); 115 | JCheckboxFixture balloonNotificationsCheckbox = settingsDialog.checkBox("Display balloon notifications", true); 116 | balloonNotificationsCheckbox.setValue(!balloonNotificationsCheckbox.isSelected()); 117 | settingsDialog.apply(); 118 | balloonNotificationsCheckbox.setValue(!balloonNotificationsCheckbox.isSelected()); 119 | settingsDialog.apply(); 120 | } 121 | 122 | @Test 123 | void cancelTest() { 124 | settingsDialog.cancel(); 125 | Duration timeout = Duration.ofSeconds(5); 126 | try { 127 | remoteRobot.find(SettingsDialog.class, timeout); 128 | fail("The 'Settings' dialog should be closed but is not."); 129 | } catch (WaitForConditionTimeoutException e) { 130 | LOGGER.log(Level.INFO, e.getMessage(), e); 131 | } 132 | } 133 | 134 | private boolean isSettingsPageLoaded(String label) { 135 | ComponentFixture cf = remoteRobot.find(ComponentFixture.class, byXpath(XPathDefinitions.BREAD_CRUMBS)); 136 | return cf.hasText(label); 137 | } 138 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/dialogs/settings/pages/NotificationsPageTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.dialogs.settings.pages; 12 | 13 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 14 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.FlatWelcomeFrame; 15 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.settings.SettingsDialog; 16 | import com.redhat.devtools.intellij.commonuitest.fixtures.dialogs.settings.pages.NotificationsPage; 17 | import org.junit.jupiter.api.AfterAll; 18 | import org.junit.jupiter.api.AfterEach; 19 | import org.junit.jupiter.api.BeforeAll; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | 23 | import java.time.Duration; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertFalse; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | /** 29 | * NotificationsPage test 30 | * 31 | * @author zcervink@redhat.com 32 | */ 33 | class NotificationsPageTest extends AbstractLibraryBaseTest { 34 | private static SettingsDialog settingsDialog; 35 | private static NotificationsPage notificationsPage; 36 | private boolean balloonNotificationsCheckBox; 37 | private boolean systemNotificationsCheckBox; 38 | 39 | @BeforeAll 40 | static void openSettingsDialog() { 41 | FlatWelcomeFrame flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 42 | flatWelcomeFrame.openSettingsDialog(); 43 | settingsDialog = remoteRobot.find(SettingsDialog.class, Duration.ofSeconds(5)); 44 | settingsDialog.navigateTo("Appearance & Behavior", "Notifications"); 45 | notificationsPage = remoteRobot.find(NotificationsPage.class, Duration.ofSeconds(5)); 46 | } 47 | 48 | @AfterAll 49 | static void closeSettingsDialog() { 50 | settingsDialog.cancel(); 51 | } 52 | 53 | @BeforeEach 54 | void backupSettings() { 55 | balloonNotificationsCheckBox = notificationsPage.displayBalloonNotificationsCheckBox().isSelected(); 56 | systemNotificationsCheckBox = notificationsPage.displaySystemNotificationsCheckBox().isSelected(); 57 | } 58 | 59 | @AfterEach 60 | void restoreSettings() { 61 | notificationsPage.displayBalloonNotificationsCheckBox().setValue(balloonNotificationsCheckBox); 62 | notificationsPage.displaySystemNotificationsCheckBox().setValue(systemNotificationsCheckBox); 63 | } 64 | 65 | @Test 66 | void toggleNotificationsTest() { 67 | notificationsPage.displayBalloonNotificationsCheckBox().setValue(true); 68 | notificationsPage.displaySystemNotificationsCheckBox().setValue(true); 69 | boolean balloonNotificationsEnabled = notificationsPage.displayBalloonNotificationsCheckBox().isSelected(); 70 | boolean systemNotificationsEnabled = notificationsPage.displaySystemNotificationsCheckBox().isSelected(); 71 | assertTrue(balloonNotificationsEnabled && systemNotificationsEnabled, "The 'Balloon Notifications' and the 'System Notifications' checkboxes should be both checked."); 72 | 73 | notificationsPage.toggleNotifications(false); 74 | balloonNotificationsEnabled = notificationsPage.displayBalloonNotificationsCheckBox().isSelected(); 75 | systemNotificationsEnabled = notificationsPage.displaySystemNotificationsCheckBox().isSelected(); 76 | assertTrue(!balloonNotificationsEnabled && !systemNotificationsEnabled, "The 'Balloon Notifications' and the 'System Notifications' checkboxes should be both unchecked."); 77 | } 78 | 79 | @Test 80 | void toggleBalloonNotificationsTest() { 81 | notificationsPage.displayBalloonNotificationsCheckBox().setValue(true); 82 | notificationsPage.toggleBalloonNotifications(false); 83 | boolean balloonNotificationsEnabled = notificationsPage.displayBalloonNotificationsCheckBox().isSelected(); 84 | assertFalse(balloonNotificationsEnabled, "The 'Balloon Notifications' checkbox should be unchecked."); 85 | } 86 | 87 | @Test 88 | void toggleSystemNotificationsTest() { 89 | notificationsPage.displaySystemNotificationsCheckBox().setValue(true); 90 | notificationsPage.toggleSystemNotifications(false); 91 | boolean systemNotificationsEnabled = notificationsPage.displaySystemNotificationsCheckBox().isSelected(); 92 | assertFalse(systemNotificationsEnabled, "The 'System Notifications' checkbox should be unchecked."); 93 | } 94 | 95 | @Test 96 | void displayBalloonNotificationsCheckBoxTest() { 97 | notificationsPage.displayBalloonNotificationsCheckBox().setValue(true); 98 | boolean balloonNotificationsEnabled = notificationsPage.displayBalloonNotificationsCheckBox().isSelected(); 99 | assertTrue(balloonNotificationsEnabled, "The 'Balloon Notifications' checkbox should be checked."); 100 | 101 | notificationsPage.displayBalloonNotificationsCheckBox().setValue(false); 102 | balloonNotificationsEnabled = notificationsPage.displayBalloonNotificationsCheckBox().isSelected(); 103 | assertFalse(balloonNotificationsEnabled, "The 'Balloon Notifications' checkbox should be unchecked."); 104 | } 105 | 106 | @Test 107 | void displaySystemNotificationsCheckBoxTest() { 108 | notificationsPage.displaySystemNotificationsCheckBox().setValue(true); 109 | boolean systemNotificationsEnabled = notificationsPage.displaySystemNotificationsCheckBox().isSelected(); 110 | assertTrue(systemNotificationsEnabled, "The 'System Notifications' checkbox should be checked."); 111 | 112 | notificationsPage.displaySystemNotificationsCheckBox().setValue(false); 113 | systemNotificationsEnabled = notificationsPage.displaySystemNotificationsCheckBox().isSelected(); 114 | assertFalse(systemNotificationsEnabled, "The 'System Notifications' checkbox should be unchecked."); 115 | } 116 | } -------------------------------------------------------------------------------- /src/test-project/src/test/java/com/redhat/devtools/intellij/commonuitest/fixtures/test/mainidewindow/toolwindowspane/ProjectExplorerTest.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at https://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package com.redhat.devtools.intellij.commonuitest.fixtures.test.mainidewindow.toolwindowspane; 12 | 13 | import com.intellij.remoterobot.fixtures.ComponentFixture; 14 | import com.intellij.remoterobot.fixtures.JPopupMenuFixture; 15 | import com.intellij.remoterobot.utils.Keyboard; 16 | import com.redhat.devtools.intellij.commonuitest.AbstractLibraryBaseTest; 17 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.menubar.MenuBar; 18 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ProjectExplorer; 19 | import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane; 20 | import com.redhat.devtools.intellij.commonuitest.utils.constants.XPathDefinitions; 21 | import com.redhat.devtools.intellij.commonuitest.utils.project.CreateCloseUtils; 22 | import com.redhat.devtools.intellij.commonuitest.utils.project.NewProjectType; 23 | import com.redhat.devtools.intellij.commonuitest.utils.steps.SharedSteps; 24 | import org.junit.jupiter.api.AfterAll; 25 | import org.junit.jupiter.api.AfterEach; 26 | import org.junit.jupiter.api.BeforeAll; 27 | import org.junit.jupiter.api.Test; 28 | 29 | import java.time.Duration; 30 | 31 | import static com.intellij.remoterobot.search.locators.Locators.byXpath; 32 | import static org.junit.jupiter.api.Assertions.assertTrue; 33 | 34 | /** 35 | * Project Explorer test 36 | * 37 | * @author zcervink@redhat.com 38 | */ 39 | class ProjectExplorerTest extends AbstractLibraryBaseTest { 40 | private static final String PROJECT_NAME = "pe_java_project"; 41 | private static ProjectExplorer projectExplorer; 42 | private final Keyboard keyboard = new Keyboard(remoteRobot); 43 | 44 | @BeforeAll 45 | static void prepareProject() { 46 | CreateCloseUtils.createNewProject(remoteRobot, PROJECT_NAME, NewProjectType.PLAIN_JAVA); 47 | ToolWindowPane toolWinPane = remoteRobot.find(ToolWindowPane.class, Duration.ofSeconds(10)); 48 | toolWinPane.openProjectExplorer(); 49 | projectExplorer = toolWinPane.find(ProjectExplorer.class, Duration.ofSeconds(10)); 50 | } 51 | 52 | @AfterAll 53 | static void closeCurrentProject() { 54 | CreateCloseUtils.closeProject(remoteRobot); 55 | } 56 | 57 | @AfterEach 58 | void hideAllPopups() { 59 | keyboard.escape(); 60 | } 61 | 62 | @Test 63 | void isItemPresentTest() { 64 | boolean isItemPresent = projectExplorer.isItemPresent(PROJECT_NAME, "src", "Main"); 65 | assertTrue(isItemPresent, "The file 'Main' should be present in the project on location 'src/Main' but is not."); 66 | } 67 | 68 | @Test 69 | void openFileTest() { 70 | if (ideaVersionInt >= 20231) { 71 | //ensure no editor is opened 72 | new MenuBar(remoteRobot).navigateTo("Window", "Editor Tabs", "Close All Tabs"); 73 | projectExplorer.openFile(PROJECT_NAME, "src", "Main"); 74 | assertTrue(remoteRobot.find(ComponentFixture.class, byXpath(XPathDefinitions.PROJECT_LABEL)).isShowing()); 75 | } 76 | } 77 | 78 | @Test 79 | void openContextMenuOnTest() { 80 | JPopupMenuFixture contextMenu = projectExplorer.openContextMenuOn("Scratches and Consoles"); 81 | assertTrue(contextMenu.hasText("New"), "The context menu on 'Scratches and Consoles' item should be opened but is not."); 82 | } 83 | 84 | @Test 85 | void openViewsPopupTest() { 86 | JPopupMenuFixture contextMenu = projectExplorer.openViewsPopup(); 87 | assertTrue(contextMenu.hasText("Packages"), "The View popup menu should be opened but is not."); 88 | } 89 | 90 | @Test 91 | void selectOpenedFileTest() { 92 | if (ideaVersionInt >= 20231) { 93 | projectExplorer.expandAll(); 94 | projectExplorer.openFile(PROJECT_NAME, "src", "Main"); 95 | projectExplorer.projectViewTree().clickRow(0); 96 | SharedSteps.waitForComponentByXpath(remoteRobot, 3, 200, byXpath(XPathDefinitions.MY_ICON_LOCATE_SVG)); 97 | projectExplorer.selectOpenedFile(); 98 | SharedSteps.waitForComponentByXpath(remoteRobot, 3, 200, byXpath(XPathDefinitions.MY_ICON_LOCATE_SVG)); 99 | assertTrue(projectExplorer.projectViewTree().isPathSelected( 100 | projectExplorer.projectViewTree().getValueAtRow(0), "src", "Main"), 101 | "The file 'Main' should be selected but is not." 102 | ); 103 | } 104 | } 105 | 106 | @Test 107 | void expandAllTest() { 108 | projectExplorer.collapseAll(); 109 | int itemsInTreeBeforeExpanding = projectExplorer.projectViewTree().collectRows().size(); 110 | projectExplorer.projectViewTree().clickRow(0); // Newer versions expands selected subtree (not all rows) 111 | projectExplorer.expandAll(); 112 | int itemsInTreeAfterExpanding = projectExplorer.projectViewTree().collectRows().size(); 113 | assertTrue(itemsInTreeAfterExpanding > itemsInTreeBeforeExpanding, "Expanding of the 'Project View' tree was not successful."); 114 | } 115 | 116 | @Test 117 | void collapseAllTest() { 118 | projectExplorer.projectViewTree().expand(PROJECT_NAME); 119 | int itemsInTreeBeforeCollapsing = projectExplorer.projectViewTree().collectRows().size(); 120 | projectExplorer.collapseAll(); 121 | int itemsInTreeAfterCollapsing = projectExplorer.projectViewTree().collectRows().size(); 122 | assertTrue(itemsInTreeAfterCollapsing < itemsInTreeBeforeCollapsing, "Collapsing of the 'Project View' tree was not successful."); 123 | } 124 | 125 | @Test 126 | void openSettingsPopupTest() { 127 | JPopupMenuFixture contextMenu = projectExplorer.openSettingsPopup(); 128 | assertTrue(contextMenu.hasText("Help"), "The Settings popup menu should be opened but is not."); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to the IntelliJ IDEA UI test library project! Here you'll find several pieces of information and advices on how to set up, use and contribute to this library. 2 | 3 | ## Purpose of this project 4 | This project allows you to create automated UI tests for your IntelliJ IDEA plugin project. Using this library you are able to access UI elements such as buttons, inputs, tree elements etc. and perform actions with them. Navigating through wizards, clicking on buttons or editing file content of newly created project could be automated using this library. 5 | 6 | ## Any Suggestions or Questions? 7 | Please submit an [issue](https://github.com/redhat-developer/intellij-common-ui-test-library/issues) to this project. 8 | 9 | ## Contributing 10 | Feel free to contribute to this project! See the [contribution guide](https://github.com/redhat-developer/intellij-common-ui-test-library/blob/main/CONTRIBUTING.md) for more details. 11 | 12 | ## Quick setup 13 | The setup of this library is easy - just extend the **build.gradle.kts** file as described in the following steps, and you are ready to write your first UI test. 14 | 15 | ### STEP #1: Adding repositories 16 | You need to add the following nexus and JetBrains repositories: 17 | ``` 18 | repositories { 19 | maven { 20 | url 'https://raw.githubusercontent.com/redhat-developer/intellij-common-ui-test-library/repository/' 21 | } 22 | maven { 23 | url 'https://packages.jetbrains.team/maven/p/ij/intellij-dependencies' 24 | } 25 | } 26 | ``` 27 | 28 | ### STEP #2: Adding dependencies 29 | Add the following dependency: 30 | ``` 31 | dependencies { 32 | compile 'com.redhat.devtools.intellij:intellij-common-ui-test-library:0.4.4' 33 | } 34 | ``` 35 | 36 | ### STEP #3: Adding source sets 37 | The following source set is needed to define where in your project will be your UI tests and resources located. The following example displays the 'src/it/java' location for java code of UI tests and the 'src/it/resources' location for resources: 38 | ``` 39 | sourceSets { 40 | integrationTest { 41 | java.srcDir file('src/it/java') 42 | resources.srcDir file('src/it/resources') 43 | compileClasspath += sourceSets.main.get().compileClasspath + sourceSets.test.get().compileClasspath 44 | runtimeClasspath += output + compileClasspath + sourceSets.test.get().runtimeClasspath 45 | } 46 | } 47 | ``` 48 | 49 | ### STEP #4: Adding tasks 50 | ``` 51 | task integrationTest(type: Test) { 52 | useJUnitPlatform() 53 | description = 'Runs the integration tests.' 54 | group = 'verification' 55 | testClassesDirs = sourceSets.integrationTest.output.classesDirs 56 | classpath = sourceSets.integrationTest.runtimeClasspath 57 | outputs.upToDateWhen { false } 58 | mustRunAfter test 59 | } 60 | 61 | runIdeForUiTests { 62 | systemProperty "robot-server.port", System.getProperty("robot-server.port") 63 | } 64 | ``` 65 | ## Additional Features 66 | 67 | ### Creating a Project 68 | 69 | **Creating an Empty Project:** 70 | Use the following method to create an empty project with a specified name: 71 | 72 | ```java 73 | CreateCloseUtils.createEmptyProject(remoteRobot, "empty-test-project"); 74 | ``` 75 | **Creating a New Project with a Specific Type:** 76 | You can also create a new project with a specific type, such as Java, Maven, or Gradle: 77 | ```java 78 | CreateCloseUtils.createNewProject(remoteRobot, "new-test-project", CreateCloseUtils.NewProjectType.PLAIN_JAVA); 79 | ``` 80 | ### Test project location 81 | Default test project location is `/home/user/IdeaProjects/intellij-ui-test-projects/`. 82 | Developers can specify the location where the test project will be created by providing a system property called `testProjectLocation`. For example: 83 | ``` 84 | task integrationTest(type: Test) { 85 | ... 86 | systemProperties['testProjectLocation'] = '/home/user/IdeaProjects/intellij-ui-test-projects/' 87 | ... 88 | } 89 | ``` 90 | Or add the location as a parameter for gradlew command which runs the test. For example: 91 | ``` 92 | systemProperties['testProjectLocation'] = project.hasProperty('testProjectLocation') ? project.property('testProjectLocation') : null 93 | 94 | ./gradlew integrationTest -PtestProjectLocation=${env.HOME}/IdeaProjects/intellij-ui-test-projects/ 95 | ``` 96 | 97 | ### Remote-robot IntelliJ instance logs 98 | If developers want to view the remote-robot intellij instance logs, they can specify system property intellij_debug to save these logs to files, which will be stored inside $user.dir/intellij_debug folder. 99 | ``` 100 | task integrationTest(type: Test) { 101 | ... 102 | systemProperties['intellij_debug'] = 'true' 103 | ... 104 | } 105 | ``` 106 | 107 | ## Start and quit IntelliJ IDEA 108 | Use the following code to start IntelliJ before running the first UI test. The runIde() method not only starts the IDE for UI tests, it also returns reference to the Remote-Robot instance which will be useful later to access UI elements such as buttons, inputs etc. 109 | ``` 110 | private static RemoteRobot robot; 111 | 112 | @BeforeAll 113 | public static void runIdeForUiTests() { 114 | robot = UITestRunner.runIde(UITestRunner.IdeaVersion.COMMUNITY_V_2022_2, 8580); 115 | } 116 | ``` 117 | 118 | After executing all the UI tests close the IDE by running the following command: 119 | ``` 120 | @AfterAll 121 | public static void closeIde() { 122 | UITestRunner.closeIde(); 123 | } 124 | ``` 125 | 126 | ## What next? Implement your first UI test! 127 | After you manage to set up this library to your project and successfully start and quit IntelliJ IDEA, there is no more setup needed. Just start writing your UI tests! Here are some examples that will help you get started: 128 | 129 | ### Create your first fixture 130 | Create an instance of a FlatWelcomeFrame class which allows you to access the 'Welcome to IntelliJ IDEA' dialog's UI. 131 | ``` 132 | FlatWelcomeFrame flatWelcomeFrame = remoteRobot.find(FlatWelcomeFrame.class, Duration.ofSeconds(10)); 133 | ``` 134 | 135 | ### Use the fixture to access UI 136 | After you have the object, it can be used to access the UI - here is an example of clicking on the 'New Project' button: 137 | ``` 138 | flatWelcomeFrame.createNewProject(); 139 | ``` 140 | 141 | ### Use utilities 142 | This library provides several static utility methods for common actions. Here is an example of one useful transformation method: 143 | ``` 144 | String contentListStr = TextUtils.listOfRemoteTextToString(contentList); 145 | ``` 146 | 147 | ### Use any tool provided by Remote-Robot framework 148 | Besides the fixtures and utilities provided by this library you can use any tool from the [Remote-Robot](https://github.com/JetBrains/intellij-ui-test-robot) framework itself. 149 | 150 | --------------------------------------------------------------------------------