To have better control over our instrumentation tests, we've ended up writing ChromeDisabler
which will run every instrumentation test session, go into phone's Chrome settings and uninstall and disable Chrome, hence preventing it from auto-updating.
Ideally, Google should disable auto-updates for Firebase Test Lab images.
Usage:
class CustomTestRunner : AndroidJUnitRunner() {
override fun onStart() {
ChromeDisabler.disable()
super.onStart()
}
}
ChromeDisabler:
object ChromeDisabler {
private const val CHROME_APP_PACKAGE_NAME = "com.android.chrome"
private const val APPLICATION_DETAILS_SETTINGS_APP_PACKAGE_NAME = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
private const val WAIT_TIMEOUT_MILLIS = 5000L
private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
private val disableButton = device.findObject(UiSelector().textStartsWith("disable"))
private val uninstallButton = device.findObject(UiSelector().textStartsWith("uninstall"))
fun disable() {
device.pressHome()
launchSettingsActivityForChrome()
device.wait(Until.hasObject(By.pkg(APPLICATION_DETAILS_SETTINGS_APP_PACKAGE_NAME).depth(0)), WAIT_TIMEOUT_MILLIS)
when {
disableButton.exists() -> {
Timber.e("Stock $CHROME_APP_PACKAGE_NAME found")
disableApp(device)
}
uninstallButton.exists() -> {
Timber.e("Non-stock $CHROME_APP_PACKAGE_NAME found")
uninstallApp(device)
disableApp(device)
}
device.findObject(UiSelector().textStartsWith("enable")).exists() -> {
Timber.e("$CHROME_APP_PACKAGE_NAME is already disabled")
}
}
}
private fun launchSettingsActivityForChrome() {
val intent = Intent().apply {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
data = Uri.fromParts("package", CHROME_APP_PACKAGE_NAME, null)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
InstrumentationRegistry.getInstrumentation().targetContext.startActivity(intent)
}
private fun disableApp(device: UiDevice) {
Timber.e("Attempting to disable $CHROME_APP_PACKAGE_NAME")
try {
disableButton.click()
device.findObject(UiSelector().textStartsWith("disable app")).click()
Timber.e("Successfully disabled $CHROME_APP_PACKAGE_NAME")
} catch (exception: Exception) {
Timber.e("Failed to disable $CHROME_APP_PACKAGE_NAME, cause: $exception")
}
}
private fun uninstallApp(device: UiDevice) {
Timber.e("Attempting to uninstall $CHROME_APP_PACKAGE_NAME")
try {
uninstallButton.click()
device.findObject(UiSelector().textStartsWith("ok")).click()
Timber.e("Successfully uninstalled $CHROME_APP_PACKAGE_NAME")
} catch (exception: Exception) {
Timber.e("Failed to uninstall $CHROME_APP_PACKAGE_NAME, cause: $exception")
}
}
}