Trejkaz
06/19/2025, 3:44 PMwaitForIdle()
seems oddly flaky if the last thing that happened was a dialog appearing or disappearing. I had an assertExists()
fail to find the thing, but then find it a moment later when it tried with useUnmergedTree = true
- and no, it was in the merged tree too.Trejkaz
06/19/2025, 3:44 PMSwingUtilities.invokeAndWait { }
after waiting for idle, and now it seems completely reliableTrejkaz
06/19/2025, 3:45 PMwaitForIdle()
should already be doing?Alexander Maryanovsky
06/19/2025, 3:49 PMTrejkaz
06/19/2025, 3:50 PMTrejkaz
06/19/2025, 3:51 PMTrejkaz
06/19/2025, 4:23 PMpackage garden.ephemeral.calculator.ui.repro
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.window.DialogWindow
import androidx.compose.ui.window.Window
import kotlinx.coroutines.launch
import org.junit.Rule
import org.junit.Test
import javax.swing.SwingUtilities
class BetterErrorHandlingTest_CutDown {
// XXX: Forced to use JUnit 4 for UI tests because Compose only provides JUnit 4 support
@get:Rule
val compose = createComposeRule()
private fun commonTestContent() {
compose.setContent {
var showErrorDialog by remember { mutableStateOf(false) }
Window(onCloseRequest = {}) {
val scope = rememberCoroutineScope()
TextButton(modifier = Modifier.Companion.testTag("TestButton"), onClick = {
scope.launch {
showErrorDialog = true
}
}) {
Text(text = "Button")
}
}
if (showErrorDialog) {
DialogWindow(onCloseRequest = { showErrorDialog = false }) {
Surface(modifier = Modifier.testTag("BetterErrorPane")) {
}
}
}
}
}
@Test
fun `calling waitForIdle only`() {
commonTestContent()
compose.onNodeWithTag("TestButton").performClick()
compose.waitForIdle()
compose.onNodeWithTag("BetterErrorPane").assertExists()
}
@Test
fun `calling waitForIdle and then SwingUtilities invokeAndWait`() {
commonTestContent()
compose.onNodeWithTag("TestButton").performClick()
compose.waitForIdle()
SwingUtilities.invokeAndWait { }
compose.onNodeWithTag("BetterErrorPane").assertExists()
}
}
Alexander Maryanovsky
06/19/2025, 4:26 PMTrejkaz
06/19/2025, 4:26 PMTrejkaz
06/19/2025, 4:26 PMTrejkaz
06/19/2025, 4:26 PMTrejkaz
06/19/2025, 4:26 PMTrejkaz
06/19/2025, 4:27 PMAlexander Maryanovsky
06/19/2025, 4:27 PMTrejkaz
06/19/2025, 4:28 PMAlexander Maryanovsky
06/19/2025, 4:28 PMAlexander Maryanovsky
06/19/2025, 4:28 PMTrejkaz
06/19/2025, 4:28 PMTrejkaz
06/19/2025, 4:30 PMTrejkaz
06/19/2025, 4:30 PMTrejkaz
06/19/2025, 4:31 PMTrejkaz
06/19/2025, 4:32 PMTrejkaz
06/19/2025, 4:33 PMAlexander Maryanovsky
06/19/2025, 4:34 PMTrejkaz
06/19/2025, 4:37 PMTrejkaz
06/19/2025, 4:39 PM