Skip to content

Commit

Permalink
test: Fixes in UI integration tests + added Getting Started test cases (
Browse files Browse the repository at this point in the history
#563)

* fix: correct xpath for selecting new project

Signed-off-by: Richard Kocian <[email protected]>

* fix: running integration UI tests with newer version of IntelliJ

Signed-off-by: Richard Kocian <[email protected]>

* test: added Getting Started test cases

Signed-off-by: Richard Kocian <[email protected]>

* build: Added dependency on gson (2.9.0) for UI tests

Signed-off-by: Richard Kocian <[email protected]>

* chore: Fixed copyright 2022 -> 2023

Signed-off-by: Richard Kocian <[email protected]>

* chore: Added junit-platform-launcher for correct working with newer versions of IJ

Signed-off-by: Richard Kocian <[email protected]>

* fix: Find the right GettingStartedView window

Signed-off-by: Richard Kocian <[email protected]>

* fix: Maximalize GettingStartedView after opening

Signed-off-by: Richard Kocian <[email protected]>

* Enabled UI itests, using snapshot of common-ui-test-library

Signed-off-by: Richard Kocian <[email protected]>

* Use IJ Ultimate 2023.2

Signed-off-by: Richard Kocian <[email protected]>

* Added encrypted IJ Ultimate activation key

Signed-off-by: Richard Kocian <[email protected]>

* fix: Use ToolWindowPane instead of ToolWindowsPane

Signed-off-by: Richard Kocian <[email protected]>

* Remove building common-ui-test-library in build job

Signed-off-by: Richard Kocian <[email protected]>

* Close Getting Started menu on start

Signed-off-by: Richard Kocian <[email protected]>

* Wait extend for openshift menu tree item

Signed-off-by: Richard Kocian <[email protected]>

* Comment unstable test -> TODO

Signed-off-by: Richard Kocian <[email protected]>

* Change job trigger to pull_request_target

Signed-off-by: Richard Kocian <[email protected]>

* feat: Added --stacktrace in gradlew command for debug

Signed-off-by: Richard Kocian <[email protected]>

* fix: New intellij license key

Signed-off-by: Richard Kocian <[email protected]>

rh-pre-commit.version: 2.2.0
rh-pre-commit.check-secrets: ENABLED

* feat: Use newest release of common-ui-test-library

Signed-off-by: Richard Kocian <[email protected]>

rh-pre-commit.version: 2.2.0
rh-pre-commit.check-secrets: ENABLED

---------

Signed-off-by: Richard Kocian <[email protected]>
Signed-off-by: Richard Kocián (rkocian) <[email protected]>
Co-authored-by: Stephane Bouchet <[email protected]>
  • Loading branch information
richardkocian and sbouchet authored Mar 4, 2024
1 parent 56f5ff6 commit 989eef4
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 32 deletions.
23 changes: 7 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,6 @@ jobs:

steps:
- uses: actions/checkout@v4
# TODO remove locally building common-ui-test-library after new release of common-ui-test-library
- name: 'Clone common-ui-test-library to Maven Local repository'
run: |
git clone --branch 174 https://github.com/richard0202/intellij-common-ui-test-library.git ../common-ui-test-library
- uses: burrunan/gradle-cache-action@3bf23b8dd95e7d2bacf2470132454fe893a178a1 #v1
name: Build common-ui-test-library
with:
build-root-directory: ../common-ui-test-library
arguments: publishToMavenLocal
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
Expand Down Expand Up @@ -99,13 +90,13 @@ jobs:
run: chmod +x gradlew
- name: Play integration tests
run: ./gradlew integrationTest --continue --no-daemon
#- name: Play integration UI tests
# run: |
# echo "${{ secrets.IDEA_KEY_PASSPHRASE }}" | gpg --decrypt --passphrase-fd 0 --pinentry-mode loopback --output idea_license_token/idea.key idea_license_token/idea.key.gpg
# export DISPLAY=:99.0
# Xvfb -ac :99 -screen 0 1920x1080x16 &
# sleep 10
# ./gradlew integrationUITest --info --continue
- name: Play integration UI tests
run: |
echo "${{ secrets.IDEA_KEY_PASSPHRASE }}" | gpg --decrypt --passphrase-fd 0 --pinentry-mode loopback --output idea_license_token/idea.key idea_license_token/idea.key.gpg
export DISPLAY=:99.0
Xvfb -ac :99 -screen 0 1920x1080x16 &
sleep 10
./gradlew integrationUITest --info --continue --stacktrace
- uses: actions/upload-artifact@v4
if: always()
with:
Expand Down
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ tasks.register('integrationTest', Test) {
}

tasks.register('integrationUITest', Test) {
dependsOn copyKey
useJUnitPlatform {
includeTags 'ui-test'
}
Expand All @@ -144,6 +145,11 @@ tasks.register('integrationUITest', Test) {
}
}

tasks.register('copyKey', Copy) {
from "idea_license_token/idea.key"
into "build/idea-sandbox/config-uiTest"
}

dependencies {
implementation(
'io.fabric8:openshift-client:6.4.1',
Expand All @@ -163,7 +169,7 @@ dependencies {
'org.awaitility:awaitility:4.2.0',
'org.mock-server:mockserver-client-java:5.15.0',
'org.mock-server:mockserver-netty:5.15.0',
'com.redhat.devtools.intellij:intellij-common-ui-test-library:0.2.0',
'com.redhat.devtools.intellij:intellij-common-ui-test-library:0.3.0',
'org.junit.jupiter:junit-jupiter-engine:5.10.0',
'org.junit.jupiter:junit-jupiter-api:5.10.0',
'org.junit.jupiter:junit-jupiter:5.10.0')
Expand Down
Binary file modified idea_license_token/idea.key.gpg
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import com.intellij.remoterobot.RemoteRobot;
import com.intellij.remoterobot.utils.WaitForConditionTimeoutException;
import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.idestatusbar.IdeStatusBar;
import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowsPane;
import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane;
import org.jboss.tools.intellij.openshift.test.ui.annotations.UITest;
import org.jboss.tools.intellij.openshift.test.ui.dialogs.ProjectStructureDialog;
import org.jboss.tools.intellij.openshift.test.ui.junit.TestRunnerExtension;
Expand All @@ -37,7 +37,11 @@ public abstract class AbstractBaseTest {
public static void connect() {
robot = IdeaRunner.getInstance().getRemoteRobot();
ProjectUtility.createEmptyProject(robot, "test-project");

// TODO fix on IJ Ultimate 2023.2 (it should be possible to set some properties to block Tip Dialogs)
ProjectUtility.closeTipDialogIfItAppears(robot);

// TODO fix on IJ Ultimate 2023.2
ProjectStructureDialog.cancelProjectStructureDialogIfItAppears(robot);
ProjectUtility.closeGotItPopup(robot);
IdeStatusBar ideStatusBar = robot.find(IdeStatusBar.class, Duration.ofSeconds(5));
Expand All @@ -50,8 +54,8 @@ public RemoteRobot getRobotReference() {

public boolean isStripeButtonAvailable(String label) {
try {
ToolWindowsPane toolWindowsPane = robot.find(ToolWindowsPane.class);
toolWindowsPane.stripeButton(label, false);
ToolWindowPane toolWindowPane = robot.find(ToolWindowPane.class);
toolWindowPane.stripeButton(label, false);
} catch (WaitForConditionTimeoutException e) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@
******************************************************************************/
package org.jboss.tools.intellij.openshift.test.ui;

import com.intellij.remoterobot.fixtures.ComponentFixture;
import com.intellij.remoterobot.search.locators.Locator;
import org.jboss.tools.intellij.openshift.test.ui.views.GettingStartedView;
import org.jboss.tools.intellij.openshift.test.ui.views.OpenshiftView;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.time.Duration;

import static com.intellij.remoterobot.search.locators.Locators.byXpath;
import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* @author Ihor Okhrimenko, Ondrej Dockal
* @author Ihor Okhrimenko, Ondrej Dockal, Richard Kocian
* Base UI test class verifying presence of tested extensions and OpenShift View presence and content
*/
public class BaseUITest extends AbstractBaseTest {
Expand All @@ -27,14 +34,73 @@ public class BaseUITest extends AbstractBaseTest {
public void openshiftExtensionTest() {
waitFor(Duration.ofSeconds(10), Duration.ofSeconds(1), "The 'OpenShift' stripe button is not available.", () -> isStripeButtonAvailable("OpenShift"));
waitFor(Duration.ofSeconds(10), Duration.ofSeconds(1), "The 'Kubernetes' stripe button is not available.", () -> isStripeButtonAvailable("Kubernetes"));
waitFor(Duration.ofSeconds(10), Duration.ofSeconds(1), "The 'Getting Started' stripe button is not available.", () -> isStripeButtonAvailable("Getting Started"));
}

@Test
public void openshiftViewTest() {
OpenshiftView view = robot.find(OpenshiftView.class);
view.openView();
view.waitForTreeItem("https://kubernetes.default.svc/", 10, 1);
//view.waitForTreeItem("https://kubernetes.default.svc/", 1000, 1); TODO (unstable)
view.waitForTreeItem("Devfile registries", 10, 1);
view.closeView();
}

@Test
@BeforeAll
public static void gettingStartedShowsOnStartup() {
GettingStartedView view = robot.find(GettingStartedView.class);
view.closeView();
}

@Test
public void gettingStartedContainsAllItems() {
GettingStartedView view = robot.find(GettingStartedView.class);
view.openView();

view.waitForTreeItem("Login/Provision OpenShift cluster", 10, 1);
view.waitForTreeItem("Browse all the Devfile stacks from Devfile registries", 10, 1);
view.waitForTreeItem("Create a Component", 10, 1);
view.waitForTreeItem("Start a component in development mode", 10, 1);
view.waitForTreeItem("Debug the component", 10, 1);
view.waitForTreeItem("Deploy component on the cluster", 10, 1);

view.closeView();
}

@Test
public void gettingStartedBehaviour() {
GettingStartedView view = robot.find(GettingStartedView.class);
view.openView();

view.maximalizeToolWindow(robot);

view.getGettingStartedTree().findText("Login/Provision OpenShift cluster").click();
assertFalse(view.findEditorPaneFixture().findAllText().isEmpty(), "Login/Provision OpenShift cluster item has empty description!");

Locator next = byXpath("//div[@accessiblename='Next: Browse all the Devfile stacks from Devfile registries >' and @class='JLabel' and @text='Next: Browse all the Devfile stacks from Devfile registries >']");
ComponentFixture nextFixture = robot.find(GettingStartedView.class, next);
nextFixture.click();
assertFalse(view.findEditorPaneFixture().findAllText().isEmpty(), "Browse all the Devfile stacks from Devfile registries item has empty description!");

view.findBackToMainButton().click();

view.getGettingStartedTree().findText("Debug the component").click();
assertFalse(view.findEditorPaneFixture().findAllText().isEmpty(), "Debug the component item has empty description!");

Locator back = byXpath("//div[@accessiblename='< Back: Start a component in development mode' and @class='JLabel' and @text='< Back: Start a component in development mode']");
ComponentFixture backFixture = robot.find(GettingStartedView.class, back);
backFixture.click();
assertFalse(view.findEditorPaneFixture().findAllText().isEmpty(), "Start a component in development mode item has empty description!");

view.findBackToMainButton().click();

Locator feedback = byXpath("//div[@text='Leave feedback']");
ComponentFixture feedbackFixture = robot.find(GettingStartedView.class, feedback);
assertTrue(feedbackFixture.isShowing(), "Feedback button is not showing");

view.closeView();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void beforeAll(ExtensionContext context) {
System.out.println("Initialize IdeaRunner and start IDE");
// need to initialize store, so that close method will be called at the testing end
context.getRoot().getStore(Namespace.GLOBAL).put("InitializeTest", this);
IdeaRunner.getInstance().startIDE(IntelliJVersion.ULTIMATE_V_2021_1, 8580);
IdeaRunner.getInstance().startIDE(IntelliJVersion.ULTIMATE_V_2023_2, 8580);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,16 @@ public static void createEmptyProject(RemoteRobot robot, String projectName) {
flatWelcomeFrame.createNewProject();
final NewProjectDialogWizard newProjectDialogWizard = flatWelcomeFrame.find(NewProjectDialogWizard.class, Duration.ofSeconds(20));
selectNewProjectType(robot, "Empty Project");
newProjectDialogWizard.next();
JTextFieldFixture textField = robot.find(JTextFieldFixture.class, byXpath("//div[@visible_text='untitled']"));
textField.setText(projectName);
newProjectDialogWizard.finish();

final IdeStatusBar ideStatusBar = robot.find(IdeStatusBar.class, Duration.ofSeconds(5));
ideStatusBar.waitUntilProjectImportIsComplete();
//ideStatusBar.waitUntilProjectImportIsComplete(); TODO fix on IJ ULTIMATE 2023.2
}

public static void selectNewProjectType(RemoteRobot robot, String projectType) {
ComponentFixture newProjectTypeList = robot.findAll(ComponentFixture.class, byXpath("JBList", "//div[@class='JBList']")).get(0);
ComponentFixture newProjectTypeList = robot.findAll(ComponentFixture.class, byXpath("JBList", "//div[contains(@visible_text, 'FX')]")).get(0);
newProjectTypeList.findText(projectType).click();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.intellij.openshift.test.ui.views;

import com.intellij.remoterobot.RemoteRobot;
import com.intellij.remoterobot.data.RemoteComponent;
import com.intellij.remoterobot.fixtures.*;
import com.intellij.remoterobot.search.locators.Locator;
import com.intellij.remoterobot.utils.Keyboard;
import com.intellij.remoterobot.utils.WaitForConditionTimeoutException;
import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane;
import org.jetbrains.annotations.NotNull;

import java.awt.event.KeyEvent;
import java.time.Duration;

import static com.intellij.remoterobot.search.locators.Locators.byXpath;
import static com.intellij.remoterobot.utils.RepeatUtilsKt.waitFor;

/**
*
* @author Richard Kocian
*
*/
@DefaultXpath(by = "Getting Started type", xpath = "//div[@class='IdeFrameImpl']")
@FixtureName(name = "GettingStarted View")
public class GettingStartedView extends ContainerFixture {

private final Locator editorPaneLocator = byXpath("//div[@class='JEditorPane']");
private final Locator backToMainViewLocator = byXpath("//div[@accessiblename='<< Getting Started with OpenShift Toolkit' and @class='JLabel' and @text='<< Getting Started with OpenShift Toolkit']");
public GettingStartedView(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent remoteComponent) {
super(remoteRobot, remoteComponent);
}

public void openView() {
final ToolWindowPane toolWindowPane = find(ToolWindowPane.class);
waitFor(Duration.ofSeconds(10), Duration.ofSeconds(1), "The 'Getting Started' stripe button is not available.", () -> isStripeButtonAvailable(toolWindowPane, "OpenShift"));
toolWindowPane.stripeButton("Getting Started", false).click();
}

public void closeView() {
final ToolWindowPane toolWindowPane = find(ToolWindowPane.class);
toolWindowPane.button(byXpath("//div[@tooltiptext='Getting Started']"), Duration.ofSeconds(2)).click();
}

public void waitForTreeItem(String itemText, int duration, int interval) {
waitFor(Duration.ofSeconds(duration),
Duration.ofSeconds(interval),
"The " + itemText + " project is still not available.",
() -> getGettingStartedTree().hasText(itemText));
}

public JTreeFixture getGettingStartedTree(){
return find(JTreeFixture.class, byXpath("//div[@class='Tree']"), Duration.ofSeconds(30));
}

private boolean isStripeButtonAvailable(ToolWindowPane toolWindowPane, String label) {
try {
toolWindowPane.stripeButton(label, false);
} catch (WaitForConditionTimeoutException e) {
return false;
}
return true;
}

public ComponentFixture findEditorPaneFixture() {
return getRemoteRobot().findAll(GettingStartedView.class, editorPaneLocator).get(0);
}

public ComponentFixture findBackToMainButton() {
return getRemoteRobot().find(GettingStartedView.class, backToMainViewLocator);
}

public void maximalizeToolWindow(RemoteRobot robot) {
Keyboard keyboard = new Keyboard(robot);
// Other OS may have different keyboard shortcut for maximizing
keyboard.hotKey(KeyEvent.VK_CONTROL, KeyEvent.VK_SHIFT, KeyEvent.VK_QUOTE);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import com.intellij.remoterobot.fixtures.FixtureName;
import com.intellij.remoterobot.fixtures.JTreeFixture;
import com.intellij.remoterobot.utils.WaitForConditionTimeoutException;
import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowsPane;
import com.redhat.devtools.intellij.commonuitest.fixtures.mainidewindow.toolwindowspane.ToolWindowPane;
import org.jetbrains.annotations.NotNull;

import java.time.Duration;
Expand All @@ -38,9 +38,14 @@ public OpenshiftView(@NotNull RemoteRobot remoteRobot, @NotNull RemoteComponent
}

public void openView() {
final ToolWindowsPane toolWindowsPane = find(ToolWindowsPane.class);
waitFor(Duration.ofSeconds(10), Duration.ofSeconds(1), "The 'OpenShift' stripe button is not available.", () -> isStripeButtonAvailable(toolWindowsPane, "OpenShift"));
toolWindowsPane.stripeButton("OpenShift", false).click();
final ToolWindowPane toolWindowPane = find(ToolWindowPane.class);
waitFor(Duration.ofSeconds(10), Duration.ofSeconds(1), "The 'OpenShift' stripe button is not available.", () -> isStripeButtonAvailable(toolWindowPane, "OpenShift"));
toolWindowPane.stripeButton("OpenShift", false).click();
}

public void closeView() {
final ToolWindowPane toolWindowPane = find(ToolWindowPane.class);
toolWindowPane.button(byXpath("//div[@tooltiptext='OpenShift']"), Duration.ofSeconds(2)).click();
}

public void expandOpenshiftViewTree(String path) {
Expand All @@ -58,9 +63,9 @@ public JTreeFixture getOpenshiftConnectorTree(){
return find(JTreeFixture.class, byXpath("//div[@class='Tree']"), Duration.ofSeconds(30));
}

private boolean isStripeButtonAvailable(ToolWindowsPane toolWindowsPane, String label) {
private boolean isStripeButtonAvailable(ToolWindowPane toolWindowPane, String label) {
try {
toolWindowsPane.stripeButton(label, false);
toolWindowPane.stripeButton(label, false);
} catch (WaitForConditionTimeoutException e) {
return false;
}
Expand Down

0 comments on commit 989eef4

Please sign in to comment.