[gui-test] JBListPopupFixture made a standard fixture, changed usages: added popupMenu to be used instead of popupClick

This commit is contained in:
Viktoria.Shirunova
2018-08-03 14:15:53 +03:00
parent 320eab0628
commit 63858dfb45
5 changed files with 98 additions and 149 deletions
@@ -22,6 +22,8 @@ import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.testGuiFramework.framework.GuiTestUtil;
import com.intellij.testGuiFramework.impl.ComponentFixtureUtilsKt;
import com.intellij.testGuiFramework.util.Predicate;
import org.fest.swing.core.ComponentDragAndDrop;
import org.fest.swing.core.GenericTypeMatcher;
import org.fest.swing.core.MouseButton;
@@ -126,7 +128,7 @@ public class EditorFixture {
* file open.
*
* @param trim if true, trim whitespace around the line
* @param caret typically "^" which will insert "^" to indicate the
* @param caret typically "^" which will insert "^" to indicate the
* caret position. If null, the caret position is not shown.
* @param selectBegin the text string to insert at the beginning of the selection boundary
* @param selectEnd the text string to insert at the end of the selection boundary
@@ -228,7 +230,7 @@ public class EditorFixture {
* Returns the contents of the current file, or null if there is no
* file open.
*
* @param caret typically "^" which will insert "^" to indicate the
* @param caret typically "^" which will insert "^" to indicate the
* caret position. If null, the caret position is not shown.
* @param selectBegin the text string to insert at the beginning of the selection boundary
* @param selectEnd the text string to insert at the end of the selection boundary
@@ -773,7 +775,9 @@ public class EditorFixture {
@NotNull
public EditorFixture invokeIntentionAction(@NotNull String labelPrefix) {
invokeAction(EditorFixture.EditorAction.SHOW_INTENTION_ACTIONS);
JBListPopupFixture.Companion.clickPopupMenuItem(labelPrefix, true, null, robot, GuiTestUtil.INSTANCE.getSHORT_TIMEOUT());
ComponentFixtureUtilsKt
.popupMenu(labelPrefix, robot, null, GuiTestUtil.INSTANCE.getSHORT_TIMEOUT(), Predicate.INSTANCE.getEquality())
.clickSearchedItem();
return this;
}
@@ -1,152 +1,57 @@
/*
* 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.
*/
// 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.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.testGuiFramework.util.FinderPredicate
import com.intellij.ui.components.JBList
import com.intellij.ui.popup.list.ListPopupModel
import org.fest.swing.core.GenericTypeMatcher
import com.intellij.ui.popup.PopupFactoryImpl
import org.fest.swing.core.Robot
import org.fest.swing.exception.ComponentLookupException
import org.fest.swing.exception.WaitTimedOutError
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<*>>(
class JBListPopupFixture(
jbList: JBList<*>,
private val searchedItem: String,
private val predicate: FinderPredicate,
robot: Robot) : JComponentFixture<JBListPopupFixture, JBList<*>>(
JBListPopupFixture::class.java, robot, jbList) {
private class PrefixMatcher(private val prefix: String) : BaseMatcher<String>() {
private val jListFixture = JListFixture(robot, jbList)
override fun matches(item: Any): Boolean {
return item is String && item.startsWith(prefix)
}
override fun describeTo(description: Description) {
description.appendText("with prefix '$prefix'")
}
init {
jListFixture.replaceCellReader(ExtendedJListCellReader())
}
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'")
}
fun clickSearchedItem(){
jListFixture.clickItem(searchedItem)
}
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>>()
try {
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)
} catch (e: WaitTimedOutError){
throw ComponentLookupException("Unable to get JListFixture because: ${e.message}")
}
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) }
}
fun clickItem(item: String) {
jListFixture.clickItem(item)
}
}
fun clickItem(index: Int) {
jListFixture.clickItem(index)
}
fun isSearchedItemEnable(): Boolean =
isItemEnable(itemIndex(searchedItem))
fun isItemEnable(index: Int): Boolean {
val item = jListFixture.target().model.getElementAt(index)
return (item as? PopupFactoryImpl.ActionItem)?.isEnabled
?: throw ClassCastException("Menu item type '${item.javaClass.canonicalName}' cannot be cast to PopupFactoryImpl.ActionItem")
}
fun isSearchedItemPresent() : Boolean = isItemPresent(searchedItem)
fun isItemPresent(item: String): Boolean = listItems().any { predicate(it, item) }
fun itemIndex(item: String): Int = listItems().indexOfFirst { predicate(it, item) }
fun listItems(): List<String> {
val itemCount = jListFixture.target().model.size
return (0 until itemCount)
.mapNotNull { jListFixture.item(it).value() }
}
}
@@ -3,6 +3,7 @@ package com.intellij.testGuiFramework.fixtures
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
import com.intellij.testGuiFramework.framework.GuiTestUtil
import com.intellij.testGuiFramework.impl.popupMenu
import com.intellij.ui.popup.PopupFactoryImpl
import org.fest.swing.core.Robot
import org.fest.swing.exception.ComponentLookupException
@@ -42,7 +43,7 @@ class RunConfigurationListFixture(val myRobot: Robot, val myIde: IdeFrameFixture
*/
fun configuration(name: String): RunActionFixture {
showPopup()
JBListPopupFixture.clickPopupMenuItem(name, false, null, myRobot, GuiTestUtil.SHORT_TIMEOUT)
myIde.popupMenu(name, GuiTestUtil.SHORT_TIMEOUT).clickSearchedItem()
return RunActionFixture()
}
@@ -62,7 +63,7 @@ class RunConfigurationListFixture(val myRobot: Robot, val myIde: IdeFrameFixture
//Close popup
showPopup()
}
JBListPopupFixture.clickPopupMenuItem(EDIT_CONFIGURATIONS, false, null, myRobot, GuiTestUtil.THIRTY_SEC_TIMEOUT)
myIde.popupMenu(EDIT_CONFIGURATIONS, GuiTestUtil.SHORT_TIMEOUT).clickSearchedItem()
}
@@ -16,15 +16,19 @@ import com.intellij.testGuiFramework.util.Predicate
import com.intellij.ui.CheckboxTree
import com.intellij.ui.HyperlinkLabel
import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBList
import com.intellij.ui.components.labels.LinkLabel
import com.intellij.ui.treeStructure.treetable.TreeTable
import com.intellij.util.ui.AsyncProcessIcon
import org.fest.swing.core.GenericTypeMatcher
import org.fest.swing.core.Robot
import org.fest.swing.exception.ComponentLookupException
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.timing.Timeout
import org.junit.Assert
import java.awt.Component
import java.awt.Container
import java.util.concurrent.TimeUnit
@@ -315,10 +319,41 @@ fun <S, C : Component> ComponentFixture<S, C>.table(cellText: String, timeout: L
* @throws ComponentLookupException if component has not been found or timeout exceeded
*/
fun <S, C : Component> ComponentFixture<S, C>.popupClick(itemName: String, timeout: Long = defaultTimeout) =
popupMenu(itemName, timeout = timeout.toFestTimeout()).clickSearchedItem()
fun popupMenu(
item: String,
robot: Robot,
root: Container? = null,
timeout: Timeout = GuiTestUtil.defaultTimeout.toFestTimeout(),
predicate: FinderPredicate = Predicate.equality
): JBListPopupFixture{
val jbList = GuiTestUtil.waitUntilFound(
robot,
root,
object : GenericTypeMatcher<JBList<*>>(JBList::class.java) {
override fun isMatching(component: JBList<*>): Boolean {
return JBListPopupFixture(component, item, predicate, robot).isSearchedItemPresent()
}
},
timeout)
return JBListPopupFixture(jbList, item, predicate, robot)
}
fun <S, C : Component> ComponentFixture<S, C>.popupMenu(
item: String,
timeout: Timeout = GuiTestUtil.defaultTimeout.toFestTimeout(),
predicate: FinderPredicate = Predicate.equality
): JBListPopupFixture {
if (target() is Container) {
JBListPopupFixture.clickPopupMenuItem(itemName, false, target() as Container, robot(), timeout.toFestTimeout())
val root: Container? = GuiTestUtil.getRootContainer(target())
Assert.assertNotNull(root)
return popupMenu(item, robot(), root, timeout, predicate)
}
else throw unableToFindComponent("Popup")
else throw unableToFindComponent("JBList with item '${item}' not found")
}
/**
* Finds a LinkLabel component in hierarchy of context component by a link name and returns fixture for it.
@@ -1,9 +1,9 @@
// 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.util.scenarios
import com.intellij.testGuiFramework.impl.GuiTestCase
import com.intellij.testGuiFramework.impl.button
import com.intellij.testGuiFramework.impl.popupClick
import com.intellij.testGuiFramework.framework.GuiTestUtil
import com.intellij.testGuiFramework.impl.*
import com.intellij.testGuiFramework.util.Key
import com.intellij.testGuiFramework.util.logTestStep
import com.intellij.testGuiFramework.utils.TestUtilsClass
import com.intellij.testGuiFramework.utils.TestUtilsClassCompanion
@@ -27,9 +27,13 @@ fun RunConfigurationScenarios.openRunConfiguration(vararg configuration: String)
logTestStep("Going to check presence of run/debug configuration `$configurationName`")
navigationBar {
assert(exists { button(configurationName) }) { "Button `$configurationName` not found on Navigation bar" }
button(configurationName).click()
popupClick(RunConfigurationScenarios.Constants.editConfigurationMenuItem)
}
GuiTestUtilKt.waitUntil("Menu item '${RunConfigurationScenarios.Constants.editConfigurationMenuItem}' is enabled", GuiTestUtil.LONG_TIMEOUT.duration().toInt()){
shortcut(Key.ESCAPE)
button(configurationName).click()
popupMenu(RunConfigurationScenarios.Constants.editConfigurationMenuItem, GuiTestUtil.NO_TIMEOUT).isSearchedItemEnable()
}
popupMenu(RunConfigurationScenarios.Constants.editConfigurationMenuItem).clickSearchedItem()
}
}
}