[gui-test] ContainerFixture refactorings (GUI-152)

Replace receivers in ComponentFixtureUtils with ContainerFixture; make MessagesFixture implement ContainerFixture to use ComponentFixtureUtils functions; get rid of redundant MessageDialogFixture.
This commit is contained in:
Sergey Karashevich
2018-08-14 12:32:45 +03:00
parent d7ea6edb8a
commit 0825f9b29f
6 changed files with 205 additions and 278 deletions
@@ -51,6 +51,7 @@ import org.fest.swing.edt.GuiQuery;
import org.fest.swing.edt.GuiTask;
import org.fest.swing.exception.ComponentLookupException;
import org.fest.swing.exception.WaitTimedOutError;
import org.fest.swing.fixture.ContainerFixture;
import org.fest.swing.timing.Condition;
import org.fest.swing.timing.Timeout;
import org.jetbrains.annotations.Contract;
@@ -81,7 +82,7 @@ import static org.fest.util.Strings.quote;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameImpl> {
public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameImpl> implements ContainerFixture<IdeFrameImpl> {
@NotNull private final File myProjectPath;
private MainToolbarFixture myToolbar;
@@ -1,98 +0,0 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.testGuiFramework.fixtures;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.messages.MessageDialog;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testGuiFramework.framework.GuiTestUtil;
import com.intellij.testGuiFramework.framework.Timeouts;
import org.fest.swing.core.GenericTypeMatcher;
import org.fest.swing.core.Robot;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.timing.Timeout;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import static org.fest.swing.edt.GuiActionRunner.execute;
public class MessageDialogFixture extends IdeaDialogFixture<DialogWrapper> implements MessagesFixture.Delegate {
@NotNull
static MessageDialogFixture findByTitle(@NotNull Robot robot, @NotNull final String title) {
return findByTitle(robot, title, Timeouts.INSTANCE.getMinutes05());
}
@NotNull
static MessageDialogFixture findByTitle(@NotNull Robot robot, @NotNull final String title, @NotNull Timeout timeout) {
final Ref<DialogWrapper> wrapperRef = new Ref<DialogWrapper>();
JDialog dialog = GuiTestUtil.INSTANCE.waitUntilFound(robot, null, new GenericTypeMatcher<JDialog>(JDialog.class) {
@Override
protected boolean isMatching(@NotNull JDialog dialog) {
if (!title.equals(dialog.getTitle()) || !dialog.isShowing()) {
return false;
}
return isMessageDialog(dialog, wrapperRef);
}
}, timeout);
return new MessageDialogFixture(robot, dialog, wrapperRef.get());
}
static MessageDialogFixture findAny(@NotNull Robot robot) {
return findAny(robot, Timeouts.INSTANCE.getMinutes05());
}
static MessageDialogFixture findAny(@NotNull Robot robot, @NotNull Timeout timeout) {
final Ref<DialogWrapper> wrapperRef = new Ref<DialogWrapper>();
JDialog dialog = GuiTestUtil.INSTANCE.waitUntilFound(robot, null, new GenericTypeMatcher<JDialog>(JDialog.class) {
@Override
protected boolean isMatching(@NotNull JDialog dialog) {
return isMessageDialog(dialog, wrapperRef);
}
}, timeout);
return new MessageDialogFixture(robot, dialog, wrapperRef.get());
}
public static boolean isMessageDialog(@NotNull JDialog dialog, Ref<DialogWrapper> wrapperRef) {
DialogWrapper wrapper = getDialogWrapperFrom(dialog, DialogWrapper.class);
if (wrapper != null) {
if(wrapper instanceof MessageDialog){
wrapperRef.set(wrapper);
return true;
}
}
return false;
}
private MessageDialogFixture(@NotNull Robot robot, @NotNull JDialog target, @NotNull DialogWrapper dialogWrapper) {
super(robot, target, dialogWrapper);
}
@Override
@NotNull
public String getMessage() {
final JTextPane textPane = robot().finder().findByType(target(), JTextPane.class);
//noinspection ConstantConditions
return execute(new GuiQuery<String>() {
@Override
protected String executeInEDT() throws Throwable {
return StringUtil.notNullize(textPane.getText());
}
});
}
}
@@ -16,7 +16,9 @@
package com.intellij.testGuiFramework.fixtures;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.messages.MessageDialog;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testGuiFramework.framework.GuiTestUtil;
import com.intellij.testGuiFramework.framework.Timeouts;
@@ -24,40 +26,60 @@ import com.intellij.ui.messages.SheetController;
import com.intellij.util.JdomKt;
import org.fest.swing.core.GenericTypeMatcher;
import org.fest.swing.core.Robot;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.exception.WaitTimedOutError;
import org.fest.swing.fixture.ContainerFixture;
import org.fest.swing.fixture.JPanelFixture;
import org.fest.swing.timing.Timeout;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
import javax.swing.*;
import java.awt.*;
import static com.intellij.testGuiFramework.fixtures.IdeaDialogFixture.getDialogWrapperFrom;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.reflect.core.Reflection.field;
import static org.fest.swing.edt.GuiActionRunner.execute;
import static org.junit.Assert.assertNotNull;
public class MessagesFixture {
@NotNull private final ContainerFixture<? extends Container> myDelegate;
public class MessagesFixture<C extends Container> implements ContainerFixture<C> {
/**
* Could be a dialog (JDialog) or Mac message panel
*/
private final C myTarget;
private final Robot myRobot;
@Nonnull
@Override
public C target() {
return myTarget;
}
@Nonnull
@Override
public Robot robot() {
return myRobot;
}
@NotNull
public static MessagesFixture findByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title) {
if (Messages.canShowMacSheetPanel()) {
return new MessagesFixture(findMacSheetByTitle(robot, root, title));
return findMacMessageByTitle(robot, root, title);
}
MessageDialogFixture dialog = MessageDialogFixture.findByTitle(robot, title);
return new MessagesFixture(dialog);
JDialog dialog = findByTitle(robot, title);
return new MessagesFixture<>(robot, dialog);
}
@NotNull
public static MessagesFixture findByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title, @NotNull Timeout timeout) {
if (Messages.canShowMacSheetPanel()) {
return new MessagesFixture(findMacSheetByTitle(robot, root, title, timeout));
return findMacMessageByTitle(robot, root, title, timeout);
}
MessageDialogFixture dialog = MessageDialogFixture.findByTitle(robot, title, timeout);
return new MessagesFixture(dialog);
JDialog dialog = findByTitle(robot, title, timeout);
return new MessagesFixture<>(robot, dialog);
}
@NotNull
@@ -68,10 +90,10 @@ public class MessagesFixture {
@NotNull
public static MessagesFixture findAny(@NotNull Robot robot, @NotNull Container root, @NotNull Timeout timeout) {
if (Messages.canShowMacSheetPanel()) {
return new MessagesFixture(findMacSheetAny(robot, root, timeout));
return findMacMessageAny(robot, root, timeout);
}
MessageDialogFixture dialog = MessageDialogFixture.findAny(robot, timeout);
return new MessagesFixture(dialog);
JDialog dialog = findAny(robot, timeout);
return new MessagesFixture<>(robot, dialog);
}
@@ -85,14 +107,17 @@ public class MessagesFixture {
}
}
private MessagesFixture(@NotNull ContainerFixture<? extends Container> delegate) {
myDelegate = delegate;
/**
* @param messageContainer could be dialog (for Windows/Linux) or panel (for Mac)
*/
private MessagesFixture(Robot robot, C messageContainer) {
myTarget = messageContainer;
myRobot = robot;
}
@NotNull
public MessagesFixture clickOk() {
GuiTestUtil.INSTANCE.findAndClickOkButton(myDelegate);
return this;
return click("OK");
}
@@ -103,49 +128,84 @@ public class MessagesFixture {
@NotNull
public MessagesFixture click(@NotNull String text) {
GuiTestUtil.INSTANCE.findAndClickButton(myDelegate, text);
GuiTestUtil.INSTANCE.findAndClickButton(this, text);
return this;
}
@NotNull
public String getMessage() {
return ((Delegate)myDelegate).getMessage();
}
@NotNull
public MessagesFixture requireMessageContains(@NotNull String message) {
String actual = ((Delegate)myDelegate).getMessage();
String actual = getMessage();
assertThat(actual).contains(message);
return this;
}
public void clickCancel() {
GuiTestUtil.INSTANCE.findAndClickCancelButton(myDelegate);
click("Cancel");
}
public static boolean isMessageDialog(@NotNull JDialog dialog) {
DialogWrapper wrapper = getDialogWrapperFrom(dialog, DialogWrapper.class);
if (wrapper != null) {
if(wrapper instanceof MessageDialog){
return true;
}
}
return false;
}
@NotNull
static JPanelFixture findMacSheetByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title) {
return findMacSheetByTitle(robot, root, title, Timeouts.INSTANCE.getMinutes05());
static JDialog findByTitle(@NotNull Robot robot, @NotNull final String title) {
return findByTitle(robot, title, Timeouts.INSTANCE.getMinutes05());
}
@NotNull
static JPanelFixture findMacSheetByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title, @NotNull Timeout timeout) {
static JDialog findByTitle(@NotNull Robot robot, @NotNull final String title, @NotNull Timeout timeout) {
return GuiTestUtil.INSTANCE.waitUntilFound(robot, null, new GenericTypeMatcher<JDialog>(JDialog.class) {
@Override
protected boolean isMatching(@NotNull JDialog dialog) {
if (!title.equals(dialog.getTitle()) || !dialog.isShowing()) {
return false;
}
return isMessageDialog(dialog);
}
}, timeout);
}
@NotNull
static JDialog findAny(@NotNull Robot robot, @NotNull Timeout timeout) {
return GuiTestUtil.INSTANCE.waitUntilFound(robot, null, new GenericTypeMatcher<JDialog>(JDialog.class) {
@Override
protected boolean isMatching(@NotNull JDialog dialog) {
return isMessageDialog(dialog);
}
}, timeout);
}
@NotNull
static MacMessageFixture findMacMessageByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title) {
return findMacMessageByTitle(robot, root, title, Timeouts.INSTANCE.getMinutes05());
}
@NotNull
static MacMessageFixture findMacMessageByTitle(@NotNull Robot robot, @NotNull Container root, @NotNull String title, @NotNull Timeout timeout) {
JPanel sheetPanel = getSheetPanel(robot, root, timeout);
String sheetTitle = getTitle(sheetPanel, robot);
assertThat(sheetTitle).as("Sheet title").isEqualTo(title);
return new MacSheetPanelFixture(robot, sheetPanel);
return new MacMessageFixture(robot, sheetPanel);
}
private static JPanelFixture findMacSheetAny(@NotNull Robot robot, @NotNull Container root) {
return findMacSheetAny(robot, root, Timeouts.INSTANCE.getMinutes05());
private static MacMessageFixture findMacMessageAny(@NotNull Robot robot, @NotNull Container root) {
return findMacMessageAny(robot, root, Timeouts.INSTANCE.getMinutes05());
}
private static JPanelFixture findMacSheetAny(@NotNull Robot robot, @NotNull Container root, @NotNull Timeout timeout) {
private static MacMessageFixture findMacMessageAny(@NotNull Robot robot, @NotNull Container root, @NotNull Timeout timeout) {
JPanel sheetPanel = getSheetPanel(robot, root, timeout);
return new MacSheetPanelFixture(robot, sheetPanel);
return new MacMessageFixture(robot, sheetPanel);
}
@NotNull
@@ -172,8 +232,7 @@ public class MessagesFixture {
@Nullable
public String getTitle() {
if (myDelegate instanceof MacSheetPanelFixture) return ((MacSheetPanelFixture)myDelegate).getTitle();
return ((MessageDialogFixture)myDelegate).target().getTitle();
return ((JDialog)myTarget).getTitle();
}
@Nullable
@@ -190,21 +249,24 @@ public class MessagesFixture {
return getHtmlBody(titleTextPane.getText());
}
@Nullable
public <T extends JComponent> T find(GenericTypeMatcher<T> matcher) {
return myDelegate.robot().finder().find(myDelegate.target(), matcher);
@NotNull
public String getMessage() {
final JTextPane textPane = robot().finder().findByType(target(), JTextPane.class);
//noinspection ConstantConditions
return execute(new GuiQuery<String>() {
@Override
protected String executeInEDT() throws Throwable {
return StringUtil.notNullize(textPane.getText());
}
});
}
interface Delegate {
@NotNull String getMessage();
}
private static class MacMessageFixture extends MessagesFixture<JPanel> {
private static class MacSheetPanelFixture extends JPanelFixture implements Delegate {
public MacSheetPanelFixture(@NotNull Robot robot, @NotNull JPanel target) {
public MacMessageFixture(@NotNull Robot robot, @NotNull JPanel target) {
super(robot, target);
}
@Nullable
public String getTitle(){
final JEditorPane messageTextPane = getMessageTextPane(target());
@@ -3,16 +3,19 @@ package com.intellij.testGuiFramework.fixtures
import com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame
import com.intellij.testGuiFramework.framework.Timeouts
import com.intellij.testGuiFramework.impl.*
import com.intellij.testGuiFramework.impl.GuiRobotHolder
import com.intellij.testGuiFramework.impl.actionLink
import com.intellij.testGuiFramework.impl.popupMenu
import org.fest.swing.core.Robot
import org.fest.swing.exception.ComponentLookupException
import org.fest.swing.fixture.ContainerFixture
import org.fest.swing.timing.Condition
import org.fest.swing.timing.Pause
import java.awt.Frame
class WelcomeFrameFixture private constructor(robot: Robot,
target: FlatWelcomeFrame) : ComponentFixture<WelcomeFrameFixture, FlatWelcomeFrame>(
WelcomeFrameFixture::class.java, robot, target) {
WelcomeFrameFixture::class.java, robot, target), ContainerFixture<FlatWelcomeFrame> {
fun createNewProject(): WelcomeFrameFixture {
findActionLinkByActionId("WelcomeScreen.CreateNewProject").click()
@@ -33,7 +36,7 @@ class WelcomeFrameFixture private constructor(robot: Robot,
return ActionLinkFixture.findByActionId(actionId, robot(), target())
}
fun findMessageDialog(title: String): MessagesFixture {
fun findMessageDialog(title: String): MessagesFixture<*> {
return MessagesFixture.findByTitle(robot(), target(), title)
}
@@ -36,7 +36,10 @@ import com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame
import com.intellij.testGuiFramework.cellReader.ExtendedJListCellReader
import com.intellij.testGuiFramework.cellReader.ExtendedJTableCellReader
import com.intellij.testGuiFramework.driver.CheckboxTreeDriver
import com.intellij.testGuiFramework.fixtures.*
import com.intellij.testGuiFramework.fixtures.MainToolbarFixture
import com.intellij.testGuiFramework.fixtures.MessagesFixture
import com.intellij.testGuiFramework.fixtures.NavigationBarFixture
import com.intellij.testGuiFramework.fixtures.SettingsTreeFixture
import com.intellij.testGuiFramework.fixtures.extended.getPathStrings
import com.intellij.testGuiFramework.framework.GuiTestUtil
import com.intellij.testGuiFramework.generators.Utils.clicks
@@ -564,7 +567,7 @@ class MessageGenerator : LocalContextCodeGenerator<JDialog>() {
override fun priority(): Int = 2
override fun acceptor(): (Component) -> Boolean = { cmp ->
cmp is JDialog && MessageDialogFixture.isMessageDialog(cmp, Ref<DialogWrapper>())
cmp is JDialog && MessagesFixture.isMessageDialog(cmp)
}
override fun generate(cmp: JDialog): String {
@@ -28,10 +28,7 @@ import org.fest.swing.core.Robot
import org.fest.swing.exception.ActionFailedException
import org.fest.swing.exception.ComponentLookupException
import org.fest.swing.exception.WaitTimedOutError
import org.fest.swing.fixture.JLabelFixture
import org.fest.swing.fixture.JListFixture
import org.fest.swing.fixture.JSpinnerFixture
import org.fest.swing.fixture.JTextComponentFixture
import org.fest.swing.fixture.*
import org.fest.swing.timing.Timeout
import org.junit.Assert
import java.awt.Component
@@ -45,7 +42,7 @@ import javax.swing.*
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.jList(containingItem: String? = null, timeout: Timeout = defaultTimeout): JListFixture {
fun <C : Container> ContainerFixture<C>.jList(containingItem: String? = null, timeout: Timeout = defaultTimeout): JListFixture {
val extCellReader = ExtendedJListCellReader()
val myJList: JList<*> = findComponentWithTimeout(timeout) { jList: JList<*> ->
if (containingItem == null) true //if were searching for any jList()
@@ -65,7 +62,7 @@ fun <S, C : Component> ComponentFixture<S, C>.jList(containingItem: String? = nu
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.button(name: String, timeout: Timeout = defaultTimeout): ExtendedButtonFixture {
fun <C : Container> ContainerFixture<C>.button(name: String, timeout: Timeout = defaultTimeout): ExtendedButtonFixture {
val jButton: JButton = findComponentWithTimeout(timeout) { it.isShowing && it.isVisible && it.text == name }
return ExtendedButtonFixture(robot(), jButton)
}
@@ -77,7 +74,7 @@ fun <S, C : Component> ComponentFixture<S, C>.button(name: String, timeout: Time
* @throws ComponentLookupException if no component has not been found or timeout exceeded
* @return list of JButton components sorted by locationOnScreen (left to right, top to down)
*/
fun <S, C : Component> ComponentFixture<S, C>.buttons(name: String, timeout: Timeout = defaultTimeout): List<ExtendedButtonFixture> {
fun <C : Container> ContainerFixture<C>.buttons(name: String, timeout: Timeout = defaultTimeout): List<ExtendedButtonFixture> {
val jButtons = waitUntilFoundList(target() as Container, JButton::class.java, timeout) {
it.isShowing && it.isVisible && it.text == name
@@ -88,8 +85,8 @@ fun <S, C : Component> ComponentFixture<S, C>.buttons(name: String, timeout: Tim
.sortedBy { it.target().locationOnScreen.y }
}
fun <S, C : Component> ComponentFixture<S, C>.componentWithBrowseButton(boundedLabelText: String,
timeout: Timeout = defaultTimeout): ComponentWithBrowseButtonFixture {
fun <C : Container> ContainerFixture<C>.componentWithBrowseButton(boundedLabelText: String,
timeout: Timeout = defaultTimeout): ComponentWithBrowseButtonFixture {
val boundedLabel: JLabel = findComponentWithTimeout(timeout) { it.text == boundedLabelText && it.isShowing }
val component = boundedLabel.labelFor
if (component is ComponentWithBrowseButton<*>) {
@@ -98,12 +95,12 @@ fun <S, C : Component> ComponentFixture<S, C>.componentWithBrowseButton(boundedL
else throw unableToFindComponent("ComponentWithBrowseButton", timeout)
}
fun <S, C : Component> ComponentFixture<S, C>.treeTable(timeout: Timeout = defaultTimeout): TreeTableFixture {
fun <C : Container> ContainerFixture<C>.treeTable(timeout: Timeout = defaultTimeout): TreeTableFixture {
val table: TreeTable = findComponentWithTimeout(timeout)
return TreeTableFixture(robot(), table)
}
fun <S, C : Component> ComponentFixture<S, C>.spinner(boundedLabelText: String, timeout: Timeout = defaultTimeout): JSpinnerFixture {
fun <C : Container> ContainerFixture<C>.spinner(boundedLabelText: String, timeout: Timeout = defaultTimeout): JSpinnerFixture {
val boundedLabel: JLabel = findComponentWithTimeout(timeout) { it.text == boundedLabelText }
val component = boundedLabel.labelFor
if (component is JSpinner)
@@ -111,7 +108,7 @@ fun <S, C : Component> ComponentFixture<S, C>.spinner(boundedLabelText: String,
else throw unableToFindComponent("JSpinner", timeout)
}
fun <S, C : Component> ComponentFixture<S, C>?.unableToFindComponent(componentName: String, timeout: Timeout): Throwable {
fun <C : Container> ContainerFixture<C>?.unableToFindComponent(componentName: String, timeout: Timeout): Throwable {
if (this == null) throw ComponentLookupException("Unable to find $componentName component without parent container (null) in $timeout")
else throw ComponentLookupException(
"Unable to find $componentName component without parent container ${this.target()::javaClass.name} in $timeout")
@@ -122,8 +119,7 @@ fun <S, C : Component> ComponentFixture<S, C>?.unableToFindComponent(componentNa
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.combobox(labelText: String, timeout: Timeout = defaultTimeout): ComboBoxFixture {
checkIsContainer()
fun <C : Container> ContainerFixture<C>.combobox(labelText: String, timeout: Timeout = defaultTimeout): ComboBoxFixture {
//todo: cut all waits in fixtures
val comboBox = GuiTestUtilKt.findBoundedComponentByText(robot(), target() as Container, labelText, JComboBox::class.java, timeout)
val comboboxFixture = ComboBoxFixture(robot(), comboBox)
@@ -137,7 +133,7 @@ fun <S, C : Component> ComponentFixture<S, C>.combobox(labelText: String, timeou
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.checkbox(labelText: String, timeout: Timeout = defaultTimeout): CheckBoxFixture {
fun <C : Container> ContainerFixture<C>.checkbox(labelText: String, timeout: Timeout = defaultTimeout): CheckBoxFixture {
val jCheckBox: JCheckBox = findComponentWithTimeout(timeout) { it.isShowing && it.isVisible && it.text == labelText }
return CheckBoxFixture(robot(), jCheckBox)
}
@@ -147,7 +143,7 @@ fun <S, C : Component> ComponentFixture<S, C>.checkbox(labelText: String, timeou
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.actionLink(name: String, timeout: Timeout = defaultTimeout): ActionLinkFixture {
fun <C : Container> ContainerFixture<C>.actionLink(name: String, timeout: Timeout = defaultTimeout): ActionLinkFixture {
val actionLink: ActionLink = findComponentWithTimeout(timeout) { it.isVisible && it.isShowing && it.text == name }
return ActionLinkFixture(robot(), actionLink)
@@ -159,7 +155,7 @@ fun <S, C : Component> ComponentFixture<S, C>.actionLink(name: String, timeout:
* @actionName text or action id of an action button (@see com.intellij.openapi.actionSystem.ActionManager#getId())
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.actionButton(actionName: String, timeout: Timeout = defaultTimeout): ActionButtonFixture {
fun <C : Container> ContainerFixture<C>.actionButton(actionName: String, timeout: Timeout = defaultTimeout): ActionButtonFixture {
val actionButton: ActionButton = try {
findComponentWithTimeout(timeout, ActionButtonFixture.textMatcher(actionName))
}
@@ -176,12 +172,9 @@ fun <S, C : Component> ComponentFixture<S, C>.actionButton(actionName: String, t
* @icon of InplaceButton component.
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.inplaceButton(icon: Icon, timeout: Timeout = defaultTimeout): InplaceButtonFixture {
fun <C : Container> ContainerFixture<C>.inplaceButton(icon: Icon, timeout: Timeout = defaultTimeout): InplaceButtonFixture {
val target = target()
return if (target is Container) {
InplaceButtonFixture.findInplaceButtonFixture(target, robot(), icon, timeout)
}
else throw unableToFindComponent("""InplaceButton by icon "$icon"""", timeout)
return InplaceButtonFixture.findInplaceButtonFixture(target, robot(), icon, timeout)
}
/**
@@ -190,8 +183,8 @@ fun <S, C : Component> ComponentFixture<S, C>.inplaceButton(icon: Icon, timeout:
* @actionClassName qualified name of class for action
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.actionButtonByClass(actionClassName: String,
timeout: Timeout = defaultTimeout): ActionButtonFixture {
fun <C : Container> ContainerFixture<C>.actionButtonByClass(actionClassName: String,
timeout: Timeout = defaultTimeout): ActionButtonFixture {
val actionButton: ActionButton = findComponentWithTimeout(timeout, ActionButtonFixture.actionClassNameMatcher(actionClassName))
return ActionButtonFixture(robot(), actionButton)
@@ -203,9 +196,8 @@ fun <S, C : Component> ComponentFixture<S, C>.actionButtonByClass(actionClassNam
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.radioButton(textLabel: String, timeout: Timeout = defaultTimeout): RadioButtonFixture =
if (target() is Container) GuiTestUtil.findRadioButton(target() as Container, textLabel, timeout)
else throw unableToFindComponent("""RadioButton by label "$textLabel"""", timeout)
fun <C : Container> ContainerFixture<C>.radioButton(textLabel: String, timeout: Timeout = defaultTimeout): RadioButtonFixture =
GuiTestUtil.findRadioButton(target() as Container, textLabel, timeout)
/**
* Finds a JTextComponent component (JTextField) in hierarchy of context component by text of label and returns JTextComponentFixture.
@@ -213,12 +205,8 @@ fun <S, C : Component> ComponentFixture<S, C>.radioButton(textLabel: String, tim
* @textLabel could be a null if label is absent
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.textfield(textLabel: String?, timeout: Timeout = defaultTimeout): JTextComponentFixture {
val target = target()
if (target is Container) {
return GuiTestUtil.textfield(textLabel, target, timeout)
}
else throw unableToFindComponent("""JTextComponent (JTextField) by label "$textLabel"""", timeout)
fun <C : Container> ContainerFixture<C>.textfield(textLabel: String?, timeout: Timeout = defaultTimeout): JTextComponentFixture {
return GuiTestUtil.textfield(textLabel, target(), timeout)
}
/**
@@ -227,18 +215,15 @@ fun <S, C : Component> ComponentFixture<S, C>.textfield(textLabel: String?, time
* @pathStrings comma separated array of Strings, representing path items: jTree("myProject", "src", "Main.java")
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.jTree(
vararg pathStrings: String,
timeout: Timeout = defaultTimeout,
predicate: FinderPredicate = Predicate.equality
): ExtendedJTreePathFixture =
if (target() is Container) ExtendedJTreePathFixture(GuiTestUtil.jTreeComponent(
fun <C : Container> ContainerFixture<C>.jTree(vararg pathStrings: String,
timeout: Timeout = defaultTimeout,
predicate: FinderPredicate = Predicate.equality): ExtendedJTreePathFixture =
ExtendedJTreePathFixture(GuiTestUtil.jTreeComponent(
container = target() as Container,
timeout = timeout,
pathStrings = *pathStrings,
predicate = predicate
), pathStrings.toList(), predicate)
else throw unableToFindComponent("""JTree "${if (pathStrings.isNotEmpty()) "by path $pathStrings" else ""}"""", timeout)
/**
* Finds a CheckboxTree component in hierarchy of context component by a path and returns CheckboxTreeFixture.
@@ -246,44 +231,39 @@ fun <S, C : Component> ComponentFixture<S, C>.jTree(
* @pathStrings comma separated array of Strings, representing path items: checkboxTree("JBoss", "JBoss Drools")
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.checkboxTree(
fun <C : Container> ContainerFixture<C>.checkboxTree(
vararg pathStrings: String,
timeout: Timeout = defaultTimeout,
predicate: FinderPredicate = Predicate.equality
): CheckboxTreeFixture =
if (target() is Container) {
val tree = GuiTestUtil.jTreeComponent(
container = target() as Container,
timeout = timeout,
predicate = predicate,
pathStrings = *pathStrings
) as? CheckboxTree ?: throw ComponentLookupException("Found JTree but not a CheckboxTree")
CheckboxTreeFixture(tree, pathStrings.toList(), predicate, robot())
}
else throw unableToFindComponent("""CheckboxTree "${if (pathStrings.isNotEmpty()) "by path ${pathStrings.joinToString()}" else ""}"""",
timeout)
): CheckboxTreeFixture {
val tree = GuiTestUtil.jTreeComponent(
container = target() as Container,
timeout = timeout,
predicate = predicate,
pathStrings = *pathStrings
) as? CheckboxTree ?: throw ComponentLookupException("Found JTree but not a CheckboxTree")
return CheckboxTreeFixture(tree, pathStrings.toList(), predicate, robot())
}
/**
* Finds a JTable component in hierarchy of context component by a cellText and returns JTableFixture.
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.table(cellText: String, timeout: Timeout = defaultTimeout): ExtendedTableFixture =
if (target() is Container) {
var tableFixture: ExtendedTableFixture? = null
val jTable: JTable = findComponentWithTimeout(timeout) {
tableFixture = ExtendedTableFixture(robot(), it)
try {
tableFixture?.cell(cellText)
tableFixture != null
}
catch (e: ActionFailedException) {
false
}
fun <C : Container> ContainerFixture<C>.table(cellText: String, timeout: Timeout = defaultTimeout): ExtendedTableFixture {
var tableFixture: ExtendedTableFixture? = null
val jTable: JTable = findComponentWithTimeout(timeout) {
tableFixture = ExtendedTableFixture(robot(), it)
try {
tableFixture?.cell(cellText)
tableFixture != null
}
catch (e: ActionFailedException) {
false
}
tableFixture ?: throw unableToFindComponent("""JTable with cell text "$cellText"""", timeout)
}
else throw unableToFindComponent("""JTable with cell text "$cellText"""", timeout)
return tableFixture ?: throw unableToFindComponent("""JTable with cell text "$cellText"""", timeout)
}
fun popupMenu(
item: String,
@@ -305,17 +285,12 @@ fun popupMenu(
}
fun <S, C : Component> ComponentFixture<S, C>.popupMenu(
item: String,
timeout: Timeout = defaultTimeout,
predicate: FinderPredicate = Predicate.equality
): JBListPopupFixture {
if (target() is Container) {
val root: Container? = GuiTestUtil.getRootContainer(target())
Assert.assertNotNull(root)
return popupMenu(item, robot(), root, timeout, predicate)
}
else throw unableToFindComponent("JBList with item '${item}' not found", timeout)
fun <C : Container> ContainerFixture<C>.popupMenu(item: String,
timeout: Timeout = defaultTimeout,
predicate: FinderPredicate = Predicate.equality): JBListPopupFixture {
val root: Container? = GuiTestUtil.getRootContainer(target())
Assert.assertNotNull(root)
return popupMenu(item, robot(), root, timeout, predicate)
}
@@ -324,57 +299,46 @@ fun <S, C : Component> ComponentFixture<S, C>.popupMenu(
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.linkLabel(linkName: String, timeout: Timeout = defaultTimeout) =
if (target() is Container) {
val myLinkLabel = GuiTestUtil.waitUntilFound(
robot(), target() as Container,
GuiTestUtilKt.typeMatcher(LinkLabel::class.java) { it.isShowing && (it.text == linkName) },
timeout)
ComponentFixture(ComponentFixture::class.java, robot(), myLinkLabel)
}
else throw unableToFindComponent("LinkLabel", timeout)
fun <C : Container> ContainerFixture<C>.linkLabel(linkName: String,
timeout: Timeout = defaultTimeout): ComponentFixture<ComponentFixture<*, *>, LinkLabel<*>> {
val myLinkLabel = GuiTestUtil.waitUntilFound(
robot(), target() as Container,
GuiTestUtilKt.typeMatcher(LinkLabel::class.java) { it.isShowing && (it.text == linkName) },
timeout)
return ComponentFixture(ComponentFixture::class.java, robot(), myLinkLabel)
}
fun <S, C : Component> ComponentFixture<S, C>.hyperlinkLabel(labelText: String,
timeout: Timeout = defaultTimeout): HyperlinkLabelFixture =
if (target() is Container) {
val hyperlinkLabel = GuiTestUtil.waitUntilFound(robot(), target() as Container,
GuiTestUtilKt.typeMatcher(HyperlinkLabel::class.java) {
it.isShowing && (it.text == labelText)
}, timeout)
HyperlinkLabelFixture(robot(), hyperlinkLabel)
}
else throw unableToFindComponent("""HyperlinkLabel by label text: "$labelText"""", timeout)
fun <C : Container> ContainerFixture<C>.hyperlinkLabel(labelText: String,
timeout: Timeout = defaultTimeout): HyperlinkLabelFixture {
val hyperlinkLabel = GuiTestUtil.waitUntilFound(robot(), target() as Container,
GuiTestUtilKt.typeMatcher(HyperlinkLabel::class.java) {
it.isShowing && (it.text == labelText)
}, timeout)
return HyperlinkLabelFixture(robot(), hyperlinkLabel)
}
/**
* Finds a table of plugins component in hierarchy of context component by a link name and returns fixture for it.
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.pluginTable(timeout: Timeout = defaultTimeout) =
if (target() is Container) PluginTableFixture.find(robot(), target() as Container, timeout)
else throw unableToFindComponent("PluginTable", timeout)
fun <C : Container> ContainerFixture<C>.pluginTable(timeout: Timeout = defaultTimeout) =
PluginTableFixture.find(robot(), target() as Container, timeout)
/**
* Finds a Message component in hierarchy of context component by a title MessageFixture.
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.message(title: String, timeout: Timeout = defaultTimeout) =
if (target() is Container) MessagesFixture.findByTitle(robot(), target() as Container, title, timeout)
else throw unableToFindComponent("Message", timeout)
fun <C : Container> ContainerFixture<C>.message(title: String, timeout: Timeout = defaultTimeout): MessagesFixture<*> =
MessagesFixture.findByTitle(robot(), target() as Container, title, timeout)
/**
* Finds a Message component in hierarchy of context component by a title MessageFixture.
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.message(title: String,
timeout: Timeout = defaultTimeout,
func: MessagesFixture.() -> Unit) {
if (target() is Container) func(MessagesFixture.findByTitle(robot(), target() as Container, title, timeout))
else throw unableToFindComponent("Message", timeout)
fun <C : Container> ContainerFixture<C>.message(title: String,
timeout: Timeout = defaultTimeout,
func: MessagesFixture<*>.() -> Unit) {
func(MessagesFixture.findByTitle(robot(), target() as Container, title, timeout))
}
/**
@@ -382,26 +346,24 @@ fun <S, C : Component> ComponentFixture<S, C>.message(title: String,
*
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.label(labelName: String, timeout: Timeout = defaultTimeout): JLabelFixture =
if (target() is Container) {
val jbLabel = GuiTestUtil.waitUntilFound(
robot(), target() as Container,
GuiTestUtilKt.typeMatcher(JBLabel::class.java) { it.isShowing && (it.text == labelName || labelName in it.text) },
timeout)
JLabelFixture(robot(), jbLabel)
}
else throw unableToFindComponent("JBLabel", timeout)
fun <C : Container> ContainerFixture<C>.label(labelName: String, timeout: Timeout = defaultTimeout): JLabelFixture {
val jbLabel = GuiTestUtil.waitUntilFound(
robot(), target() as Container,
GuiTestUtilKt.typeMatcher(JBLabel::class.java) { it.isShowing && (it.text == labelName || labelName in it.text) },
timeout)
return JLabelFixture(robot(), jbLabel)
}
/**
* Find an AsyncProcessIcon component in a current context (gets by receiver) and returns a fixture for it.
* Indexing processIcon is excluded from this search
*/
fun <S, C : Component> ComponentFixture<S, C>.asyncProcessIcon(timeout: Timeout = defaultTimeout): AsyncProcessIconFixture {
fun <C : Container> ContainerFixture<C>.asyncProcessIcon(timeout: Timeout = defaultTimeout): AsyncProcessIconFixture {
val indexingProcessIconTooltipText = ActionsBundle.message("action.ShowProcessWindow.double.click")
val asyncProcessIcon = GuiTestUtil.waitUntilFound(
robot(),
target() as Container,
target(),
GuiTestUtilKt.typeMatcher(AsyncProcessIcon::class.java) {
it.isShowing &&
it.isVisible &&
@@ -426,20 +388,14 @@ fun <ComponentType : Component> waitUntilFoundList(container: Container?,
return GuiTestUtil.waitUntilFoundList(container, timeout, GuiTestUtilKt.typeMatcher(componentClass) { matcher(it) })
}
fun <S, C : Component> ComponentFixture<S, C>?.checkIsContainer() {
if (this != null && target() !is Container) throw ComponentLookupException(
"Unable to find component because ${target().javaClass.simpleName} is not a Container")
}
/**
* function to find component of returning type inside a container (gets from receiver).
*
* @throws ComponentLookupException if desired component haven't been found under the container (gets from receiver) in specified timeout
*/
inline fun <S, reified ComponentType : Component, ContainerComponentType : Component> ComponentFixture<S, ContainerComponentType>?.findComponentWithTimeout(
inline fun <reified ComponentType : Component, ContainerComponentType : Container> ContainerFixture<ContainerComponentType>?.findComponentWithTimeout(
timeout: Timeout = defaultTimeout,
crossinline finderFunction: (ComponentType) -> Boolean = { _ -> true }): ComponentType {
checkIsContainer()
try {
return GuiTestUtil.waitUntilFound(GuiRobotHolder.robot, this?.target() as Container?,
GuiTestUtilKt.typeMatcher(ComponentType::class.java) { finderFunction(it) },
@@ -447,7 +403,7 @@ inline fun <S, reified ComponentType : Component, ContainerComponentType : Compo
}
catch (e: WaitTimedOutError) {
throw ComponentLookupException(
"Unable to find ${ComponentType::class.java.name} ${if (this?.target() != null) "in container ${this.target() as Container}" else ""} in $timeout seconds")
"Unable to find ${ComponentType::class.java.name} ${if (this?.target() != null) "in container ${this.target()}" else ""} in $timeout seconds")
}
}