From 663ae683909b80994f62d904e5c35c4a6ac5fc8b Mon Sep 17 00:00:00 2001 From: Amine Date: Tue, 25 Mar 2025 13:36:35 +0100 Subject: [PATCH] ci: Instrumentation tests coverage in ci. --- .../android/1-LoginActivityTest.kt | 1 + .../readerforselfossv2/android/Helpers.kt | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/1-LoginActivityTest.kt b/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/1-LoginActivityTest.kt index 2dea4a4..4542e8b 100644 --- a/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/1-LoginActivityTest.kt +++ b/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/1-LoginActivityTest.kt @@ -93,5 +93,6 @@ class `1-LoginActivityTest` : WithANRException() { performLogin() onView(withText(R.string.gdpr_dialog_title)).check(matches(isDisplayed())) onView(withText("OK")).perform(click()) + onView(withId(R.id.swipeRefreshLayout)).perform(waitUntilNotLoading(300000)) } } diff --git a/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/Helpers.kt b/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/Helpers.kt index 207afcf..68ebd38 100644 --- a/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/Helpers.kt +++ b/androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/Helpers.kt @@ -8,9 +8,13 @@ import android.widget.RelativeLayout import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.core.graphics.drawable.toBitmap +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu +import androidx.test.espresso.PerformException import androidx.test.espresso.Root +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction import androidx.test.espresso.matcher.RootMatchers.isPlatformPopup import androidx.test.espresso.matcher.ViewMatchers.hasSibling import androidx.test.espresso.matcher.ViewMatchers.withChild @@ -19,11 +23,14 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withParent import androidx.test.espresso.matcher.ViewMatchers.withResourceName import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.espresso.util.HumanReadables import org.hamcrest.CoreMatchers.allOf +import org.hamcrest.CoreMatchers.any import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.Matchers import org.hamcrest.TypeSafeMatcher +import java.util.concurrent.TimeoutException fun withError( @StringRes id: Int, @@ -44,6 +51,39 @@ fun withError( } } +fun waitUntilNotLoading(millis: Long): ViewAction { + return object : ViewAction { + override fun getConstraints(): Matcher = any(View::class.java) + + override fun getDescription(): String = "wait for a specific view is hidden during $millis millis." + + override fun perform( + uiController: UiController, + view: View?, + ) { + uiController.loopMainThreadUntilIdle() + val startTime = System.currentTimeMillis() + val endTime = startTime + millis + + do { + // found view with required ID + if (view is SwipeRefreshLayout && !view.isRefreshing) { + return + } + uiController.loopMainThreadForAtLeast(100) + } while (System.currentTimeMillis() < endTime) + + // timeout happens + throw PerformException + .Builder() + .withActionDescription(this.description) + .withViewDescription(HumanReadables.describe(view)) + .withCause(TimeoutException()) + .build() + } + } +} + fun isPopupWindow(): Matcher = isPlatformPopup() fun withDrawable(