My some view that starts from an activity shows an alert dialog when pressing the back button using the BackHandler
.
@Composable
fun PostEditContent(
title: String,
uiState: BasePostEditUiState
) {
var enabledBackHandler by remember { mutableStateOf(true) }
var enabledAlertDialog by remember { mutableStateOf(false) }
val snackBarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()
val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
val navigateToBack = { onBackPressedDispatcher?.onBackPressed() }
val forceNavigateToBack = {
coroutineScope.launch {
enabledBackHandler = false
awaitFrame()
navigateToBack()
}
}
if (enabledAlertDialog) {
PostEditAlertDialog(
onDismissRequest = { enabledAlertDialog = false },
onOkClick = { forceNavigateToBack() }
)
}
BackHandler(enabledBackHandler) {
enabledAlertDialog = true
}
...
It's working fine. But in the testing, it sometimes failed because the awaitFrame()
is not working properly.
@Suppress("TestFunctionName")
@Composable
private fun PostEditScreenWithHomeBackStack(uiState: PostEditUiState) {
val navController = rememberNavController()
NavHost(navController, startDestination = "home") {
composable(route = "home") {
Text(HOME_STACK_TEXT)
}
composable(route = "edit") {
PostEditScreen(uiState = uiState)
}
}
SideEffect {
navController.navigate("edit")
}
}
...
@Test
fun navigateToUp_WhenSuccessSaving() {
composeTestRule.apply {
setContent {
PostEditScreenWithHomeBackStack(emptyUiState.copy(title = "a", content = "a"))
}
// The save button calls the `forceNavigateToBack()` that in the upper code block
onNodeWithContentDescription("save").performClick()
onNodeWithText(HOME_STACK_TEXT).assertIsDisplayed()
}
}
Is there a better way to show the alert dialog or fix the flaky test? Thanks.