Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing action while app not idle in Espresso - Android

A lot of people have asked how to get the Espresso framework to wait for a background task to be finished before performing an action or asserting something. I understand that in those situations, IdlingResource is often the answer.

My question is sort of the opposite. I have a countdown that Espresso waits for by default because a ProgressBar gets updated. During this countdown, I have a sort of "Cancel" button to stop the countdown.

The test I want to write will set up the background task and check that cancel button takes the app back to the previous screen. Right now it waits for the background task to finish before trying to click the cancel button but the cancel button disappears after the task is done.

How would I "force" Espresso to perform an action (click the cancel), even though the app is not idle?

like image 308
ArbiterBo Avatar asked Sep 25 '17 21:09

ArbiterBo


1 Answers

To be honest with you, I don't think it is possible. I had the same problem. I fixed it by using UIAutomator to click the (in your case) cancel button.

In my case I had a login button, after which there's a map. The app is never idle after the Login button or even just in the MapFragment (Problem for Espresso), so I had to use UIAutomator for the Login button and to check if the map comes up after logging in.

I popped this into the app's dependencies:

androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'

And in my LoginTest.kt file:

import androidx.test.uiautomator.*
//your imports here

@RunWith(AndroidJUnit4::class)
@LargeTest
class LoginTest {
    @Rule
    @JvmField
    //your rules here
    lateinit var mDevice:UiDevice


    @Before
    fun setUp() {
        //your setUp stuff
        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

    }

    @Test
    fun checkLogin(){
        onView(withId(R.id.loginBtn)).perform(click())   //goes to LoginFragment

        mDevice.findObject(UiSelector().text("LOGIN")).click()   //clicks login button
        //this is where I had to use the UIAutomator because espresso would never be
        //idle after the login button

        mDevice.wait(Until.findObject(By.text("YOU HAVE LOGGED IN")),15000)
        //this waits until the object with the given text appears, max. wait time is 15 seconds
        //as espresso would still not be idle, I had to check if the login was successful 
        //with (again) the help of UIAutomator
    }

    @After
    fun tearDown() {

    }

}

hope this helps somebody

like image 74
L4ry Avatar answered Nov 15 '22 01:11

L4ry