From 919c25111b708bdb7894253decc32db838b7bd1e Mon Sep 17 00:00:00 2001 From: Nikita Evdokimov Date: Mon, 9 Dec 2024 15:31:32 +0300 Subject: [PATCH] TECH: Consider a RootViewWithoutFocusException in a flaky safety --- .../RootViewWithoutFocusWrapperException.kt | 12 +++++++++++ .../internal/extensions/other/ThrowableExt.kt | 20 ++++++++++--------- .../kaspresso/params/FlakySafetyParams.kt | 4 +++- 3 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/exceptions/RootViewWithoutFocusWrapperException.kt diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/exceptions/RootViewWithoutFocusWrapperException.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/exceptions/RootViewWithoutFocusWrapperException.kt new file mode 100644 index 000000000..a2dec6c4f --- /dev/null +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/exceptions/RootViewWithoutFocusWrapperException.kt @@ -0,0 +1,12 @@ +package com.kaspersky.kaspresso.internal.exceptions + +import java.lang.RuntimeException + +/** + * A wrapper for a RootViewWithoutFocusException. It's needed because RootViewWithoutFocusException is a private class, + * so we have to use reflection to catch it and provide a user a sane way to control it. + * + * @see com.kaspersky.kaspresso.params.FlakySafetyParams.Companion.getDefaultAllowedExceptions + * @see com.kaspersky.kaspresso.internal.extensions.other.ThrowableExtKt.isAllowed + */ +class RootViewWithoutFocusWrapperException : RuntimeException() diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/extensions/other/ThrowableExt.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/extensions/other/ThrowableExt.kt index 2776f03a7..ffbc4d739 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/extensions/other/ThrowableExt.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/internal/extensions/other/ThrowableExt.kt @@ -1,6 +1,7 @@ package com.kaspersky.kaspresso.internal.extensions.other import com.kaspersky.kaspresso.internal.exceptions.KaspressoError +import com.kaspersky.kaspresso.internal.exceptions.RootViewWithoutFocusWrapperException import io.reactivex.exceptions.ExtCompositeException internal inline fun invokeSafely( @@ -44,15 +45,16 @@ internal fun List.throwAll() { * @return true if the given throwable is contained by [allowed] set, false otherwise. */ internal fun T.isAllowed(allowed: Set>): Boolean { - return when (this) { - is ExtCompositeException -> { - exceptions.find { e: Throwable -> - allowed.find { it.isAssignableFrom(e.javaClass) } != null - } != null - } - else -> { - allowed.find { it.isAssignableFrom(javaClass) } != null - } + return when { + javaClass.simpleName == "RootViewWithoutFocusException" -> allowed.find { + it.isAssignableFrom(RootViewWithoutFocusWrapperException::class.java) // RootViewWithoutFocusException class is private, so we cannot access it directly + } != null + + this is ExtCompositeException -> exceptions.find { + e: Throwable -> allowed.find { it.isAssignableFrom(e.javaClass) } != null + } != null + + else -> allowed.find { it.isAssignableFrom(javaClass) } != null } } diff --git a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/params/FlakySafetyParams.kt b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/params/FlakySafetyParams.kt index 7bc601572..3ffa286d6 100644 --- a/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/params/FlakySafetyParams.kt +++ b/kaspresso/src/main/kotlin/com/kaspersky/kaspresso/params/FlakySafetyParams.kt @@ -4,6 +4,7 @@ import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.PerformException import androidx.test.uiautomator.StaleObjectException import com.kaspersky.components.kautomator.intercept.exception.UnfoundedUiObjectException +import com.kaspersky.kaspresso.internal.exceptions.RootViewWithoutFocusWrapperException import junit.framework.AssertionFailedError /** @@ -29,7 +30,8 @@ class FlakySafetyParams( AssertionFailedError::class.java, UnfoundedUiObjectException::class.java, StaleObjectException::class.java, - IllegalStateException::class.java + IllegalStateException::class.java, + RootViewWithoutFocusWrapperException::class.java, ) fun default() = FlakySafetyParams(