[gui-test] IDEA-CR-35340 review fixes

added `silentWaitUntil` method which can wait for condition without WaitTimedOutError
This commit is contained in:
Eugene Nizienko
2018-07-25 15:26:20 +03:00
parent 0ecd0bb8e2
commit 9c61286080
2 changed files with 48 additions and 27 deletions
@@ -12,7 +12,7 @@ import com.intellij.testGuiFramework.impl.FirstStart.Utils.button
import com.intellij.testGuiFramework.impl.FirstStart.Utils.dialog
import com.intellij.testGuiFramework.impl.FirstStart.Utils.radioButton
import com.intellij.testGuiFramework.impl.FirstStart.Utils.waitFrame
import com.intellij.testGuiFramework.impl.GuiTestUtilKt.waitUntil
import com.intellij.testGuiFramework.impl.GuiTestUtilKt.silentWaitUntil
import com.intellij.testGuiFramework.launcher.ide.IdeType
import org.fest.swing.core.GenericTypeMatcher
import org.fest.swing.core.Robot
@@ -93,6 +93,8 @@ abstract class FirstStart(val ideType: IdeType) {
var DEFAULT_TIMEOUT: Long = defaultTimeout
}
// In case we found WelcomeFrame we don't need to make completeInstallation.
private fun completeFirstStart() {
findWelcomeFrame()?.close() ?: let {
completeInstallation()
@@ -104,7 +106,7 @@ abstract class FirstStart(val ideType: IdeType) {
}
}
private val checkIsWelcomeFramePredicate: (Frame) -> Boolean = { frame ->
private val checkIsWelcomeFrame: (Frame) -> Boolean = { frame ->
frame.javaClass.simpleName == "FlatWelcomeFrame"
&& frame.isShowing
&& frame.isEnabled
@@ -114,15 +116,10 @@ abstract class FirstStart(val ideType: IdeType) {
private fun findWelcomeFrame(seconds: Int = 5): Frame? {
LOG.info("Waiting for a Welcome Frame")
return try {
waitUntil("Welcome Frame to show up", seconds) {
Frame.getFrames().any { checkIsWelcomeFramePredicate(it) }
}
Frame.getFrames().first { checkIsWelcomeFramePredicate(it) }
}
catch (e: WaitTimedOutError) {
null
silentWaitUntil("Welcome Frame to show up", seconds) {
Frame.getFrames().any { checkIsWelcomeFrame(it) }
}
return Frame.getFrames().firstOrNull { checkIsWelcomeFrame(it) }
}
@@ -74,7 +74,7 @@ object GuiTestUtilKt {
return tree
}
catch(e: Exception) {
catch (e: Exception) {
throw Exception("Unable to build a tree from given data. Check indents and ")
}
}
@@ -141,11 +141,17 @@ object GuiTestUtilKt {
}
fun findComponentByText(robot: Robot, container: Container, text: String): Component {
return withPauseWhenNull { robot.finder().findAll(container, ComponentMatcher { component ->
component!!.isShowing && component.isTextComponent() && component.getComponentText() == text }).firstOrNull() }
return withPauseWhenNull {
robot.finder().findAll(container, ComponentMatcher { component ->
component!!.isShowing && component.isTextComponent() && component.getComponentText() == text
}).firstOrNull()
}
}
fun <BoundedComponent> findBoundedComponentByText(robot: Robot, container: Container, text: String, componentType: Class<BoundedComponent>): BoundedComponent {
fun <BoundedComponent> findBoundedComponentByText(robot: Robot,
container: Container,
text: String,
componentType: Class<BoundedComponent>): BoundedComponent {
val componentWithText = findComponentByText(robot, container, text)
if (componentWithText is JLabel && componentWithText.labelFor != null) {
val labeledComponent = componentWithText.labelFor
@@ -159,8 +165,9 @@ object GuiTestUtilKt {
.sortedBy { it.bounds.x }
.firstOrNull()
} as BoundedComponent
} catch (e: WaitTimedOutError) {
throw ComponentLookupException("Unable to find component of type: ${componentType.simpleName} in $container by text: $text" )
}
catch (e: WaitTimedOutError) {
throw ComponentLookupException("Unable to find component of type: ${componentType.simpleName} in $container by text: $text")
}
}
@@ -169,7 +176,7 @@ object GuiTestUtilKt {
val centerXAxis = this.bounds.height / 2 + this.locationOnScreen.y
val sideCheck =
if (onLeft)
textComponent.locationOnScreen.x < this.locationOnScreen.x
textComponent.locationOnScreen.x < this.locationOnScreen.x
else
textComponent.locationOnScreen.x > this.locationOnScreen.x
return (textComponent.locationOnScreen.y <= centerXAxis)
@@ -190,7 +197,7 @@ object GuiTestUtilKt {
*/
fun <ReturnType> withPauseWhenNull(timeoutInSeconds: Int = 30, testWithPause: () -> ReturnType?): ReturnType {
val ref = Ref<ReturnType>()
Pause.pause(object: Condition("With pause...") {
Pause.pause(object : Condition("With pause...") {
override fun test(): Boolean {
val testWithPauseResult = testWithPause()
if (testWithPauseResult != null) ref.set(testWithPauseResult)
@@ -206,6 +213,15 @@ object GuiTestUtilKt {
}, Timeout.timeout(timeoutInSeconds.toLong(), TimeUnit.SECONDS))
}
fun silentWaitUntil(condition: String, timeoutInSeconds: Int = 60, conditionalFunction: () -> Boolean) {
try {
Pause.pause(object : Condition("$timeoutInSeconds second(s) until $condition silently") {
override fun test() = conditionalFunction()
}, Timeout.timeout(timeoutInSeconds.toLong(), TimeUnit.SECONDS))
}
catch (ignore: WaitTimedOutError) { }
}
fun <ComponentType : Component> findAllWithBFS(container: Container, clazz: Class<ComponentType>): List<ComponentType> {
val result = LinkedList<ComponentType>()
val queue: Queue<Component> = LinkedList()
@@ -216,7 +232,7 @@ object GuiTestUtilKt {
}
queue.add(container)
while(queue.isNotEmpty()) {
while (queue.isNotEmpty()) {
val polled = queue.poll()
check(polled)
if (polled is Container)
@@ -227,7 +243,10 @@ object GuiTestUtilKt {
}
fun <ComponentType : Component> waitUntilGone(robot: Robot, timeoutInSeconds: Int = 30, root: Container? = null, matcher: GenericTypeMatcher<ComponentType>) {
fun <ComponentType : Component> waitUntilGone(robot: Robot,
timeoutInSeconds: Int = 30,
root: Container? = null,
matcher: GenericTypeMatcher<ComponentType>) {
return GuiTestUtil.waitUntilGone(root, timeoutInSeconds, matcher)
}
@@ -235,7 +254,10 @@ object GuiTestUtilKt {
waitProgressDialogUntilGone(this.robot(), dialogTitle, timeoutToAppearInSeconds, timeoutToGoneInSeconds)
}
fun waitProgressDialogUntilGone(robot: Robot, progressTitle: String, timeoutToAppearInSeconds: Int = 5, timeoutToGoneInSeconds: Int = 60) {
fun waitProgressDialogUntilGone(robot: Robot,
progressTitle: String,
timeoutToAppearInSeconds: Int = 5,
timeoutToGoneInSeconds: Int = 60) {
//wait dialog appearance. In a bad case we could pass dialog appearance.
var dialog: JDialog? = null
try {
@@ -243,26 +265,28 @@ object GuiTestUtilKt {
dialog = findProgressDialog(robot, progressTitle)
dialog != null
}
} catch (timeoutError: WaitTimedOutError) { return }
}
catch (timeoutError: WaitTimedOutError) {
return
}
waitUntil("progress dialog with title $progressTitle will gone", timeoutToGoneInSeconds) { dialog == null || !dialog!!.isShowing }
}
fun findProgressDialog(robot: Robot, progressTitle: String): JDialog? {
return robot.finder().findAll(typeMatcher(JDialog::class.java) {
findAllWithBFS(it, EngravedLabel::class.java).filter { it.isShowing && it.text == progressTitle }.any()
} ).firstOrNull()
}).firstOrNull()
}
fun <ComponentType : Component?> typeMatcher(componentTypeClass: Class<ComponentType>,
matcher: (ComponentType) -> Boolean): GenericTypeMatcher<ComponentType> {
matcher: (ComponentType) -> Boolean): GenericTypeMatcher<ComponentType> {
return object : GenericTypeMatcher<ComponentType>(componentTypeClass) {
override fun isMatching(component: ComponentType): Boolean = matcher(component)
}
}
fun <ReturnType> computeOnEdt(query: () -> ReturnType): ReturnType?
= GuiActionRunner.execute(object : GuiQuery<ReturnType>() {
fun <ReturnType> computeOnEdt(query: () -> ReturnType): ReturnType? = GuiActionRunner.execute(object : GuiQuery<ReturnType>() {
override fun executeInEDT(): ReturnType = query()
})
@@ -306,7 +330,7 @@ object GuiTestUtilKt {
val errors = mutableListOf<Error>()
for (errorMessage in freshErrorMessages) {
val messageBuilder = StringBuilder(errorMessage.message ?: "")
val additionalInfo : String? = errorMessage.additionalInfo
val additionalInfo: String? = errorMessage.additionalInfo
if (additionalInfo != null && additionalInfo.isNotEmpty())
messageBuilder.append(System.getProperty("line.separator")).append("Additional Info: ").append(additionalInfo)
val error = Error(messageBuilder.toString(), errorMessage.throwable)