Issue#125 Attampt to fix Compose Flakiness

This commit is contained in:
Gergely Hegedus 2022-09-26 21:53:14 +03:00
parent b6b661b055
commit fb411a6b71
2 changed files with 15 additions and 26 deletions

View file

@ -3,15 +3,13 @@ package org.fnives.test.showcase.ui
import androidx.compose.ui.test.MainTestClock
import androidx.compose.ui.test.junit4.StateRestorationTester
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.IdlingResource
import androidx.test.espresso.Espresso
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.fnives.test.showcase.R
import org.fnives.test.showcase.android.testutil.intent.DismissSystemDialogsRule
import org.fnives.test.showcase.android.testutil.screenshot.ScreenshotRule
import org.fnives.test.showcase.android.testutil.synchronization.idlingresources.anyResourceNotIdle
import org.fnives.test.showcase.android.testutil.synchronization.idlingresources.awaitUntilIdle
import org.fnives.test.showcase.android.testutil.synchronization.loopMainThreadFor
import org.fnives.test.showcase.android.testutil.viewaction.LoopMainThreadFor
import org.fnives.test.showcase.compose.screen.AppNavigation
import org.fnives.test.showcase.core.integration.fake.FakeUserDataLocalStorage
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
@ -24,7 +22,6 @@ import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.runner.RunWith
import org.koin.test.KoinTest
import java.util.concurrent.Executors
@RunWith(AndroidJUnit4::class)
class AuthComposeInstrumentedTest : KoinTest {
@ -190,25 +187,7 @@ class AuthComposeInstrumentedTest : KoinTest {
* Await the idling resource on a different thread while looping main.
*/
fun MainTestClock.awaitIdlingResources() {
val idlingRegistry = IdlingRegistry.getInstance()
if (!anyResourceNotIdle()) return
val executor = Executors.newSingleThreadExecutor()
var isIdle = false
executor.submit {
do {
idlingRegistry.resources
.filterNot(IdlingResource::isIdleNow)
.forEach { idlingResource ->
idlingResource.awaitUntilIdle()
}
} while (!idlingRegistry.resources.all(IdlingResource::isIdleNow))
isIdle = true
}
while (!isIdle) {
loopMainThreadFor(200L)
}
executor.shutdown()
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadFor(100L))
advanceTimeByFrame()
}

View file

@ -17,6 +17,7 @@ class OkHttp3IdlingResource private constructor(
) : IdlingResource {
@Volatile
var callback: IdlingResource.ResourceCallback? = null
private var isIdleCallbackWasCalled: Boolean = true
init {
val currentCallback = dispatcher.idleCallback
@ -24,12 +25,21 @@ class OkHttp3IdlingResource private constructor(
sleepForDispatcherDefaultCallInRetrofitErrorState()
callback?.onTransitionToIdle()
currentCallback?.run()
isIdleCallbackWasCalled = true
}
}
override fun getName(): String = name
override fun isIdleNow(): Boolean = dispatcher.runningCallsCount() == 0
override fun isIdleNow(): Boolean {
val isIdle = dispatcher.runningCallsCount() == 0
if (isIdle) {
// sometime the callback is just not properly called it seems, or maybe sync error.
// if it isn't called Espresso crashes, so we add this here.
callback?.onTransitionToIdle()
}
return isIdle
}
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
this.callback = callback