ci: Instrumentation tests coverage in ci.
All checks were successful
Check PR code / BuildAndTestAndCoverage (pull_request) Successful in 41m45s
All checks were successful
Check PR code / BuildAndTestAndCoverage (pull_request) Successful in 41m45s
This commit is contained in:
parent
1b2e9edc8c
commit
8a7743a6fb
@ -28,13 +28,6 @@ jobs:
|
|||||||
- name: run selfoss
|
- name: run selfoss
|
||||||
run: |
|
run: |
|
||||||
docker compose -f .gitea/workflows/assets/docker-compose.yml up -d
|
docker compose -f .gitea/workflows/assets/docker-compose.yml up -d
|
||||||
# https://github.com/ReactiveCircus/android-emulator-runner/issues/385
|
|
||||||
- name: Kill crashpad_handler processes
|
|
||||||
if: always()
|
|
||||||
run: |
|
|
||||||
pkill -SIGTERM crashpad_handler || true
|
|
||||||
sleep 5
|
|
||||||
pkill -SIGKILL crashpad_handler || true
|
|
||||||
- name: Change url until I find a better way to do it
|
- name: Change url until I find a better way to do it
|
||||||
run: |
|
run: |
|
||||||
sed -i "s/val defaultUrl = \"http:\/\/10\.0\.2\.2\:8888\"/val defaultUrl = \"http:\/\/172\.17\.0\.1\:8888\"/g" ./androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/CommonTests.kt
|
sed -i "s/val defaultUrl = \"http:\/\/10\.0\.2\.2\:8888\"/val defaultUrl = \"http:\/\/172\.17\.0\.1\:8888\"/g" ./androidApp/src/androidTest/kotlin/bou/amine/apps/readerforselfossv2/android/CommonTests.kt
|
||||||
@ -42,13 +35,14 @@ jobs:
|
|||||||
uses: reactivecircus/android-emulator-runner@v2
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
with:
|
with:
|
||||||
api-level: 29
|
api-level: 29
|
||||||
|
profile: pixel_2
|
||||||
script: |
|
script: |
|
||||||
./gradlew androidApp:clearScreenshotsTask || true
|
./gradlew androidApp:clearScreenshotsTask || true
|
||||||
./gradlew androidApp:createScreenshotDirectory
|
./gradlew androidApp:createScreenshotDirectory
|
||||||
adb logcat -G 16M
|
adb logcat -G 16M
|
||||||
./gradlew JacocoDebugCodeCoverage || true
|
./gradlew JacocoDebugCodeCoverage || true
|
||||||
./gradlew androidApp:fetchScreenshots
|
./gradlew androidApp:fetchScreenshots
|
||||||
adb logcat 'InputReader:S' 'chatty:S' 'audio_hw_generic:S' '*:I' -d > ./androidApp/build/reports/androidTests/connected/screenshots/logs.txt
|
adb logcat 'InputReader:S' 'chatty:S' 'audio_hw_generic:S' 'LogApiCalls:D' '*:I' -d > ./androidApp/build/reports/androidTests/connected/screenshots/logs.txt
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
|
@ -93,5 +93,6 @@ class `1-LoginActivityTest` : WithANRException() {
|
|||||||
performLogin()
|
performLogin()
|
||||||
onView(withText(R.string.gdpr_dialog_title)).check(matches(isDisplayed()))
|
onView(withText(R.string.gdpr_dialog_title)).check(matches(isDisplayed()))
|
||||||
onView(withText("OK")).perform(click())
|
onView(withText("OK")).perform(click())
|
||||||
|
checkHomeLoadingDone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android
|
package bou.amine.apps.readerforselfossv2.android
|
||||||
|
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
@ -14,7 +15,9 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import org.hamcrest.CoreMatchers.not
|
import org.hamcrest.CoreMatchers.not
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.FixMethodOrder
|
import org.junit.FixMethodOrder
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -29,6 +32,14 @@ class `2-HomeActivityTest` : WithANRException() {
|
|||||||
@get:Rule
|
@get:Rule
|
||||||
val activityRule = ActivityScenarioRule(HomeActivity::class.java)
|
val activityRule = ActivityScenarioRule(HomeActivity::class.java)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun registerIdlingResource() {
|
||||||
|
IdlingRegistry
|
||||||
|
.getInstance()
|
||||||
|
.register(CountingIdlingResourceSingleton.countingIdlingResource)
|
||||||
|
checkHomeLoadingDone()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMenu() {
|
fun testMenu() {
|
||||||
onView(withId(R.id.action_search)).check(matches(isDisplayed())).check(
|
onView(withId(R.id.action_search)).check(matches(isDisplayed())).check(
|
||||||
|
@ -2,14 +2,17 @@ package bou.amine.apps.readerforselfossv2.android
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isSelected
|
import androidx.test.espresso.matcher.ViewMatchers.isSelected
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
import org.hamcrest.CoreMatchers.not
|
import org.hamcrest.CoreMatchers.not
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -31,6 +34,9 @@ class `3-SettingsActivityTest` : WithANRException() {
|
|||||||
activityRule.scenario.onActivity { activity ->
|
activityRule.scenario.onActivity { activity ->
|
||||||
context = activity.window.context
|
context = activity.window.context
|
||||||
}
|
}
|
||||||
|
IdlingRegistry
|
||||||
|
.getInstance()
|
||||||
|
.register(CountingIdlingResourceSingleton.countingIdlingResource)
|
||||||
openMenu()
|
openMenu()
|
||||||
onView(withText(R.string.title_activity_settings)).perform(click())
|
onView(withText(R.string.title_activity_settings)).perform(click())
|
||||||
}
|
}
|
||||||
@ -91,6 +97,7 @@ class `3-SettingsActivityTest` : WithANRException() {
|
|||||||
@Test
|
@Test
|
||||||
fun testAbout() {
|
fun testAbout() {
|
||||||
onView(withText(R.string.action_about)).perform(click())
|
onView(withText(R.string.action_about)).perform(click())
|
||||||
|
onView(isRoot()).perform(waitUntilShown("ACRA", 30000))
|
||||||
onView(withText("ACRA")).check(matches(isDisplayed()))
|
onView(withText("ACRA")).check(matches(isDisplayed()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package bou.amine.apps.readerforselfossv2.android
|
|||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||||
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.action.ViewActions.replaceText
|
import androidx.test.espresso.action.ViewActions.replaceText
|
||||||
@ -19,6 +20,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
import org.hamcrest.CoreMatchers.not
|
import org.hamcrest.CoreMatchers.not
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -38,6 +40,9 @@ class `4-SettingsActivityGeneralTest` : WithANRException() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun init() {
|
fun init() {
|
||||||
|
IdlingRegistry
|
||||||
|
.getInstance()
|
||||||
|
.register(CountingIdlingResourceSingleton.countingIdlingResource)
|
||||||
openActionBarOverflowOrOptionsMenu(
|
openActionBarOverflowOrOptionsMenu(
|
||||||
ApplicationProvider.getApplicationContext(),
|
ApplicationProvider.getApplicationContext(),
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.android
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
@ -13,6 +14,7 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
import org.hamcrest.CoreMatchers.not
|
import org.hamcrest.CoreMatchers.not
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -35,6 +37,9 @@ class `5-SettingsActivityReaderTest` : WithANRException() {
|
|||||||
activityRule.scenario.onActivity { activity ->
|
activityRule.scenario.onActivity { activity ->
|
||||||
context = activity.window.context
|
context = activity.window.context
|
||||||
}
|
}
|
||||||
|
IdlingRegistry
|
||||||
|
.getInstance()
|
||||||
|
.register(CountingIdlingResourceSingleton.countingIdlingResource)
|
||||||
onView(withText(R.string.pref_header_viewer)).perform(click())
|
onView(withText(R.string.pref_header_viewer)).perform(click())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.android
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
@ -15,6 +16,7 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
import org.hamcrest.CoreMatchers.not
|
import org.hamcrest.CoreMatchers.not
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
@ -37,6 +39,9 @@ class `6-SettingsActivityOfflineTest` : WithANRException() {
|
|||||||
activityRule.scenario.onActivity { activity ->
|
activityRule.scenario.onActivity { activity ->
|
||||||
context = activity.window.context
|
context = activity.window.context
|
||||||
}
|
}
|
||||||
|
IdlingRegistry
|
||||||
|
.getInstance()
|
||||||
|
.register(CountingIdlingResourceSingleton.countingIdlingResource)
|
||||||
onView(withText(R.string.pref_header_offline)).perform(click())
|
onView(withText(R.string.pref_header_offline)).perform(click())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.android
|
|||||||
|
|
||||||
import androidx.test.espresso.AmbiguousViewMatcherException
|
import androidx.test.espresso.AmbiguousViewMatcherException
|
||||||
import androidx.test.espresso.Espresso.onView
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.action.ViewActions
|
import androidx.test.espresso.action.ViewActions
|
||||||
import androidx.test.espresso.action.ViewActions.click
|
import androidx.test.espresso.action.ViewActions.click
|
||||||
import androidx.test.espresso.action.ViewActions.swipeDown
|
import androidx.test.espresso.action.ViewActions.swipeDown
|
||||||
@ -14,6 +15,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -32,6 +34,9 @@ class `7-SourcesActivityTest` : WithANRException() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun init() {
|
fun init() {
|
||||||
|
IdlingRegistry
|
||||||
|
.getInstance()
|
||||||
|
.register(CountingIdlingResourceSingleton.countingIdlingResource)
|
||||||
sourceName = UUID.randomUUID().toString().substring(0, 15)
|
sourceName = UUID.randomUUID().toString().substring(0, 15)
|
||||||
|
|
||||||
goToSources()
|
goToSources()
|
||||||
|
@ -15,6 +15,7 @@ import androidx.test.espresso.action.ViewActions.typeTextIntoFocusedView
|
|||||||
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
|
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
import androidx.test.espresso.base.DefaultFailureHandler
|
import androidx.test.espresso.base.DefaultFailureHandler
|
||||||
|
import androidx.test.espresso.matcher.RootMatchers.isDialog
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
import androidx.test.espresso.matcher.ViewMatchers.isChecked
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
|
||||||
@ -24,6 +25,7 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
|||||||
import androidx.test.uiautomator.UiDevice
|
import androidx.test.uiautomator.UiDevice
|
||||||
import androidx.test.uiautomator.UiSelector
|
import androidx.test.uiautomator.UiSelector
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
|
import org.hamcrest.CoreMatchers.not
|
||||||
import org.hamcrest.Matchers.hasToString
|
import org.hamcrest.Matchers.hasToString
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
@ -139,6 +141,10 @@ fun testAddSourceWithUrl(
|
|||||||
onView(withText(sourceName)).check(matches(isDisplayed()))
|
onView(withText(sourceName)).check(matches(isDisplayed()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkHomeLoadingDone() {
|
||||||
|
onView(withId(R.id.swipeRefreshLayout)).inRoot(not(isDialog())).perform(waitForRecyclerViewToStopLoading(300000))
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
||||||
open class WithANRException {
|
open class WithANRException {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -8,22 +8,32 @@ import android.widget.RelativeLayout
|
|||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
|
||||||
|
import androidx.test.espresso.PerformException
|
||||||
import androidx.test.espresso.Root
|
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.RootMatchers.isPlatformPopup
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
|
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withChild
|
import androidx.test.espresso.matcher.ViewMatchers.withChild
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withParent
|
import androidx.test.espresso.matcher.ViewMatchers.withParent
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withResourceName
|
import androidx.test.espresso.matcher.ViewMatchers.withResourceName
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
|
import androidx.test.espresso.util.HumanReadables
|
||||||
|
import androidx.test.espresso.util.TreeIterables
|
||||||
import org.hamcrest.CoreMatchers.allOf
|
import org.hamcrest.CoreMatchers.allOf
|
||||||
|
import org.hamcrest.CoreMatchers.any
|
||||||
import org.hamcrest.Description
|
import org.hamcrest.Description
|
||||||
import org.hamcrest.Matcher
|
import org.hamcrest.Matcher
|
||||||
import org.hamcrest.Matchers
|
import org.hamcrest.Matchers
|
||||||
import org.hamcrest.TypeSafeMatcher
|
import org.hamcrest.TypeSafeMatcher
|
||||||
|
import java.util.concurrent.TimeoutException
|
||||||
|
|
||||||
fun withError(
|
fun withError(
|
||||||
@StringRes id: Int,
|
@StringRes id: Int,
|
||||||
@ -44,6 +54,86 @@ fun withError(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun waitUntilShown(
|
||||||
|
viewText: String,
|
||||||
|
millis: Long,
|
||||||
|
): ViewAction {
|
||||||
|
return object : ViewAction {
|
||||||
|
override fun getConstraints(): Matcher<View> = isRoot()
|
||||||
|
|
||||||
|
override fun getDescription(): String = "wait for $millis millis, for a specific view with text <$viewText> to be visible."
|
||||||
|
|
||||||
|
override fun perform(
|
||||||
|
uiController: UiController,
|
||||||
|
view: View,
|
||||||
|
) {
|
||||||
|
uiController.loopMainThreadUntilIdle()
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
val endTime = startTime + millis
|
||||||
|
val viewMatcher = withText(viewText)
|
||||||
|
|
||||||
|
do {
|
||||||
|
for (child in TreeIterables.breadthFirstViewTraversal(view)) {
|
||||||
|
if (viewMatcher.matches(child) && child.isShown) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uiController.loopMainThreadForAtLeast(100)
|
||||||
|
} while (System.currentTimeMillis() < endTime)
|
||||||
|
|
||||||
|
// timeout happens
|
||||||
|
throw PerformException
|
||||||
|
.Builder()
|
||||||
|
.withActionDescription(this.description)
|
||||||
|
.withViewDescription(HumanReadables.describe(view))
|
||||||
|
.withCause(TimeoutException())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun waitForRecyclerViewToStopLoading(millis: Long): ViewAction {
|
||||||
|
return object : ViewAction {
|
||||||
|
override fun getConstraints(): Matcher<View> = any(View::class.java)
|
||||||
|
|
||||||
|
override fun getDescription(): String = "wait for $millis millis for the recyclerview to stop loading."
|
||||||
|
|
||||||
|
override fun perform(
|
||||||
|
uiController: UiController,
|
||||||
|
view: View?,
|
||||||
|
) {
|
||||||
|
uiController.loopMainThreadUntilIdle()
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
val endTime = startTime + millis
|
||||||
|
|
||||||
|
do {
|
||||||
|
// either the empty view is displayed
|
||||||
|
for (child in TreeIterables.breadthFirstViewTraversal(view)) {
|
||||||
|
// found view with required ID
|
||||||
|
if (withId(R.id.emptyText).matches(child) && child.isVisible) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// or the refresh layout is refreshing
|
||||||
|
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<Root> = isPlatformPopup()
|
fun isPopupWindow(): Matcher<Root> = isPlatformPopup()
|
||||||
|
|
||||||
fun withDrawable(
|
fun withDrawable(
|
||||||
|
@ -310,6 +310,7 @@ class LoginActivity :
|
|||||||
.withAboutSpecial2Description(AppSettingsService.BUG_URL)
|
.withAboutSpecial2Description(AppSettingsService.BUG_URL)
|
||||||
.withAboutSpecial1("Project Page")
|
.withAboutSpecial1("Project Page")
|
||||||
.withAboutSpecial1Description(AppSettingsService.SOURCE_URL)
|
.withAboutSpecial1Description(AppSettingsService.SOURCE_URL)
|
||||||
|
.withShowLoadingProgress(false)
|
||||||
.start(this)
|
.start(this)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ class SourcesActivity :
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
CountingIdlingResourceSingleton.increment()
|
||||||
val mLayoutManager = LinearLayoutManager(this)
|
val mLayoutManager = LinearLayoutManager(this)
|
||||||
|
|
||||||
var items: ArrayList<SelfossModel.SourceDetail>
|
var items: ArrayList<SelfossModel.SourceDetail>
|
||||||
@ -57,7 +58,6 @@ class SourcesActivity :
|
|||||||
binding.recyclerView.setHasFixedSize(true)
|
binding.recyclerView.setHasFixedSize(true)
|
||||||
binding.recyclerView.layoutManager = mLayoutManager
|
binding.recyclerView.layoutManager = mLayoutManager
|
||||||
|
|
||||||
CountingIdlingResourceSingleton.increment()
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val response = repository.getSourcesDetails()
|
val response = repository.getSourcesDetails()
|
||||||
CountingIdlingResourceSingleton.increment()
|
CountingIdlingResourceSingleton.increment()
|
||||||
|
@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.UpsertSourceActivity
|
import bou.amine.apps.readerforselfossv2.android.UpsertSourceActivity
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBinding
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
@ -104,8 +105,10 @@ class SourcesListAdapter(
|
|||||||
source: SelfossModel.SourceDetail,
|
source: SelfossModel.SourceDetail,
|
||||||
position: Int,
|
position: Int,
|
||||||
) {
|
) {
|
||||||
|
CountingIdlingResourceSingleton.increment()
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val successfullyDeletedSource = repository.deleteSource(source.id, source.title)
|
val successfullyDeletedSource = repository.deleteSource(source.id, source.title)
|
||||||
|
CountingIdlingResourceSingleton.increment()
|
||||||
launch(Dispatchers.Main) {
|
launch(Dispatchers.Main) {
|
||||||
if (successfullyDeletedSource) {
|
if (successfullyDeletedSource) {
|
||||||
items.removeAt(position)
|
items.removeAt(position)
|
||||||
@ -119,7 +122,9 @@ class SourcesListAdapter(
|
|||||||
Toast.LENGTH_SHORT,
|
Toast.LENGTH_SHORT,
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
|
CountingIdlingResourceSingleton.decrement()
|
||||||
}
|
}
|
||||||
|
CountingIdlingResourceSingleton.decrement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import android.view.ViewGroup
|
|||||||
import bou.amine.apps.readerforselfossv2.android.HomeActivity
|
import bou.amine.apps.readerforselfossv2.android.HomeActivity
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.testing.CountingIdlingResourceSingleton
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.imageIntoViewTarget
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.imageIntoViewTarget
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.maybeIfContext
|
import bou.amine.apps.readerforselfossv2.android.utils.maybeIfContext
|
||||||
@ -59,12 +60,14 @@ class FilterSheetFragment :
|
|||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
CountingIdlingResourceSingleton.increment()
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
handleTagChips()
|
handleTagChips()
|
||||||
handleSourceChips()
|
handleSourceChips()
|
||||||
|
|
||||||
binding.progressBar2.visibility = GONE
|
binding.progressBar2.visibility = GONE
|
||||||
binding.filterView.visibility = VISIBLE
|
binding.filterView.visibility = VISIBLE
|
||||||
|
CountingIdlingResourceSingleton.decrement()
|
||||||
}
|
}
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
dismiss()
|
dismiss()
|
||||||
|
@ -124,6 +124,7 @@ class SettingsActivity :
|
|||||||
LibsBuilder()
|
LibsBuilder()
|
||||||
.withAboutIconShown(true)
|
.withAboutIconShown(true)
|
||||||
.withAboutVersionShown(true)
|
.withAboutVersionShown(true)
|
||||||
|
.withShowLoadingProgress(false)
|
||||||
.start(it)
|
.start(it)
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user