Reputation: 9380
I have dialog in compose:
@Composable
fun testgtt() {
val saveDialogState = remember { mutableStateOf(false) }
Button(onClick = { saveDialogState.value = true }, modifier = Modifier.testTag(PLACE_TAG)) {
Text(text = "helllow")
}
Dialog(onDismissRequest = { saveDialogState.value = false }) {
Text(text = "helllow",modifier = Modifier.testTag(BUTTON_TAG))
}
}
and want to test it:
@Test
fun das(){
composeTestRule.setContent {
TerTheme {
testgtt()
}
}
composeTestRule.onRoot(useUnmergedTree = true).printToLog("currentLabelExists")
composeTestRule.onNodeWithTag(PLACE_TAG).performClick()
composeTestRule.onNodeWithTag(BUTTON_TAG).assertIsDisplayed()
}
but I get this error:
java.lang.AssertionError: Failed: assertExists.
Reason: Expected exactly '1' node but found '2' nodes that satisfy: (isRoot)
Nodes found:
1) Node #1 at (l=0.0, t=0.0, r=206.0, b=126.0)px
Has 1 child
2) Node #78 at (l=0.0, t=0.0, r=116.0, b=49.0)px
Has 1 child
Inspite of the fact that I see the Dialog itself.
Upvotes: 11
Views: 8354
Reputation: 41
I also faced the same situation where i need to click a button in a dialog in compose. In compose testing cheat sheet they have this matcher call isDialog(), using this you can test the dialog in your UI tests.
Sample test
composeTestRule.onNode(
isDialog()
and
hasAnyDescendant(
hasText("ok", ignoreCase = true)
),
useUnmergedTree = true
).performClick()
Upvotes: 3
Reputation: 1809
Short answer : Use onAllNodesWithText
sach as following :
onAllNodesWithText("Your Text")[0].assertIsDisplayed()
onAllNodesWithText("Your Text")[1].assertIsDisplayed()
Details:
According to here this error happens when we have two (or more) text or tag inside the Composable functions...You can check it with this:
onRoot(useUnmergedTree = true).printToLog("TAG")
Upvotes: 4
Reputation: 5628
As @DanielO said you can use the isRoot()
selector, see below. That however prints out the same message as before.
A possible workaround is to instead print both root trees using something like
composeTestRule.onAllNodes(isRoot()).printToLog("currentLabelExists")
You have to distinctivly select which root you are looking for. By using the selectors:
.get( index )
.onFirst()
.onLast()
When added it should look like this:
composeTestRule.onAllNodes(isRoot()).get(1).printToLog("T:")
composeTestRule.onAllNodes(isRoot()).onFirst().printToLog("T:")
composeTestRule.onAllNodes(isRoot()).onLast().printToLog("T:")
Upvotes: 5
Reputation: 155
The reason for this error is the line: composeTestRule.onRoot(useUnmergedTree = true).printToLog("currentLabelExists")
onRoot
expects a single node, but i suspect both the containing view and the dialog each return their own root (Speculation)
A possible workaround is to instead print both root trees using something like
composeTestRule.onAllNodes(isRoot()).printToLog("currentLabelExists")
Upvotes: 5
Reputation: 9380
use navigation component:
@Composable
fun de(){
val navController = rememberNavController()
Scaffold { innerPadding ->
NavHost(navController, "home", Modifier.padding(innerPadding)) {
composable("home") {
// This content fills the area provided to the NavHost
val saveDialogState = remember { mutableStateOf(true) }
Button(onClick = {
navController.navigate("detail_dialog")
}, modifier = Modifier.testTag(PLACE_TAG)) {
Text(text = "helllow")
}
}
dialog("detail_dialog") {
// This content will be automatically added to a Dialog() composable
// and appear above the HomeScreen or other composable destinations
Dialog(onDismissRequest = {navController.navigate("home")}) {
Card(
shape = RoundedCornerShape(10.dp),
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
// .padding(horizontal = 16.dp)
.padding(vertical = 8.dp),
elevation = 8.dp
){
Text(text = "helllow", modifier = Modifier.testTag(BUTTON_TAG))
}
}
}
}
}
}
Upvotes: 0