Skip to content

Commit

Permalink
Faced missing displayed views in Espresso tests
Browse files Browse the repository at this point in the history
They seem to only depends on MaterialDialog timings...
I'd like to avoid writing code in packaged classes just to manage timing as Idling Resources or BusyBee require.
  • Loading branch information
federicoiosue committed Aug 4, 2020
1 parent 0f78b8c commit cfbdbc4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,37 @@
package it.feio.android.omninotes.ui;


import static androidx.test.espresso.Espresso.onData;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo;
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;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.is;

import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import androidx.core.view.GravityCompat;
import androidx.test.espresso.PerformException;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
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.rule.ActivityTestRule;
import it.feio.android.omninotes.BaseAndroidTestCase;
import it.feio.android.omninotes.MainActivity;
import it.feio.android.omninotes.R;
import java.util.concurrent.TimeoutException;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
Expand Down Expand Up @@ -129,4 +134,48 @@ void navigateUpSettings () {
1), isDisplayed())).perform(click());
}

/**
* Perform action of waiting for a specific view id.
* @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)) {
if (viewMatcher.matches(child)) {
return;
}
}

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

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
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.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
Expand All @@ -44,7 +45,6 @@
import androidx.appcompat.widget.AppCompatImageView;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.LargeTest;
import it.feio.android.omninotes.R;
import java.util.Calendar;
Expand Down Expand Up @@ -77,9 +77,11 @@ public void addNewCategory () throws InterruptedException {
onView(allOf(withId(R.id.menu_category), withContentDescription(R.string.category), isDisplayed())).perform(
click());

// Materialdialog "Add Category"
onView(isRoot()).perform(waitId(R.id.md_buttonDefaultPositive, 5000));

onView((withText(R.string.add_category))).perform(click());

sleep(1000);
onView(withId(R.id.category_title)).perform(replaceText(categoryName), closeSoftKeyboard());

onView(allOf(withId(R.id.save), withText("Ok"), isDisplayed())).perform(click());
Expand All @@ -97,11 +99,9 @@ public void addNewCategory () throws InterruptedException {
onView(allOf(withContentDescription(R.string.drawer_open),
withParent(withId(R.id.toolbar)),
isDisplayed())).perform(click());

}

@Test
@FlakyTest(detail = "Fixme with Idling Resources or BusyBee") // FIXME
public void checkCategoryCreation () throws InterruptedException {

addNewCategory();
Expand Down Expand Up @@ -157,11 +157,9 @@ public void categoryColorChange () throws InterruptedException {

onView(allOf(withId(R.id.color_chooser), isDisplayed())).check(
matches(withBackgroundColor(Color.parseColor("#FF263238"))));

}

@Test
@FlakyTest(detail = "Fixme with Idling Resources or BusyBee") // FIXME
public void categoryDeletion () throws InterruptedException {

addNewCategory();
Expand Down

0 comments on commit cfbdbc4

Please sign in to comment.