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?
fun main() {
SwingUtilities.invokeLater {
val composePanel = ComposePanel().apply {
setContent {
MyTextField()
}
}
with(JFrame("compose test")) {
add(composePanel)
setSize(400, 200)
isVisible = true
}
}
} (edited)