Closed GoogleCodeExporter closed 9 years ago
"if onView is called immediately after the action perform(click()) then the
onView will fail since the new widget is not yet visible. "
I believe I've seen similar issues. I have a simple app that have view A and if
you swipe to the right you'll get to view B. On view B there's an extra button
on the action bar which is not presented on view A. If I run my espresso test
and swipe to view B then immediately uses onView() to try to match the button,
it'll fail. UI dump from the log would reveal that the button is not in the
view yet.
I didn't implement as complicated workaround as OP did. A simple
Thread.Sleep(1000) before the onView() call made the test pass.
I don't think onData is applicable here since there is no AdapterView. Neither
is registerIdelresouce as there's no background thread.
Original comment by lyfort...@gmail.com
on 24 Jan 2014 at 1:06
[deleted comment]
I found a little better way.
Pattern of use:
// wait during 15 seconds for a view
onView(isRoot()).perform(waitId(R.id.wizardNext, Sampling.SECONDS_15));
Required Action:
/** Perform action of waiting for a specific view id. */
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();
}
};
}
Original comment by kucheren...@gmail.com
on 21 Mar 2014 at 4:38
Thanks for this. I've improved it by taking any view matcher
public static ViewAction waitToFind(final Matcher<View> viewMatcher, final int
millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return "wait for a specific view with matcher <" + viewMatcher + "> 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;
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();
}
};
}
Though I'm sure this could be implemented in an IdlingResource and then
register it with Espresso
Original comment by zboa...@gmail.com
on 14 Apr 2014 at 4:00
I tried the solution above. But sometimes, I get the below error:
java.lang.RuntimeException: Action will not be performed because the target
view does not match one or more of the following constraints:
at least 90 percent of the view's area is displayed to the user.
I tried adding constraint like this:
if (viewMatcher.matches(child)&& viewMatcher.matches(isCompletelyDisplayed())
But this timed out. Clearly, suggesting that the function matches with the view
even if it is partially displayed.
Any suggestions for that.
Original comment by dikshago...@gmail.com
on 5 May 2014 at 1:19
The requested waitForView API breaks the Espresso API paradigm (i.e. everything
should be synchronized. The test author should not have to make a decision on
how long to wait for a view). For components that are not synchronized by
default, Espresso provides the IdlingResource interface. Please use it. It will
make your tests much cleaner and more dependable.
Some of you may also be hitting
https://code.google.com/p/android-test-kit/issues/detail?id=55. We will look
into improving this in the coming release.
Original comment by vale...@google.com
on 7 May 2014 at 6:33
Original issue reported on code.google.com by
marcp...@gmail.com
on 20 Jan 2014 at 8:36