Skip to content

Instantly share code, notes, and snippets.

@dimorinny
Created July 2, 2019 18:05
Show Gist options
  • Save dimorinny/cb5cc92ae6cc42763ce3977ab2a8fd46 to your computer and use it in GitHub Desktop.
Save dimorinny/cb5cc92ae6cc42763ce3977ab2a8fd46 to your computer and use it in GitHub Desktop.
Close system dialogs
package com.avito.android.runner
import android.annotation.SuppressLint
import android.support.test.InstrumentationRegistry
import android.support.test.uiautomator.UiDevice
import android.support.test.uiautomator.UiSelector
import android.util.Log
import com.avito.android.util.getStackTraceString
/**
* Based on https://github.com/nenick/espresso-macchiato
*/
class SystemDialogsManager {
@SuppressLint("LogNotTimber")
fun closeSystemDialogs() {
try {
dismissCrashDialogIfShown()
} catch (t: Throwable) {
Log.v(TAG, "Failed to close crash dialog: ${t.getStackTraceString()}")
}
try {
dismissAnrDialogIfShown()
} catch (t: Throwable) {
Log.v(TAG, "Failed to close application not respond dialog: ${t.getStackTraceString()}")
}
}
private fun dismissCrashDialogIfShown() {
val crashStrings = listOfNotNull(
stringResourceByName("aerr_application", ".*"),
stringResourceByName("aerr_application_repeated", ".*"),
stringResourceByName("aerr_process", ".*"),
stringResourceByName("aerr_process_repeated", ".*")
)
.joinToOrRegexp()
if (crashStrings.isEmpty()) {
throw RuntimeException("Unable to find any of resources in crashStrings")
}
if (elementWithTextExists(crashStrings)) {
val ok = stringResourceByName("ok")
val close = stringResourceByName("aerr_close")
val closeApp = stringResourceByName("aerr_close_app")
when {
ok != null && elementWithTextExists(ok) -> click(ok)
close != null && elementWithTextExists(close) -> click(close)
closeApp != null && elementWithTextExists(closeApp) -> click(closeApp)
else -> throw IllegalStateException("Found crash dialog but can't find dismiss button")
}
}
}
private fun dismissAnrDialogIfShown() {
val anrStrings = listOfNotNull(
stringResourceByName("anr_process", ".*"),
stringResourceByName("anr_activity_application", ".*", ".*"),
stringResourceByName("anr_application_process", ".*")
).joinToOrRegexp()
if (anrStrings.isEmpty()) {
throw RuntimeException("Unable to find any of resources in anrStrings")
}
if (elementWithTextExists(anrStrings)) {
val wait = stringResourceByName("wait") ?: throw RuntimeException(
"Found anr dialog but can't find wait button"
)
click(wait)
}
}
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 stringResourceByName(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 (t: Throwable) {
null
}
private fun List<String>.joinToOrRegexp(): String =
joinToString(separator = "|") {
it.replace("?", "\\?")
}.let {
"($it)"
}
}
private const val TAG = "SystemDialogsManager"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment