You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iceraven-browser/app/src/androidTest/java/org/mozilla/fenix/helpers/RetryTestRule.kt

101 lines
4.5 KiB
Kotlin

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.helpers
import android.util.Log
import androidx.test.espresso.IdlingResourceTimeoutException
import androidx.test.espresso.NoMatchingViewException
import androidx.test.uiautomator.UiObjectNotFoundException
import junit.framework.AssertionFailedError
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.IdlingResourceHelper.unregisterAllIdlingResources
import org.mozilla.fenix.helpers.TestHelper.exitMenu
/**
* Rule to retry flaky tests for a given number of times, catching some of the more common exceptions.
* The Rule doesn't clear the app state in between retries, so we are doing some cleanup here.
* The @Before and @After methods are not called between retries.
*
*/
class RetryTestRule(private val retryCount: Int = 5) : TestRule {
@Suppress("TooGenericExceptionCaught", "ComplexMethod")
override fun apply(base: Statement, description: Description): Statement {
return statement {
for (i in 1..retryCount) {
try {
Log.i(TAG, "RetryTestRule: Started try #$i.")
base.evaluate()
break
} catch (t: AssertionError) {
Log.i(TAG, "RetryTestRule: AssertionError caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
} catch (t: AssertionFailedError) {
Log.i(TAG, "RetryTestRule: AssertionFailedError caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
} catch (t: UiObjectNotFoundException) {
Log.i(TAG, "RetryTestRule: UiObjectNotFoundException caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
} catch (t: NoMatchingViewException) {
Log.i(TAG, "RetryTestRule: NoMatchingViewException caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
} catch (t: IdlingResourceTimeoutException) {
Log.i(TAG, "RetryTestRule: IdlingResourceTimeoutException caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
} catch (t: RuntimeException) {
Log.i(TAG, "RetryTestRule: RuntimeException caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
} catch (t: NullPointerException) {
Log.i(TAG, "RetryTestRule: NullPointerException caught, retrying the UI test")
unregisterAllIdlingResources()
exitMenu()
if (i == retryCount) {
Log.i(TAG, "RetryTestRule: Max numbers of retries reached.")
throw t
}
}
}
}
}
private inline fun statement(crossinline eval: () -> Unit): Statement {
return object : Statement() {
override fun evaluate() = eval()
}
}
}