[gui-test] do not send any messages if server is not started; minor fixes;

This commit is contained in:
Sergey Karashevich
2018-10-04 18:56:37 +03:00
parent 37ebfd01ad
commit d79c963e37
6 changed files with 79 additions and 40 deletions
@@ -1,24 +1,25 @@
// 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.testGuiFramework.framework.GuiTestUtil
import com.intellij.testGuiFramework.framework.RunWithIde
import com.intellij.testGuiFramework.framework.Timeouts
import com.intellij.testGuiFramework.impl.GuiTestUtilKt.typeMatcher
import com.intellij.testGuiFramework.impl.actionLink
import com.intellij.testGuiFramework.impl.button
import com.intellij.testGuiFramework.impl.FirstStart
import com.intellij.testGuiFramework.impl.FirstStart.Utils.button
import com.intellij.testGuiFramework.impl.FirstStart.Utils.dialog
import com.intellij.testGuiFramework.impl.ScreenshotOnFailure
import com.intellij.testGuiFramework.launcher.GuiTestLocalLauncher
import com.intellij.testGuiFramework.launcher.ide.CommunityIde
import com.intellij.testGuiFramework.testCases.SystemPropertiesTestCase
import org.fest.swing.core.GenericTypeMatcher
import com.intellij.testGuiFramework.launcher.ide.Ide
import com.intellij.testGuiFramework.remote.IdeControl
import com.intellij.ui.components.labels.ActionLink
import org.fest.swing.core.Robot
import org.junit.Test
import java.awt.Point
import java.net.URL
import javax.swing.JEditorPane
import javax.swing.JLabel
import javax.swing.text.Document
import javax.swing.text.JTextComponent
@RunWithIde(CommunityIde::class)
class IdeaUpdateGuiTest : SystemPropertiesTestCase() {
class IdeaUpdateGuiTest {
private val customUpdatesXml: URL by lazy {
IdeaUpdateGuiTest::class.java.getResource("/update/update.xml")
@@ -26,22 +27,54 @@ class IdeaUpdateGuiTest : SystemPropertiesTestCase() {
@Test
fun testIdeaUpdate() {
restartIdeWithSystemProperties(listOf(Pair("idea.updates.url", customUpdatesXml.toString())))
welcomeFrame { actionLink("Events", timeout = Timeouts.minutes01).click()
val jEditorPane = GuiTestUtil.waitUntilFound(robot(), this.target(), jEditorTextMatcher("is ready to update"), Timeouts.minutes01)
jEditorPane.clickTextInJEditorPane(robot(), "update")
}
dialog("IDE and Plugin Updates") { button("Remind Me Later").click() }
GuiTestLocalLauncher.firstStartIdeLocally(Ide(CommunityIde(), 0, 0), CommunityUpdateFirstStart::class.java.name,
listOf(Pair("idea.updates.url", customUpdatesXml.toString())))
}
}
class CommunityUpdateFirstStart : FirstStart(CommunityIde()) {
override fun completeFirstStart() {
"Complete Installation" { completeInstallation() }
"Accept Agreement" { acceptAgreement() }
// "Accept DataSharing" { acceptDataSharing() }
"Customize IDE" { customizeIde() }
// "Evaluate License" { evaluateLicense(ideType.name, myRobot) }
"Find Welcome Frame" { findWelcomeFrame() }
"Test..." { test() }
"Close Welcome Frame" { findWelcomeFrame()?.close() }
"Wait until IDE is closed for 30 seconds" { Thread.sleep(Timeouts.seconds30.duration()) }
"Close IDE with force " { IdeControl.closeIde() }
}
private fun JEditorPane.clickTextInJEditorPane(robot: Robot, textToClick: String) {
robot().click(this, this.getTextCenter(textToClick))
fun test() {
try {
val welcomeFrame = findWelcomeFrame()
"Find action link with text \"Events\" and click it..." {
val actionLink: JLabel = Utils.waitUntilFound(myRobot, welcomeFrame, JLabel::class.java,
Timeouts.seconds10) { it.javaClass.name == ActionLink::class.java.name && it.text == "Events" && it.isShowing }
myRobot.click(actionLink)
}
"Find JTextComponent containing a text \"is ready to update\" and click \"update\" word" {
val jEditorPane = Utils.waitUntilFound(myRobot, welcomeFrame, JTextComponent::class.java, Timeouts.minutes01) {
it.document.contains("is ready to update")
}
jEditorPane.clickTextInJEditorPane(myRobot, "update")
}
"Find dialog with title \"IDE and Plugin Updates\"" {
myRobot.dialog("IDE and Plugin Updates", Timeouts.minutes01)
}
"Click button \"Remind Me Later\"" {
myRobot.button("Remind Me Later", Timeouts.seconds05).click()
}
}
catch (e: Exception) {
ScreenshotOnFailure.takeScreenshot("FirstStart-TestStep", e)
e.printStackTrace(System.err)
}
}
private fun jEditorTextMatcher(text: String): GenericTypeMatcher<JEditorPane> {
return typeMatcher(JEditorPane::class.java) {
it.document.contains(text)
}
private fun JTextComponent.clickTextInJEditorPane(robot: Robot, textToClick: String) {
myRobot.click(this, this.getTextCenter(textToClick))
}
private fun Document.contains(text: String): Boolean = this.text.contains(text)
@@ -51,10 +84,15 @@ class IdeaUpdateGuiTest : SystemPropertiesTestCase() {
return this.getText(0, length)
}
private fun JEditorPane.getTextCenter(text: String): Point {
private fun JTextComponent.getTextCenter(text: String): Point {
val offset = document.text.indexOf(text)
val coordinates = modelToView(offset + text.length / 2)
return Point(coordinates.centerX.toInt(), coordinates.centerY.toInt())
}
}
operator fun String.invoke(block: () -> Unit) {
println("Step: $this")
block()
}
@@ -67,7 +67,7 @@ abstract class FirstStart(val ideType: IdeType) {
}
}
private fun takeScreenshot(e: Throwable) {
fun takeScreenshot(e: Throwable) {
ScreenshotOnFailure.takeScreenshot("FirstStartFailed", e)
}
@@ -91,7 +91,7 @@ abstract class FirstStart(val ideType: IdeType) {
// In case we found WelcomeFrame we don't need to make completeInstallation.
private fun completeFirstStart() {
open fun completeFirstStart() {
findWelcomeFrame()?.close() ?: let {
completeInstallation()
acceptAgreement()
@@ -108,9 +108,9 @@ abstract class FirstStart(val ideType: IdeType) {
&& frame.isEnabled
}
private fun Frame.close() = myRobot.close(this)
fun Frame.close() = myRobot.close(this)
private fun findWelcomeFrame(seconds: Int = 5): Frame? {
fun findWelcomeFrame(seconds: Int = 5): Frame? {
LOG.info("Waiting for a Welcome Frame")
silentWaitUntil("Welcome Frame to show up", seconds) {
Frame.getFrames().any { checkIsWelcomeFrame(it) }
@@ -132,7 +132,7 @@ abstract class FirstStart(val ideType: IdeType) {
}
}
private fun acceptAgreement() {
open fun acceptAgreement() {
if (!needToShowAgreement()) return
with(myRobot) {
try {
@@ -158,7 +158,7 @@ abstract class FirstStart(val ideType: IdeType) {
myRobot.rotateMouseWheel(amount)
}
private fun completeInstallation() {
open fun completeInstallation() {
if (!needToShowCompleteInstallation()) return
with(myRobot) {
val title = "Complete Installation"
@@ -171,7 +171,7 @@ abstract class FirstStart(val ideType: IdeType) {
}
}
private fun acceptDataSharing() {
open fun acceptDataSharing() {
with(myRobot) {
LOG.info("Accepting Data Sharing")
val title = "Data Sharing"
@@ -187,7 +187,7 @@ abstract class FirstStart(val ideType: IdeType) {
}
}
private fun customizeIde(ideName: String = ideType.name) {
open fun customizeIde(ideName: String = ideType.name) {
if (!needToShowCustomizeWizard()) return
with(myRobot) {
val title = "Customize $ideName"
@@ -199,7 +199,7 @@ abstract class FirstStart(val ideType: IdeType) {
}
}
private fun evaluateLicense(ideName: String, robot: Robot) {
open fun evaluateLicense(ideName: String, robot: Robot) {
with(robot) {
val licenseActivationFrameTitle = "$ideName License Activation"
LOG.info("Waiting for '$licenseActivationFrameTitle' dialog")
@@ -44,6 +44,7 @@ class ScreenshotOnFailure: TestWatcher() {
val file = getOrCreateScreenshotFile(screenshotName)
if (t is ComponentLookupException) LOG.error("${getHierarchy()} \n caused by:", t)
myScreenshotTaker.safeTakeScreenshotAndSave(file)
println("Screenshot saved to $file")
LOG.info("Screenshot: $file")
}
catch (e: Exception) {
@@ -133,8 +133,8 @@ object GuiTestLocalLauncher {
return startIde(ide = ide, ideaStartTest = ProcessBuilder().inheritIO().command(args))
}
fun firstStartIdeLocally(ide: Ide = Ide(CommunityIde(), 0, 0), firstStartClassName: String = "undefined") {
val args = createArgsForFirstStart(ide = ide, firstStartClassName = firstStartClassName)
fun firstStartIdeLocally(ide: Ide = Ide(CommunityIde(), 0, 0), firstStartClassName: String = "undefined", additionalJvmOptions: List<Pair<String, String>> = emptyList()) {
val args = createArgsForFirstStart(ide = ide, firstStartClassName = firstStartClassName, additionalJvmOptions = additionalJvmOptions)
return startIdeAndWait(ide = ide, args = args)
}
@@ -200,13 +200,14 @@ object GuiTestLocalLauncher {
testClassNames = testClassNames,
additionalJvmOptions = additionalJvmOptions)
private fun createArgsForFirstStart(ide: Ide, firstStartClassName: String = "undefined", port: Int = 0): List<String> = createArgsBase(
private fun createArgsForFirstStart(ide: Ide, firstStartClassName: String = "undefined", port: Int = 0, additionalJvmOptions: List<Pair<String, String>> = emptyList()): List<String> = createArgsBase(
ide = ide,
mainClass = "com.intellij.testGuiFramework.impl.FirstStarterKt",
firstStartClassName = firstStartClassName,
commandName = null,
port = port,
testClassNames = emptyList())
testClassNames = emptyList(),
additionalJvmOptions = additionalJvmOptions)
/**
* customVmOptions should contain a full VM options formatted items like: customVmOptions = listOf("-Dapple.laf.useScreenMenuBar=true", "-Dide.mac.file.chooser.native=false").
@@ -30,11 +30,8 @@ object IdeControl {
return currentIdeProcess ?: throw Exception("Current IDE processStdIn is not initialised or already been killed")
}
private var isServerInitialised: Boolean = false
private val myServer: JUnitServer
get() {
isServerInitialised = true
return JUnitServerHolder.getServer()
}
@@ -58,7 +55,7 @@ object IdeControl {
fun closeIde() {
sendCloseIdeSignal()
IdeControl.killIdeProcess()
if (isServerInitialised) myServer.stopServer()
myServer.stopServer()
}
fun restartIde(ide: Ide, additionalJvmOptions: List<Pair<String, String>> = emptyList(), runIde: RunIdeFun) {
@@ -88,6 +85,7 @@ object IdeControl {
}
private fun sendCloseIdeSignal() {
if (!myServer.isStarted()) return
myServer.send(TransportMessage(MessageType.CLOSE_IDE))
IdeControl.waitForCurrentProcess(2, TimeUnit.MINUTES)
}
@@ -127,6 +127,7 @@ class JUnitServerImpl : JUnitServer {
override fun getPort(): Int = port
override fun stopServer() {
if (!isStarted) return
serverSendThread.interrupt()
LOG.info("Server Send Thread joined")
serverReceiveThread.interrupt()