Skip to content

Instantly share code, notes, and snippets.

@tir38
Last active May 18, 2018 16:03
Show Gist options
  • Save tir38/fb9921e3ba733b4eb9706c1c54db19fa to your computer and use it in GitHub Desktop.
Save tir38/fb9921e3ba733b4eb9706c1c54db19fa to your computer and use it in GitHub Desktop.
Ugly attempt to Idle Espresso test until view is visible. DO NOT USE THIS. Code sample for discussion here: https://issuetracker.google.com/issues/79626762
package com.example.app.tests;
import android.support.test.espresso.IdlingResource;
import android.support.test.espresso.ViewFinder;
import android.support.test.espresso.ViewInteraction;
import android.util.Log;
import android.view.View;
import java.lang.reflect.Field;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
/**
* An implementation of {@link IdlingResource} that is idle until view (provided by viewId) is visible.
*/
public class IdleUntilVisibleIdlingResource implements IdlingResource {
private static final String TAG = IdleUntilVisibleIdlingResource.class.getSimpleName();
private ResourceCallback resourceCallback;
private final int viewId;
public IdleUntilVisibleIdlingResource(int viewId) {
this.viewId = viewId;
}
@Override
public String getName() {
return TAG;
}
@Override
public boolean isIdleNow() {
// i don't know what activity is current, so I can't just call findViewById()
View viewOfInterest;
try {
Field field = ViewInteraction.class.getDeclaredField("viewFinder");
field.setAccessible(true);
ViewInteraction viewInteraction = onView(withId(viewId));
ViewFinder viewFinder = (ViewFinder) field.get(viewInteraction);
viewOfInterest = viewFinder.getView();
} catch (IllegalAccessException | NoSuchFieldException e) {
Log.e(TAG, "Reflection failed", e);
// if reflection fails, just return false and eventually we'll hit our IdlingPolicy timeout
return false;
}
boolean isIdle = viewOfInterest != null && viewOfInterest.getVisibility() == View.VISIBLE;
if (isIdle) {
resourceCallback.onTransitionToIdle();
}
return isIdle;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback callback) {
resourceCallback = callback;
}
}
@RunWith(AndroidJUnit4.class)
public final class TestCases {
@Rule
public ActivityTestRule<IntroActivity> activityRule = new ActivityTestRule<>(IntroActivity.class);
@Before
public void setUp() {
IdlingRegistry.getInstance().register(new IdleUntilVisibleIdlingResource(R.id.some_view_of_interest));
}
@Test
public void someTest() {
// 1. test starts on Intro Activity
// 2. click on a button that navigates off IntroActivity and to a second, unknown activity
// 3. idle until some view is visible on the second activity; see setUp() method
// 4. do some view assertions on the second activity
// In step #3, I need to get access to this view. However because I don't know which activity is the current
// activity, I can't use findViewById(). So I use a hack to get the view directly from Espresso (which has
// already done most of the ugly/hacky/relfective work to get access to the view tree)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment