Skip to content

Instantly share code, notes, and snippets.

@lukaville
Last active July 3, 2019 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukaville/d7105a54a4cf23c8b7a9c7025bdcb780 to your computer and use it in GitHub Desktop.
Save lukaville/d7105a54a4cf23c8b7a9c7025bdcb780 to your computer and use it in GitHub Desktop.
Dismiss Android system dialogs (application is not responding and application crashed) before tests to improve tests run stability
import android.content.res.Resources
import android.support.test.InstrumentationRegistry
import android.support.test.uiautomator.UiDevice
import android.support.test.uiautomator.UiSelector
import java.lang.IllegalStateException
/**
* Based on https://github.com/nenick/espresso-macchiato
*/
class DismissSystemDialogsRule : SimpleRule() {
override fun before() {
dismissSystemDialogIfShown(
dialogSelectors = listOfNotNull(
getStringResourceByName("aerr_application", ".*"),
getStringResourceByName("aerr_application_repeated", ".*"),
getStringResourceByName("aerr_process", ".*"),
getStringResourceByName("aerr_process_repeated", ".*")
),
dismissButtonSelectors = listOfNotNull(
getStringResourceByName("ok"),
getStringResourceByName("aerr_close"),
getStringResourceByName("aerr_close_app")
)
)
dismissSystemDialogIfShown(
dialogSelectors = listOfNotNull(
getStringResourceByName("anr_process", ".*"),
getStringResourceByName("anr_activity_application", ".*", ".*"),
getStringResourceByName("anr_application_process", ".*"),
getStringResourceByName("anr_activity_process", ".*")
),
dismissButtonSelectors = listOfNotNull(
getStringResourceByName("wait"),
getStringResourceByName("ok"),
getStringResourceByName("aerr_close"),
getStringResourceByName("aerr_close_app")
)
)
}
private fun dismissSystemDialogIfShown(
dialogSelectors: List<String>,
dismissButtonSelectors: List<String>
) {
val isDialogDisplayed = elementWithTextExists(dialogSelectors.joinToOrRegexp())
if (isDialogDisplayed) {
dismissButtonSelectors
.firstOrNull { elementWithTextExists(it) }
?.let { click(it) }
?: throw IllegalStateException("Found system dialog but can't find dismiss button")
}
}
private fun List<String>.joinToOrRegexp(): String =
joinToString(separator = "|") {
it.replace("?", "\\?")
}.let {
"($it)"
}
private fun elementWithTextExists(expectedMessage: String): Boolean {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val dialog = device.findObject(UiSelector().textMatches(expectedMessage))
return dialog.exists()
}
private fun click(textSelector: String) {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
val targetUiObject = device.findObject(UiSelector().text(textSelector))
targetUiObject.click()
}
private fun getStringResourceByName(name: String, vararg formatArgs: String): String? = try {
// for all available strings see Android/sdk/platforms/android-28/data/res/values/strings.xml
val resId = InstrumentationRegistry.getContext().resources.getIdentifier(name, "string", "android")
InstrumentationRegistry.getContext().getString(resId, *formatArgs)
} catch (exception: Resources.NotFoundException) {
null
}
}
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
abstract class SimpleRule : TestRule {
override fun apply(base: Statement, description: Description): Statement =
object : Statement() {
override fun evaluate() {
before()
try {
base.evaluate()
} finally {
after()
}
}
}
protected open fun before() {}
protected open fun after() {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment