How to test a hybrid Swing / Compose Desktop application

95 Views Asked by At

We are migrating a large Swing application to Compose Desktop and are intending to replace Swing components by compose components within the existing Swing UI, e.g. a Composable component with TextFields into a Swing container like JPanel. We are using a ComposePanel to do this, and that works fine. The individual compose components can be unit-tested OK with ComposeTestRule. However, we need higher level tests of the application containing both the Swing components and the new components which means sending keyboard & mouse input to the "embedded" compose components and also reading their state. Is there a way to do this? Ideally, we'd like the matchers and assertions provided by ComposeTestRule, but which would be available even if the composable is contained in a ComposePanel or ComposeWindow.

Here is a simple example of what we are trying to achieve. The state of MyTextField can be easily unit-tested using ComposeTestRule:

@get:Rule
val composeTestRule = createComposeRule()
@Test
fun `text field should be initialised to bar and also editable`()  {
    with (composeTestRule) {
        setContent {
            MyTextField()
        }
        onNodeWithText("bar").assertExists()
        onNodeWithTag("myTextField").performTextInput("foo ")
        onNodeWithText("foo bar").assertExists()
    }
}
@Composable
@Preview
fun MyTextField() {
    var text by remember { mutableStateOf("bar") }
    MaterialTheme {
        TextField(
            value =text,
            onValueChange = { changedText ->
                text = changedText
                println("changedText = ${changedText}")
            },
            modifier = Modifier.testTag("myTextField")
        )
    }
}

but when it's embedded in a JFrame using ComposePanel, how does one programatically perform the same sort of interactions and checks?

enter image description here


fun main() {
    SwingUtilities.invokeLater {
        val composePanel = ComposePanel().apply {
            setContent {
                MyTextField()
            }
        }
        with(JFrame("compose test")) {
            add(composePanel)
            setSize(400, 200)
            isVisible = true
        }
    }
} (edited) 
0

There are 0 best solutions below