[gui-test] add NavigationBar and MainToolWindow fixtures; cleanup

- cleanup for ActionButtonFixture
- Add MainToolbar and NavigationBar fixtures to get help with location of ActionButtons on toolbar
- Add autogeneration methods for a NavigationBar and MainToolbar contexts to Generators
This commit is contained in:
Sergey Karashevich
2017-08-14 14:26:07 +03:00
parent b1d286f8f6
commit 037b743809
6 changed files with 208 additions and 53 deletions
@@ -24,6 +24,7 @@ import org.fest.swing.core.GenericTypeMatcher;
import org.fest.swing.core.Robot;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.exception.ComponentLookupException;
import org.fest.swing.format.Formatting;
import org.fest.swing.timing.Condition;
import org.fest.swing.timing.Pause;
import org.fest.swing.timing.Timeout;
@@ -32,9 +33,11 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.intellij.testGuiFramework.framework.GuiTestUtil.SHORT_TIMEOUT;
import static com.intellij.util.containers.ContainerUtil.getFirstItem;
import static org.fest.swing.edt.GuiActionRunner.execute;
public class ActionButtonFixture extends JComponentFixture<ActionButtonFixture, ActionButton> {
@@ -43,60 +46,52 @@ public class ActionButtonFixture extends JComponentFixture<ActionButtonFixture,
public static ActionButtonFixture findByActionId(@NotNull final String actionId,
@NotNull final Robot robot,
@NotNull final Container container, Timeout timeout) {
final Ref<ActionButton> actionButtonRef = new Ref<ActionButton>();
Pause.pause(new Condition("Find ActionButton with ID '" + actionId + "'") {
@Override
public boolean test() {
Collection<ActionButton> found = robot.finder().findAll(container, new GenericTypeMatcher<ActionButton>(ActionButton.class) {
@Override
protected boolean isMatching(@NotNull ActionButton button) {
if (button.isVisible()) {
AnAction action = button.getAction();
if (action != null) {
String id = ActionManager.getInstance().getId(action);
return actionId.equals(id);
}
}
return false;
}
});
if (found.size() == 1) {
actionButtonRef.set(getFirstItem(found));
return true;
}
return false;
}
}, timeout);
ActionButton button = actionButtonRef.get();
if (button == null) {
throw new ComponentLookupException("Failed to find ActionButton with ID '" + actionId + "'");
}
return new ActionButtonFixture(robot, button);
final String criteriaDescription = " by actionId: '" + actionId + "'";
GenericTypeMatcher<ActionButton> matcher = new GenericTypeMatcher<ActionButton>(ActionButton.class) {
@Override
protected boolean isMatching(ActionButton button) {
AnAction action = button.getAction();
String buttonActionId = ActionManager.getInstance().getId(action);
return button.isEnabled() && button.isShowing() && buttonActionId != null && buttonActionId.equals(actionId);
}
};
return getActionButtonFixtureWithMatcher(robot, container, matcher, criteriaDescription, timeout);
}
@NotNull
public static ActionButtonFixture findByActionClassName(@NotNull final String actionClassName,
@NotNull final Robot robot,
@NotNull final Container container, Timeout timeout) {
@NotNull final Robot robot,
@NotNull final Container container, Timeout timeout) {
final String criteriaDescription = " by action class name: '" + actionClassName + "'";
GenericTypeMatcher<ActionButton> matcher = new GenericTypeMatcher<ActionButton>(ActionButton.class) {
@Override
protected boolean isMatching(@NotNull ActionButton button) {
AnAction action = button.getAction();
return button.isShowing()
&& button.isEnabled()
&& action != null
&& action.getClass().getSimpleName().equals(actionClassName);
}
};
return getActionButtonFixtureWithMatcher(robot, container, matcher, criteriaDescription, timeout);
}
@NotNull
private static ActionButtonFixture getActionButtonFixtureWithMatcher(@NotNull Robot robot,
@NotNull Container container,
@NotNull GenericTypeMatcher<ActionButton> matcher,
@NotNull String criteriaDescription,
Timeout timeout) {
final Ref<ActionButton> actionButtonRef = new Ref<ActionButton>();
Pause.pause(new Condition("Find ActionButton by action class name: '" + actionClassName + "'") {
Pause.pause(new Condition("Find ActionButton " + criteriaDescription) {
@Override
public boolean test() {
Collection<ActionButton> found = robot.finder().findAll(container, new GenericTypeMatcher<ActionButton>(ActionButton.class) {
@Override
protected boolean isMatching(@NotNull ActionButton button) {
if (button.isVisible()) {
AnAction action = button.getAction();
if (action != null) {
return action.getClass().getSimpleName().equals(actionClassName);
}
}
return false;
}
});
if (found.size() == 1) {
actionButtonRef.set(getFirstItem(found));
Collection<ActionButton> found = robot.finder().findAll(container, matcher);
if (found.size() >= 1) {
ActionButton actionButton = getIfOnce(found, "Find ActionButton " + criteriaDescription);
if (actionButton == null) return false;
actionButtonRef.set(actionButton);
return true;
}
return false;
@@ -105,11 +100,24 @@ public class ActionButtonFixture extends JComponentFixture<ActionButtonFixture,
ActionButton button = actionButtonRef.get();
if (button == null) {
throw new ComponentLookupException("Failed to find ActionButton with action class name: '" + actionClassName + "'");
throw new ComponentLookupException("Failed to find Action button " + criteriaDescription);
}
return new ActionButtonFixture(robot, button);
}
@Nullable
private static ActionButton getIfOnce(@NotNull Collection<ActionButton> found, @Nullable String criteria) {
Stream<ActionButton> objectStream = found.stream();
if (found.size() > 1) {
throw new ComponentLookupException("Find more than one ActionButton component matched criteria " + criteria + ": "
+ objectStream
.map(component -> Formatting.format((Component)component))
.collect(Collectors.joining(", ")));
}
Optional<ActionButton> buttonOptional = objectStream.findFirst();
return buttonOptional.orElse(null);
}
@NotNull
public static ActionButtonFixture findByActionId(@NotNull final String actionId,
@NotNull final Robot robot,
@@ -145,7 +153,10 @@ public class ActionButtonFixture extends JComponentFixture<ActionButtonFixture,
}
@NotNull
public static ActionButtonFixture findByText(@NotNull final String text, @NotNull Robot robot, @NotNull Container container, @NotNull Timeout timeout) {
public static ActionButtonFixture findByText(@NotNull final String text,
@NotNull Robot robot,
@NotNull Container container,
@NotNull Timeout timeout) {
ActionButton button = GuiTestUtil.waitUntilFound(robot, container, new GenericTypeMatcher<ActionButton>(ActionButton.class) {
@Override
@@ -155,7 +166,6 @@ public class ActionButtonFixture extends JComponentFixture<ActionButtonFixture,
}
}, timeout);
return new ActionButtonFixture(robot, button);
}
private ActionButtonFixture(@NotNull Robot robot, @NotNull ActionButton target) {
@@ -82,6 +82,8 @@ public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameI
@NotNull private final File myProjectPath;
private EditorFixture myEditor;
private MainToolbarFixture myToolbar;
private NavigationBarFixture myNavBar;
@NotNull
public static IdeFrameFixture find(@NotNull final Robot robot, @Nullable final File projectPath, @Nullable final String projectName) {
@@ -210,6 +212,23 @@ public class IdeFrameFixture extends ComponentFixture<IdeFrameFixture, IdeFrameI
return myEditor;
}
@NotNull
public MainToolbarFixture getToolbar() {
if (myToolbar == null) {
myToolbar = MainToolbarFixture.Companion.createMainToolbarFixture(robot(), this);
}
return myToolbar;
}
@NotNull
public NavigationBarFixture getNavigationBar() {
if (myNavBar == null) {
myNavBar = NavigationBarFixture.Companion.createNavigationBarFixture(robot(), this);
}
return myNavBar;
}
//@NotNull
//public GradleInvocationResult invokeProjectMake() {
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2017 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.actionSystem.impl.ActionToolbarImpl
import org.fest.swing.core.Robot
import javax.swing.Box
class MainToolbarFixture(private val myRobot: Robot, val myToolbar: ActionToolbarImpl, private val myIdeFrame: IdeFrameFixture) :
ComponentFixture<MainToolbarFixture, ActionToolbarImpl>(MainToolbarFixture::class.java, myRobot, myToolbar) {
fun show() {
if (!isShowing()) myIdeFrame.invokeMainMenu("ViewToolBar")
}
fun hide() {
if (isShowing()) myIdeFrame.invokeMainMenu("ViewToolBar")
}
fun isShowing(): Boolean = myToolbar.isShowing
companion object {
fun createMainToolbarFixture(robot: Robot, ideFrame: IdeFrameFixture): MainToolbarFixture {
val actionToolbar = robot.finder()
.find(ideFrame.target()) { component -> component is ActionToolbarImpl && isMainToolbar(component) } as ActionToolbarImpl
return MainToolbarFixture(robot, actionToolbar, ideFrame)
}
fun isMainToolbar(actionToolbarImpl: ActionToolbarImpl): Boolean =
(actionToolbarImpl.parent is Box)
//actionToolbarImpl.parent.javaClass.name.contains(NavBarRootPaneExtension::class.java.simpleName)
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2017 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.ide.actions.ViewNavigationBarAction
import com.intellij.openapi.actionSystem.ActionManager
import org.fest.swing.core.Robot
import javax.swing.JPanel
class NavigationBarFixture(private val myRobot: Robot, val myPanel: JPanel, private val myIdeFrame: IdeFrameFixture) :
ComponentFixture<NavigationBarFixture, JPanel>(NavigationBarFixture::class.java, myRobot, myPanel) {
private val VIEW_NAV_BAR_ACTION = "ViewNavigationBar"
fun show() {
if (!isShowing()) myIdeFrame.invokeMainMenu(VIEW_NAV_BAR_ACTION)
}
fun hide() {
if (isShowing()) myIdeFrame.invokeMainMenu(VIEW_NAV_BAR_ACTION)
}
fun isShowing(): Boolean {
val action = ActionManager.getInstance().getAction(VIEW_NAV_BAR_ACTION) as ViewNavigationBarAction
return action.isSelected(null)
}
companion object {
fun createNavigationBarFixture(robot: Robot, ideFrame: IdeFrameFixture): NavigationBarFixture {
val navBarPanel = robot.finder()
.find(ideFrame.target()) { component -> component is JPanel && isNavBar(component) } as JPanel
return NavigationBarFixture(robot, navBarPanel, ideFrame)
}
fun isNavBar(navBarPanel: JPanel): Boolean = navBarPanel.name == "navbar"
}
}
@@ -22,6 +22,7 @@ import com.intellij.ide.projectView.impl.ProjectViewTree
import com.intellij.openapi.actionSystem.impl.ActionButton
import com.intellij.openapi.actionSystem.impl.ActionMenu
import com.intellij.openapi.actionSystem.impl.ActionMenuItem
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
import com.intellij.openapi.editor.impl.EditorComponentImpl
import com.intellij.openapi.ui.*
import com.intellij.openapi.util.Ref
@@ -33,9 +34,7 @@ import com.intellij.openapi.wm.impl.WindowManagerImpl
import com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame
import com.intellij.testGuiFramework.cellReader.ExtendedJListCellReader
import com.intellij.testGuiFramework.cellReader.ExtendedJTableCellReader
import com.intellij.testGuiFramework.fixtures.MessageDialogFixture
import com.intellij.testGuiFramework.fixtures.MessagesFixture
import com.intellij.testGuiFramework.fixtures.SettingsTreeFixture
import com.intellij.testGuiFramework.fixtures.*
import com.intellij.testGuiFramework.fixtures.extended.ExtendedTreeFixture
import com.intellij.testGuiFramework.framework.GuiTestUtil
import com.intellij.testGuiFramework.generators.Utils.clicks
@@ -505,6 +504,21 @@ class EditorGenerator : LocalContextCodeGenerator<EditorComponentImpl>() {
}
class MainToolbarGenerator : LocalContextCodeGenerator<ActionToolbarImpl>() {
override fun acceptor(): (Component) -> Boolean = {component -> component is ActionToolbarImpl
&& MainToolbarFixture.isMainToolbar(component)}
override fun generate(cmp: ActionToolbarImpl): String = "toolbar {"
}
class NavigationBarGenerator : LocalContextCodeGenerator<JPanel>() {
override fun acceptor(): (Component) -> Boolean = {component -> component is JPanel
&& NavigationBarFixture.isNavBar(component)}
override fun generate(cmp: JPanel): String = "navigationBar {"
}
//class JBPopupMenuGenerator: LocalContextCodeGenerator<JBPopupMenu>() {
//
@@ -420,6 +420,20 @@ open class GuiTestCase : GuiTestBase() {
func(this.editor)
}
/**
* Context function for IdeFrame: creates a MainToolbarFixture instance as receiver object. Code block after
* it call methods on the receiver object (MainToolbarFixture instance).
*
* @timeout in seconds to find get EditorFixture
*/
fun IdeFrameFixture.toolbar(timeout: Long = defaultTimeout, func: MainToolbarFixture.() -> Unit) {
func(this.toolbar)
}
fun IdeFrameFixture.navigationBar(timeout: Long = defaultTimeout, func: NavigationBarFixture.() -> Unit) {
func(this.navigationBar)
}
/**
* Extension function for IDE to iterate through the menu.
*