assertj / assertj-swing

Fluent assertions for Swing apps
Other
109 stars 52 forks source link

Stuck waiting for event queue when DialogWrapper is created dynamically #239

Open FWDekker opened 5 years ago

FWDekker commented 5 years ago

Issue

I use IntelliJ's DialogWrapper to show dialogs in an IntelliJ plugin. This dialog is opened by a different window. When trying to simulate input events using AssertJ Swing, however, simply changing the text of an input box easily takes 30 seconds. Clicking a button takes 11 seconds.

The issue seems to be that, once the sub-dialog has been opened, the robot gets stuck in waitForIdle(EventQueue). This makes this issue related to #13 and #201. The difference is that I do not use a custom event queue.

Reproducible example

I have created a minimal reproducible example. The code can be found below.

Java code

```java package com.fwdekker.assertjswingtest; import com.intellij.openapi.ui.DialogWrapper; import org.assertj.swing.edt.GuiActionRunner; import org.assertj.swing.fixture.FrameFixture; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JPanel; import static org.assertj.swing.fixture.Containers.showInFrame; // Uses AssertJ Swing to test the interaction between the dialogs. class DialogTest { private FrameFixture frame; @BeforeEach void beforeEach() { frame = showInFrame(GuiActionRunner.execute(MainDialog::new).getRootPane()); } @AfterEach void afterEach() { frame.cleanUp(); } @Test void myTest() { // This action takes 10 seconds frame.button("mainButton").click(); } } // The main dialog that opens the sub-dialog. class MainDialog extends JDialog { MainDialog() { JPanel contentPane = new JPanel(); JButton mainButton = new JButton("Open"); mainButton.setName("mainButton"); mainButton.addActionListener(e -> new SubDialog().showAndGet()); contentPane.add(mainButton); setContentPane(contentPane); setModal(true); pack(); } } // The sub-dialog using IntelliJ's `DialogWrapper`. class SubDialog extends DialogWrapper { private JPanel contentPane = new JPanel(); SubDialog() { super(null); init(); } @Override protected JPanel createCenterPanel() { return contentPane; } } ```

Gradle build file

```groovy plugins { id "java" id "org.jetbrains.intellij" version "0.4.9" } repositories { mavenCentral() } dependencies { testCompile group: "org.assertj", name: "assertj-core", version: "3.8.0" testCompile group: "org.assertj", name: "assertj-swing-junit", version: "3.8.0" testCompile group: "org.junit.jupiter", name: "junit-jupiter-api", version: "5.5.0" testCompile group: "org.junit.jupiter", name: "junit-jupiter-engine", version: "5.5.0" } intellij { version = "2019.1.1" } test { useJUnitPlatform() } ```

Alternatively, download a .zip of the minimal project. You can run the test from the command line with ./gradlew test (Unix-like) or gradlew test (Windows).

Workarounds

I was able to find two workarounds for this issue. They are suboptimal solutions, but may be useful for others who have this issue: