-
Notifications
You must be signed in to change notification settings - Fork 330
Integration test update #3374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration test update #3374
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,94 +6,163 @@ | |
|
|
||
| package io.flutter.tests.gui | ||
|
|
||
| import com.intellij.openapi.util.SystemInfo.isMac | ||
| import com.intellij.testGuiFramework.fixtures.ActionButtonFixture | ||
| import com.intellij.testGuiFramework.fixtures.ExecutionToolWindowFixture | ||
| import com.intellij.testGuiFramework.fixtures.IdeFrameFixture | ||
| import com.intellij.testGuiFramework.framework.RunWithIde | ||
| import com.intellij.testGuiFramework.framework.Timeouts | ||
| import com.intellij.testGuiFramework.impl.GuiTestCase | ||
| import com.intellij.testGuiFramework.impl.GuiTestUtilKt | ||
| import com.intellij.testGuiFramework.impl.button | ||
| import com.intellij.testGuiFramework.launcher.ide.CommunityIde | ||
| import io.flutter.tests.gui.fixtures.FlutterInspectorFixture | ||
| import org.fest.swing.edt.GuiActionRunner.execute | ||
| import org.fest.swing.edt.GuiQuery | ||
| import org.fest.swing.fixture.JButtonFixture | ||
| import com.intellij.testGuiFramework.util.step | ||
| import io.flutter.tests.gui.fixtures.flutterInspectorFixture | ||
| import org.fest.swing.fixture.JTreeRowFixture | ||
| import org.fest.swing.timing.Condition | ||
| import org.fest.swing.timing.Pause.pause | ||
| import org.junit.Assert.assertNotNull | ||
| import org.junit.Test | ||
| import java.awt.Container | ||
| import java.awt.event.KeyEvent | ||
| import kotlin.test.expect | ||
|
|
||
| @RunWithIde(CommunityIde::class) | ||
| class InspectorTest : GuiTestCase() { | ||
|
|
||
| @Test | ||
| fun importSimpleProject() { | ||
| fun widgetTree() { | ||
| ProjectCreator.importProject() | ||
| ideFrame { | ||
| launchFlutterApp() | ||
| val inspector = flutterInspectorFixture(this) | ||
| inspector.populate() | ||
| val widgetTree = inspector.widgetTreeFixture() | ||
| val widgetTree = inspector.widgetsFixture() | ||
| val inspectorTree = widgetTree.inspectorTreeFixture() | ||
| val detailsTree = widgetTree.inspectorTreeFixture(isDetails = true) | ||
| expect(true) { detailsTree.selection() == null } | ||
|
|
||
| step("Details selection synced with main tree") { | ||
| inspectorTree.selectRow(2, expand = true) | ||
| expect("[[root], MyApp, MaterialApp, MyHomePage]") { inspectorTree.selectionSync().toString() } | ||
| expect("[MyHomePage]") { detailsTree.selectionSync().toString() } | ||
| inspectorTree.selectRow(10, expand = true) | ||
| expect("[[root], MyApp, MaterialApp, MyHomePage, Scaffold, FloatingActionButton]") { | ||
| inspectorTree.selectionSync().toString() | ||
| } | ||
| val string = detailsTree.selectionSync().toString() | ||
| expect(true) { | ||
| string.startsWith("[MyHomePage,") && string.endsWith("FloatingActionButton]") | ||
| } | ||
| } | ||
|
|
||
| // This is disabled due to an issue in the test framework. The #selectRow call causes | ||
| // the widget tree to change its selection, which is absolutely not what we want. | ||
| // step("Details selection leaves main tree unchanged") { | ||
| // val string = detailsTree.selectionSync().toString() | ||
| // detailsTree.selectRow(1, expand = false) | ||
| // pause(object : Condition("Details tree changes") { | ||
| // override fun test(): Boolean { | ||
| // return string != detailsTree.selectionSync().toString() | ||
| // } | ||
| // }, Timeouts.seconds05) | ||
| // expect("[[root], MyApp, MaterialApp, MyHomePage, Scaffold, FloatingActionButton]") { | ||
| // inspectorTree.selectionSync().toString() | ||
| // } | ||
| // } | ||
|
|
||
| runner().stop() | ||
| } | ||
| } | ||
|
|
||
| private fun IdeFrameFixture.runner(): ExecutionToolWindowFixture.ContentFixture { | ||
| return runToolWindow.findContent("main.dart") | ||
| @Test | ||
| fun hotReload() { | ||
| ProjectCreator.importProject() | ||
| ideFrame { | ||
| launchFlutterApp() | ||
| val inspector = flutterInspectorFixture(this) | ||
| inspector.populate() | ||
| val widgets = inspector.widgetsFixture() | ||
| val widgetsTree = widgets.inspectorTreeFixture(isDetails = false) | ||
| widgetsTree.selectRow(0) | ||
| val detailsTree = widgets.inspectorTreeFixture(isDetails = true) | ||
| val initialDetails = detailsTree.selectionSync().toString() | ||
|
|
||
| editor { | ||
| // Wait until current file has appeared in current editor and set focus to editor. | ||
| moveTo(0) | ||
| val editorCode = getCurrentFileContents(false)!! | ||
| val original = "pushed the button this" | ||
| val index = editorCode.indexOf(original) + original.length | ||
| moveTo(index) | ||
| val key = if (isMac) KeyEvent.VK_BACK_SPACE else KeyEvent.VK_DELETE | ||
| for (n in 1..4) typeKey(key) | ||
| typeText("that") | ||
| //typeKey(KeyEvent.VK_ESCAPE) // Dismiss completion popup -- not needed with "that" but is needed with "so" | ||
| } | ||
|
|
||
| step("Trigger Hot Reload and wait for it to finish") { | ||
| val reload = findHotReloadButton() | ||
| reload.click() | ||
| editor.clickCenter() // Need to cycle the event loop to get button enabled on Mac. | ||
| pause(object : Condition("Hot Reload finishes") { | ||
| override fun test(): Boolean { | ||
| return reload.isEnabled | ||
| } | ||
| }, Timeouts.seconds05) | ||
| step("Work around #3370") { | ||
| // https://github.com/flutter/flutter-intellij/issues/3370 | ||
| inspector.renderTreeFixture().show() // The refresh button is broken so force tree update by switching views. | ||
| inspector.populate() | ||
| widgets.show() // And back to the one we want | ||
| } | ||
| widgetsTree.selectRow(6) // Text widget | ||
pq marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| pause(object : Condition("Details tree changes") { | ||
| override fun test(): Boolean { | ||
| return initialDetails != detailsTree.selectionSync().toString() | ||
| } | ||
| }, Timeouts.seconds05) | ||
| val row: JTreeRowFixture = detailsTree.treeFixture().node(1) | ||
| val expected = "\"You have pushed the button that many times:\"" | ||
| expect(expected) { row.value() } | ||
| } | ||
|
|
||
| runner().stop() | ||
| } | ||
| } | ||
|
|
||
| fun IdeFrameFixture.launchFlutterApp() { | ||
| findRunApplicationButton().click() | ||
| val runner = runner() | ||
| pause(object : Condition("Start app") { | ||
| override fun test(): Boolean { | ||
| return runner.isExecutionInProgress | ||
| } | ||
| }, Timeouts.seconds10) | ||
| step("Launch Flutter app") { | ||
| findRunApplicationButton().click() | ||
| val runner = runner() | ||
| pause(object : Condition("Start app") { | ||
| override fun test(): Boolean { | ||
| return runner.isExecutionInProgress | ||
| } | ||
| }, Timeouts.seconds30) | ||
| } | ||
| } | ||
|
|
||
| fun IdeFrameFixture.selectSimulator() { | ||
| selectDevice("Open iOS Simulator") | ||
| private fun findHotReloadButton(): ActionButtonFixture { | ||
| return findActionButtonByClassName("ReloadFlutterAppRetarget") | ||
pq marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| fun IdeFrameFixture.selectDevice(devName: String) { | ||
| val runButton = findRunApplicationButton() | ||
| val actionToolbarContainer = execute<Container>(object : GuiQuery<Container>() { | ||
| @Throws(Throwable::class) | ||
| override fun executeInEDT(): Container? { | ||
| return runButton.target().parent | ||
| } | ||
| }) | ||
| assertNotNull(actionToolbarContainer) | ||
|
|
||
| // These next two lines look like the right way to select the simulator, but it does not work. | ||
| // val comboBoxActionFixture = ComboBoxActionFixture.findComboBoxByText(robot(), actionToolbarContainer!!, "<no devices>") | ||
| // comboBoxActionFixture.selectItem(devName) | ||
| // Need to get focus on the combo box but the ComboBoxActionFixture.click() method is private, so it is inlined here. | ||
| val selector = button("<no devices>") | ||
| val comboBoxButtonFixture = JButtonFixture(robot(), selector.target()) | ||
| GuiTestUtilKt.waitUntil("ComboBoxButton will be enabled", Timeouts.seconds10) { | ||
| GuiTestUtilKt.computeOnEdt { comboBoxButtonFixture.target().isEnabled } ?: false | ||
| } | ||
| comboBoxButtonFixture.click() | ||
| robot().pressAndReleaseKey(KeyEvent.VK_DOWN) | ||
| robot().pressAndReleaseKey(KeyEvent.VK_ENTER) | ||
| robot().waitForIdle() | ||
| private fun IdeFrameFixture.runner(): ExecutionToolWindowFixture.ContentFixture { | ||
| return runToolWindow.findContent("main.dart") | ||
| } | ||
|
|
||
| private fun IdeFrameFixture.findActionButtonByActionId(actionId: String): ActionButtonFixture { | ||
| private fun findActionButtonByActionId(actionId: String): ActionButtonFixture { | ||
| // This seems to be broken, but finding by simple class name works. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bummer. But I guess since we own all the classes under test, not a big deal? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what the problem is. I haven't even ruled out pilot error (hmm, that may not be a great idiom these days). It might be a bug in the framework. I keep this around to remind myself not to use it. |
||
| var button: ActionButtonFixture? = null | ||
| ideFrame { | ||
| button = ActionButtonFixture.fixtureByActionId(target(), robot(), actionId) | ||
| button = ActionButtonFixture.fixtureByActionId(target().parent, robot(), actionId) | ||
| } | ||
| return button!! | ||
| } | ||
|
|
||
| fun IdeFrameFixture.flutterInspectorFixture(ideFrame: IdeFrameFixture): FlutterInspectorFixture { | ||
| return FlutterInspectorFixture(project, robot(), ideFrame) | ||
| private fun findActionButtonByClassName(className: String): ActionButtonFixture { | ||
| // This works when the button is enabled but fails if it is disabled (implementation detail). | ||
| var button: ActionButtonFixture? = null | ||
| ideFrame { | ||
| button = ActionButtonFixture.fixtureByActionClassName(target(), robot(), className) | ||
| } | ||
| return button!! | ||
| } | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.