2

Can we get the current display activity in Espresso to write down some conditional code accordingly?

In my application we have an Introduction page which display user only once from the next application directly take user to login screen. Can we check on which screen user landed so we can write down our test case accordingly.

Krishnakant
  • 1,453
  • 3
  • 18
  • 30

2 Answers2

2

You can put an unique ID in the layout we have to check. In the example you described I would put in the login layout:

<RelativeLayout ...
    android:id="@+id/loginWrapper"
 ...

Then, in the test you only have to check that this Id is displayed:

onView(withId(R.id.loginWrapper)).check(matches(isCompletelyDisplayed()));

I don't know if there is a better way but this one works.

And you can also wait for some time with the waitId method you can find online:

/**
 * Perform action of waiting for a specific view id.
 * <p/>
 * E.g.:
 * onView(isRoot()).perform(waitId(R.id.dialogEditor, Sampling.SECONDS_15));
 *
 * @param viewId
 * @param millis
 * @return
 */
public static ViewAction waitId(final int viewId, final long millis) {
    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return isRoot();
        }

        @Override
        public String getDescription() {
            return "wait for a specific view with id <" + viewId + "> during " + millis + " millis.";
        }

        @Override
        public void perform(final UiController uiController, final View view) {
            uiController.loopMainThreadUntilIdle();
            final long startTime = System.currentTimeMillis();
            final long endTime = startTime + millis;
            final Matcher<View> viewMatcher = withId(viewId);

            do {
                for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
                    // found view with required ID
                    if (viewMatcher.matches(child)) {
                        return;
                    }
                }

                uiController.loopMainThreadForAtLeast(50);
            }
            while (System.currentTimeMillis() < endTime);

            // timeout happens
            throw new PerformException.Builder()
                .withActionDescription(this.getDescription())
                .withViewDescription(HumanReadables.describe(view))
                .withCause(new TimeoutException())
                .build();
        }
    };
}

With this method you can do for example:

onView(isRoot()).perform(waitId(R.id.loginWrapper, 5000));

And this way the test will not fail if the login screen takes 5 seconds or less to appear.

jeprubio
  • 17,312
  • 5
  • 45
  • 56
0

in my Espresso test classes I use ActivityTestRule, so to get current Activity I use

mRule.getActivity()

Here's my example code:

@RunWith(AndroidJUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SettingsActivityTest {

    @Rule
    public ActivityTestRule<SettingsActivity> mRule = new ActivityTestRule<>(SettingsActivity.class);

    @Test
    public void checkIfToolbarIsProperlyDisplayed() throws InterruptedException {
        onView(withText(R.string.action_settings)).check(matches(withParent(withId(R.id.toolbar))));
        onView(withId(R.id.toolbar)).check(matches(isDisplayed()));

        Toolbar toolbar = (Toolbar) mRule.getActivity().findViewById(R.id.toolbar);
        assertTrue(toolbar.hasExpandedActionView());
    }
}

Hope it will help

piotrek1543
  • 19,130
  • 7
  • 81
  • 94