Issue#125 Attampt to fix Compose Flakiness
This commit is contained in:
parent
b6b661b055
commit
fb411a6b71
2 changed files with 15 additions and 26 deletions
|
|
@ -3,15 +3,13 @@ package org.fnives.test.showcase.ui
|
||||||
import androidx.compose.ui.test.MainTestClock
|
import androidx.compose.ui.test.MainTestClock
|
||||||
import androidx.compose.ui.test.junit4.StateRestorationTester
|
import androidx.compose.ui.test.junit4.StateRestorationTester
|
||||||
import androidx.compose.ui.test.junit4.createComposeRule
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
import androidx.test.espresso.IdlingRegistry
|
import androidx.test.espresso.Espresso
|
||||||
import androidx.test.espresso.IdlingResource
|
import androidx.test.espresso.matcher.ViewMatchers
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import org.fnives.test.showcase.R
|
import org.fnives.test.showcase.R
|
||||||
import org.fnives.test.showcase.android.testutil.intent.DismissSystemDialogsRule
|
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.screenshot.ScreenshotRule
|
||||||
import org.fnives.test.showcase.android.testutil.synchronization.idlingresources.anyResourceNotIdle
|
import org.fnives.test.showcase.android.testutil.viewaction.LoopMainThreadFor
|
||||||
import org.fnives.test.showcase.android.testutil.synchronization.idlingresources.awaitUntilIdle
|
|
||||||
import org.fnives.test.showcase.android.testutil.synchronization.loopMainThreadFor
|
|
||||||
import org.fnives.test.showcase.compose.screen.AppNavigation
|
import org.fnives.test.showcase.compose.screen.AppNavigation
|
||||||
import org.fnives.test.showcase.core.integration.fake.FakeUserDataLocalStorage
|
import org.fnives.test.showcase.core.integration.fake.FakeUserDataLocalStorage
|
||||||
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
|
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
|
||||||
|
|
@ -24,7 +22,6 @@ import org.junit.Test
|
||||||
import org.junit.rules.RuleChain
|
import org.junit.rules.RuleChain
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.koin.test.KoinTest
|
import org.koin.test.KoinTest
|
||||||
import java.util.concurrent.Executors
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class AuthComposeInstrumentedTest : KoinTest {
|
class AuthComposeInstrumentedTest : KoinTest {
|
||||||
|
|
@ -190,25 +187,7 @@ class AuthComposeInstrumentedTest : KoinTest {
|
||||||
* Await the idling resource on a different thread while looping main.
|
* Await the idling resource on a different thread while looping main.
|
||||||
*/
|
*/
|
||||||
fun MainTestClock.awaitIdlingResources() {
|
fun MainTestClock.awaitIdlingResources() {
|
||||||
val idlingRegistry = IdlingRegistry.getInstance()
|
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainThreadFor(100L))
|
||||||
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()
|
|
||||||
|
|
||||||
advanceTimeByFrame()
|
advanceTimeByFrame()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ class OkHttp3IdlingResource private constructor(
|
||||||
) : IdlingResource {
|
) : IdlingResource {
|
||||||
@Volatile
|
@Volatile
|
||||||
var callback: IdlingResource.ResourceCallback? = null
|
var callback: IdlingResource.ResourceCallback? = null
|
||||||
|
private var isIdleCallbackWasCalled: Boolean = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val currentCallback = dispatcher.idleCallback
|
val currentCallback = dispatcher.idleCallback
|
||||||
|
|
@ -24,12 +25,21 @@ class OkHttp3IdlingResource private constructor(
|
||||||
sleepForDispatcherDefaultCallInRetrofitErrorState()
|
sleepForDispatcherDefaultCallInRetrofitErrorState()
|
||||||
callback?.onTransitionToIdle()
|
callback?.onTransitionToIdle()
|
||||||
currentCallback?.run()
|
currentCallback?.run()
|
||||||
|
isIdleCallbackWasCalled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String = name
|
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?) {
|
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
|
||||||
this.callback = callback
|
this.callback = callback
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue