mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[gui-test] fix TypeAheadTest when Edit Configurations is disabled
fix TypeAheadTest when Edit Configurations... action is disabled.
This commit is contained in:
+21
-1
@@ -1,14 +1,20 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.testGuiFramework.tests.community
|
||||
|
||||
import com.intellij.openapi.util.component1
|
||||
import com.intellij.openapi.util.component2
|
||||
import com.intellij.testGuiFramework.fixtures.IdeFrameFixture
|
||||
import com.intellij.testGuiFramework.fixtures.JBListPopupFixture
|
||||
import com.intellij.testGuiFramework.fixtures.JDialogFixture
|
||||
import com.intellij.testGuiFramework.framework.RunWithIde
|
||||
import com.intellij.testGuiFramework.impl.GuiTestCase
|
||||
import com.intellij.testGuiFramework.impl.GuiTestUtilKt
|
||||
import com.intellij.testGuiFramework.launcher.ide.CommunityIde
|
||||
import com.intellij.ui.popup.PopupFactoryImpl
|
||||
import org.fest.swing.timing.Pause
|
||||
import org.fest.swing.timing.Timeout
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@RunWithIde(CommunityIde::class)
|
||||
class TypeAheadTest : GuiTestCase() {
|
||||
@@ -61,12 +67,26 @@ class TypeAheadTest : GuiTestCase() {
|
||||
}
|
||||
|
||||
private fun IdeFrameFixture.openRunDebugConfiguration() {
|
||||
val attempts = 5
|
||||
val timeoutInterval = 2L
|
||||
navigationBar {
|
||||
if (!isShowing()) show()
|
||||
actionButton("Run").waitUntilEnabledAndShowing()
|
||||
button("Main").click()
|
||||
for (i in 0..attempts) {
|
||||
button("Main").click()
|
||||
if (ensureEditConfigurationsIsEnabled()) break;
|
||||
else if (i == attempts - 1) throw Exception("Action 'Edit Configurations' is still disabled")
|
||||
Pause.pause(timeoutInterval, TimeUnit.SECONDS)
|
||||
}
|
||||
popupClick("Edit Configurations...")
|
||||
}
|
||||
}
|
||||
|
||||
private fun IdeFrameFixture.ensureEditConfigurationsIsEnabled(): Boolean {
|
||||
val (jListFixture, index) = JBListPopupFixture.getJListFixtureAndItemToClick("Edit Configurations...", false, null, this.robot(),
|
||||
Timeout.timeout(1000))
|
||||
val actionItem = jListFixture.target().model.getElementAt(index) as PopupFactoryImpl.ActionItem
|
||||
return actionItem.action.templatePresentation.isEnabled
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -818,7 +818,7 @@ public class EditorFixture {
|
||||
@NotNull
|
||||
public EditorFixture invokeIntentionAction(@NotNull String labelPrefix) {
|
||||
invokeAction(EditorFixture.EditorAction.SHOW_INTENTION_ACTIONS);
|
||||
JBListPopupFixture.clickPopupMenuItem(labelPrefix, true, null, robot, SHORT_TIMEOUT);
|
||||
JBListPopupFixture.Companion.clickPopupMenuItem(labelPrefix, true, null, robot, SHORT_TIMEOUT);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
-175
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.execution.configurations.ConfigurationTypeBase;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.testGuiFramework.cellReader.ExtendedJListCellReader;
|
||||
import com.intellij.testGuiFramework.framework.GuiTestUtil;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.popup.PopupFactoryImpl;
|
||||
import com.intellij.ui.popup.list.ListPopupModel;
|
||||
import org.fest.swing.core.GenericTypeMatcher;
|
||||
import org.fest.swing.core.Robot;
|
||||
import org.fest.swing.fixture.JListFixture;
|
||||
import org.fest.swing.timing.Timeout;
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import static com.intellij.testGuiFramework.framework.GuiTestUtil.waitUntilFound;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class JBListPopupFixture extends JComponentFixture<JBListPopupFixture, JBList> {
|
||||
|
||||
private JBListPopupFixture(JBList jbList, Robot robot) {
|
||||
super(JBListPopupFixture.class, robot, jbList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks an IntelliJ/Studio popup menu item with the label prefix
|
||||
*
|
||||
* @param label the target menu item label prefix
|
||||
* @param searchByPrefix if false equality is checked, if true prefix is checked
|
||||
* @param component a component in the same window that the popup menu is associated with
|
||||
* @param robot the robot to drive it with
|
||||
*/
|
||||
public static void clickPopupMenuItem(@NotNull String label,
|
||||
boolean searchByPrefix,
|
||||
@Nullable Component component,
|
||||
@NotNull Robot robot,
|
||||
@NotNull Timeout timeout) {
|
||||
if (searchByPrefix) {
|
||||
clickPopupMenuItemMatching(new PrefixMatcher(label), component, robot, timeout);
|
||||
}
|
||||
else {
|
||||
clickPopupMenuItemMatching(new EqualsMatcher(label), component, robot, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
private static void clickPopupMenuItemMatching(@NotNull Matcher<String> labelMatcher,
|
||||
@Nullable Component component,
|
||||
@NotNull Robot robot,
|
||||
@NotNull Timeout timeout) {
|
||||
// IntelliJ doesn't seem to use a normal JPopupMenu, so this won't work:
|
||||
// JPopupMenu menu = myRobot.findActivePopupMenu();
|
||||
// Instead, it uses a JList (technically a JBList), which is placed somewhere
|
||||
// under the root pane.
|
||||
Container root = null;
|
||||
if (component != null) {
|
||||
root = GuiTestUtil.getRootContainer(component);
|
||||
assertNotNull(root);
|
||||
}
|
||||
|
||||
Ref<Pair<JListFixture, Integer>> fixtureAndClickableItemRef = new Ref<>();
|
||||
// First find the JBList which holds the popup. There could be other JBLists in the hierarchy,
|
||||
// so limit it to one that is actually used as a popup, as identified by its model being a ListPopupModel:
|
||||
waitUntilFound(robot, root, new GenericTypeMatcher<JBList>(JBList.class) {
|
||||
@Override
|
||||
protected boolean isMatching(@NotNull JBList list) {
|
||||
ListModel model = list.getModel();
|
||||
if (model instanceof ListPopupModel) {
|
||||
Pair<JListFixture, Integer> fixtureAndClickableItem = getJListFixtureAndClickableItem(labelMatcher, robot, list);
|
||||
if (fixtureAndClickableItem != null) {
|
||||
fixtureAndClickableItemRef.set(fixtureAndClickableItem);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, timeout);
|
||||
|
||||
Pair<JListFixture, Integer> fixtureAndClickableItemPair = fixtureAndClickableItemRef.get();
|
||||
JListFixture popupListFixture = fixtureAndClickableItemPair.first;
|
||||
popupListFixture.replaceCellReader(new ExtendedJListCellReader());
|
||||
int clickableItem = fixtureAndClickableItemPair.second;
|
||||
popupListFixture.clickItem(clickableItem);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Pair<JListFixture, Integer> getJListFixtureAndClickableItem(@NotNull Matcher<String> labelMatcher,
|
||||
@NotNull Robot robot,
|
||||
JBList list) {
|
||||
JListFixture jListFixture = new JListFixture(robot, list);
|
||||
jListFixture.replaceCellReader(new ExtendedJListCellReader());
|
||||
int itemCount = jListFixture.target().getModel().getSize();
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
if (labelMatcher.matches(jListFixture.item(i).value())) {
|
||||
return new Pair<>(jListFixture, i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String readPopupItem(ListPopupModel model, int itemNumber) {
|
||||
assert itemNumber < model.getSize();
|
||||
Object elementAt = model.getElementAt(itemNumber);
|
||||
if (elementAt instanceof PopupFactoryImpl.ActionItem) {
|
||||
return ((PopupFactoryImpl.ActionItem)elementAt).getText();
|
||||
}
|
||||
else if (elementAt instanceof ConfigurationTypeBase) {
|
||||
return ((ConfigurationTypeBase)elementAt).getDisplayName();
|
||||
}
|
||||
else { // For example package private class IntentionActionWithTextCaching used in quickfix popups
|
||||
return elementAt.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class PrefixMatcher extends BaseMatcher<String> {
|
||||
|
||||
private final String prefix;
|
||||
|
||||
public PrefixMatcher(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
return item instanceof String && ((String)item).startsWith(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("with prefix '" + prefix + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private static class EqualsMatcher extends BaseMatcher<String> {
|
||||
|
||||
private final String wanted;
|
||||
|
||||
public EqualsMatcher(String wanted) {
|
||||
this.wanted = wanted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object item) {
|
||||
return item instanceof String && item.equals(wanted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("equals to '" + wanted + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.util.Pair
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.component1
|
||||
import com.intellij.openapi.util.component2
|
||||
import com.intellij.testGuiFramework.cellReader.ExtendedJListCellReader
|
||||
import com.intellij.testGuiFramework.framework.GuiTestUtil
|
||||
import com.intellij.testGuiFramework.framework.GuiTestUtil.waitUntilFound
|
||||
import com.intellij.ui.components.JBList
|
||||
import com.intellij.ui.popup.list.ListPopupModel
|
||||
import org.fest.swing.core.GenericTypeMatcher
|
||||
import org.fest.swing.core.Robot
|
||||
import org.fest.swing.exception.ComponentLookupException
|
||||
import org.fest.swing.fixture.JListFixture
|
||||
import org.fest.swing.timing.Timeout
|
||||
import org.hamcrest.BaseMatcher
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Matcher
|
||||
import org.junit.Assert.assertNotNull
|
||||
import java.awt.Component
|
||||
import java.awt.Container
|
||||
|
||||
class JBListPopupFixture private constructor(jbList: JBList<*>, robot: Robot) : JComponentFixture<JBListPopupFixture, JBList<*>>(
|
||||
JBListPopupFixture::class.java, robot, jbList) {
|
||||
|
||||
private class PrefixMatcher(private val prefix: String) : BaseMatcher<String>() {
|
||||
|
||||
override fun matches(item: Any): Boolean {
|
||||
return item is String && item.startsWith(prefix)
|
||||
}
|
||||
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("with prefix '$prefix'")
|
||||
}
|
||||
}
|
||||
|
||||
private class EqualsMatcher(private val wanted: String) : BaseMatcher<String>() {
|
||||
|
||||
override fun matches(item: Any): Boolean {
|
||||
return item is String && item == wanted
|
||||
}
|
||||
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("equals to '$wanted'")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Clicks an IntelliJ/Studio popup menu item with the label prefix
|
||||
*
|
||||
* @param label the target menu item label prefix
|
||||
* @param searchByPrefix if false equality is checked, if true prefix is checked
|
||||
* @param component a component in the same window that the popup menu is associated with
|
||||
* @param robot the robot to drive it with
|
||||
*/
|
||||
fun clickPopupMenuItem(label: String,
|
||||
searchByPrefix: Boolean,
|
||||
component: Component?,
|
||||
robot: Robot,
|
||||
timeout: Timeout) {
|
||||
val matcher = if (searchByPrefix) PrefixMatcher(label) else EqualsMatcher(label)
|
||||
clickPopupMenuItemMatching(matcher, component, robot, timeout)
|
||||
}
|
||||
|
||||
fun getJListFixtureAndItemToClick(label: String,
|
||||
searchByPrefix: Boolean,
|
||||
container: Component?,
|
||||
robot: Robot,
|
||||
timeout: Timeout): Pair<JListFixture, Int> {
|
||||
val matcher = if (searchByPrefix) PrefixMatcher(label) else EqualsMatcher(label)
|
||||
return getJListFixtureAndClickableItemByMatcher(container as Container?, matcher, robot, timeout)
|
||||
}
|
||||
|
||||
private fun clickPopupMenuItemMatching(labelMatcher: Matcher<String>,
|
||||
component: Component?,
|
||||
robot: Robot,
|
||||
timeout: Timeout) {
|
||||
// IntelliJ doesn't seem to use a normal JPopupMenu, so this won't work:
|
||||
// JPopupMenu menu = myRobot.findActivePopupMenu();
|
||||
// Instead, it uses a JList (technically a JBList), which is placed somewhere
|
||||
// under the root pane.
|
||||
var root: Container? = null
|
||||
if (component != null) {
|
||||
root = GuiTestUtil.getRootContainer(component)
|
||||
assertNotNull(root)
|
||||
}
|
||||
|
||||
val fixtureAndClickableItemPair = getJListFixtureAndClickableItemByMatcher(root, labelMatcher, robot, timeout)
|
||||
val (popupListFixture, clickableItem) = fixtureAndClickableItemPair
|
||||
popupListFixture.replaceCellReader(ExtendedJListCellReader())
|
||||
popupListFixture.clickItem(clickableItem)
|
||||
}
|
||||
|
||||
|
||||
private fun getJListFixtureAndClickableItemByMatcher(root: Container?,
|
||||
labelMatcher: Matcher<String>,
|
||||
robot: Robot,
|
||||
timeout: Timeout): Pair<JListFixture, Int> {
|
||||
val fixtureAndClickableItemRef = Ref<Pair<JListFixture, Int>>()
|
||||
waitUntilFound<JBList<*>>(robot, root, object : GenericTypeMatcher<JBList<*>>(JBList::class.java) {
|
||||
override fun isMatching(list: JBList<*>): Boolean {
|
||||
val model = list.model
|
||||
if (model is ListPopupModel) {
|
||||
val fixtureAndClickableItem = getJListFixtureAndClickableItemByList(labelMatcher, robot, list)
|
||||
if (fixtureAndClickableItem != null) {
|
||||
fixtureAndClickableItemRef.set(fixtureAndClickableItem)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}, timeout)
|
||||
return fixtureAndClickableItemRef.get() ?: throw ComponentLookupException("Unable to get JListFixture by matcher $labelMatcher")
|
||||
}
|
||||
|
||||
private fun getJListFixtureAndClickableItemByList(labelMatcher: Matcher<String>,
|
||||
robot: Robot,
|
||||
list: JBList<*>): Pair<JListFixture, Int>? {
|
||||
val jListFixture = JListFixture(robot, list)
|
||||
jListFixture.replaceCellReader(ExtendedJListCellReader())
|
||||
val itemCount = jListFixture.target().model.size
|
||||
return (0 until itemCount)
|
||||
.firstOrNull { labelMatcher.matches(jListFixture.item(it).value()) }
|
||||
?.let { Pair(jListFixture, it) }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user