Skip to content

Commit

Permalink
Wait for recyclerView to appear
Browse files Browse the repository at this point in the history
This is needed for NotEventsTest.agenda_MultipleWithTimes(), among
others.
  • Loading branch information
amberin committed Apr 11, 2024
1 parent 3035421 commit 463b377
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ class NoteEventsTest : OrgzlyTest() {

onNotesInAgenda().check(matches(recyclerViewItemCount(10)))

SystemClock.sleep(2000)

// Today: deadline
onItemInAgenda(1, R.id.item_head_scheduled_text).check(matches(not(isDisplayed())))
onItemInAgenda(1, R.id.item_head_deadline_text).check(matches(isDisplayed()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static com.orgzly.android.espresso.util.EspressoUtils.contextualToolbarOverflowMenu;
import static com.orgzly.android.espresso.util.EspressoUtils.onActionItemClick;
import static com.orgzly.android.espresso.util.EspressoUtils.onBook;
Expand All @@ -24,6 +25,7 @@
import static com.orgzly.android.espresso.util.EspressoUtils.replaceTextCloseKeyboard;
import static com.orgzly.android.espresso.util.EspressoUtils.scroll;
import static com.orgzly.android.espresso.util.EspressoUtils.searchForTextCloseKeyboard;
import static com.orgzly.android.espresso.util.EspressoUtils.waitId;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
Expand Down Expand Up @@ -264,6 +266,7 @@ public void testSchedulingNote() {
onView(withId(R.id.date_picker_button)).perform(click());
onView(withClassName(equalTo(DatePicker.class.getName()))).perform(setDate(2014, 4, 1));
onView(withText(android.R.string.ok)).perform(click());
onView(isRoot()).perform(waitId(R.id.time_picker_button, 5000));
onView(withId(R.id.time_picker_button)).perform(scroll(), click());
onView(withClassName(equalTo(TimePicker.class.getName()))).perform(setTime(9, 15));
onView(withText(android.R.string.ok)).perform(click());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.orgzly.android.espresso.util.EspressoUtils.onListItem;
import static com.orgzly.android.espresso.util.EspressoUtils.onSnackbar;
import static com.orgzly.android.espresso.util.EspressoUtils.replaceTextCloseKeyboard;
import static com.orgzly.android.espresso.util.EspressoUtils.scroll;
import static com.orgzly.android.espresso.util.EspressoUtils.waitId;

import androidx.test.core.app.ActivityScenario;

Expand Down Expand Up @@ -46,6 +48,7 @@ public void testDirectoryRepoWithPercentCharacter() {
ActivityScenario.launch(ReposActivity.class);

onView(withId(R.id.activity_repos_flipper)).check(matches(isDisplayed()));
onView(isRoot()).perform(waitId(R.id.activity_repos_directory, 5000));
onView(withId(R.id.activity_repos_directory)).perform(scroll(), click());
onView(withId(R.id.activity_repo_directory)).perform(replaceTextCloseKeyboard(repoUri));
onView(withId(R.id.fab)).perform(click()); // Repo done
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
Expand All @@ -33,12 +34,15 @@
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.DataInteraction;
import androidx.test.espresso.PerformException;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.action.CloseKeyboardAction;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.espresso.util.HumanReadables;
import androidx.test.espresso.util.TreeIterables;
import androidx.test.platform.app.InstrumentationRegistry;

import com.orgzly.R;
Expand All @@ -49,6 +53,8 @@
import org.hamcrest.Matchers;
import org.hamcrest.TypeSafeMatcher;

import java.util.concurrent.TimeoutException;

/*
* Few espresso-related notes:
*
Expand Down Expand Up @@ -179,8 +185,8 @@ public static ViewInteraction onSavedSearch(int position) {
}

public static ViewInteraction onRecyclerViewItem(@IdRes int recyclerView, int position, @IdRes int childView) {
onView(isRoot()).perform(waitId(recyclerView, 5000));
onView(withId(recyclerView)).perform(RecyclerViewActions.scrollToPosition(position));
SystemClock.sleep(500);
return onView(new EspressoRecyclerViewMatcher(recyclerView)
.atPositionOnView(position, childView));
}
Expand Down Expand Up @@ -447,4 +453,50 @@ public void perform(UiController uiController, View view) {
public static ViewAction scroll() {
return new NestedScrollViewExtension();
}

/**
* Perform action of waiting for a specific view id. Copied from https://stackoverflow.com/a/49814995.
* @param viewId The id of the view to wait for.
* @param millis The timeout of until when to wait for.
*/
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();
}
};
}
}

0 comments on commit 463b377

Please sign in to comment.