Espresso View.isEnabled() with IdlingResources

To wait for a given View to become enabled is not an integrated part of the Android testing library Espresso. One has to create custom IdlingResources in order to wait for a specific state to be reached.

This sample class waits for a View to be enabled before responding with being idle:


import android.support.test.espresso.IdlingResource;
import android.view.View;

/**
 * IdlingResource waiting until the given view is not enabled any more.<br>
 * Can easily be adapted to check for different view properties, like "isVisible", "isSelected", "isChecked", etc.
 * <p>
 * Sample usage:
 * </p><pre> * ViewEnabledIdlingResource idlingResource = new ViewEnabledIdlingResource(mActivityRule.getActivity().findViewById(R.id.buttonApp));
 * registerIdlingResources(idlingResource);
 * Espresso.registerIdlingResources(idlingResource);
 * // .. do something. View is now guaranteed to be enabled.
 * Espresso.unregisterIdlingResources(idlingResource);
 * </pre>
 */
public class ViewEnabledIdlingResource implements IdlingResource {
    private final View view;
    private ResourceCallback resourceCallback;

    public ViewEnabledIdlingResource(View view) {
        this.view = view;
    }

    @Override
    public String getName() {
        return ViewEnabledIdlingResource.class.getName() + ":" + view.getId();
    }

    @Override
    public boolean isIdleNow() {
        boolean idle = view.isEnabled();
        if (idle) {
            resourceCallback.onTransitionToIdle();
        }
        return idle;
    }

    @Override
    public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
        this.resourceCallback = resourceCallback;
    }
}

Usage Example:

@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
    @Rule
    public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class);

    @Test
    public void onButtonEnabled_labelUpdated() {
        ViewEnabledIdlingResource idlingResource 
            = new ViewEnabledIdlingResource(mActivityRule.getActivity().findViewById(R.id.button));
        Espresso.registerIdlingResources(idlingResource);
        onView(withId(R.id.label))
                .matches(withText("Updated Text!"));
        Espresso.unregisterIdlingResources(idlingResource);
    }
}