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 extends Fixture> fixtureClass, boolean openPane) {
91 | if ((!isPaneOpened(fixtureClass) && openPane) || (isPaneOpened(fixtureClass) && !openPane)) {
92 | clickOnStripeButton(label, openPane);
93 | }
94 | }
95 |
96 | public boolean isPaneOpened(Class extends Fixture> 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 |
--------------------------------------------------------------------------------