How do you click a menuItem in NavigationView on Android when testing with Espresso? -
how click on menuitem in navigationview design library using espresso? works fine on larger devices whole menu visible in landscape or smaller devices bottom of menu off screen , can not figure out way scroll/swipe these menuitems can click on them.
calling:
onview(withtext(r.string.contact_us)).perform(scrollto()).check(matches(isdisplayed())).perform(click());
generates following:
caused by: java.lang.runtimeexception: action not performed because target view not match 1 or more of following constraints: (view has effective visibility=visible , descendant of a: (is assignable class: class android.widget.scrollview or assignable class: class android.widget.horizontalscrollview)) target view: "navigationmenuitemview{id=-1, visibility=visible, width=888, height=144, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=1653.0, text=contact us, input-type=0, ime-target=false, has-links=false}"
navigationview inherits framelayout , doing canvas shift scroll. https://developer.android.com/reference/android/support/design/widget/navigationview.html
i tried write customviewaction scroll screen using below action , check if menuitem visible , if not keep scrolling, not work.
coordinatesprovider coordinatesprovider = new coordinatesprovider() { public float[] calculatecoordinates(view view) { float[] xy = generallocation.bottom_center.calculatecoordinates(view); xy[0] += 0.0f * (float)view.getwidth(); xy[1] += -0.083f * (float)view.getheight(); return xy; } }; onview(withid(r.id.navigation_view)).perform(new generalswipeaction(swipe.slow, coordinatesprovider, generallocation.top_center, press.finger)); onview(withtext(r.string.contact_us)).check(matches(isdisplayed())).perform(click());
has figured out how test navigationview on espresso yet? pretty sure logic behind customviewaction work can not work.
i figured out, used custom viewaction
public static viewaction swipefortexttobevisible(final string text, final long millis, final view navigationview) { return new viewaction() { @override public matcher<view> getconstraints() { return isroot(); } @override public string getdescription() { return "swipe specific view text <" + text + "> 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 = withtext(text); { boolean returnafteronemoreswipe = false; //not sure why have 1 more swipe works (view child : treeiterables.breadthfirstviewtraversal(view)) { // found view required id if (viewmatcher.matches(child) && child.getvisibility() == view.visible) { returnafteronemoreswipe = true; } } coordinatesprovider coordinatesprovider = new coordinatesprovider() { public float[] calculatecoordinates(view view) { float[] xy = generallocation.bottom_center.calculatecoordinates(view); xy[0] += 0.0f * (float)view.getwidth(); xy[1] += -0.083f * (float)view.getheight(); return xy; } }; //below code c/p perform in android/support/test/espresso/action/generalswipeaction.class float[] startcoordinates = coordinatesprovider.calculatecoordinates(navigationview); float[] endcoordinates = generallocation.top_center.calculatecoordinates(navigationview); float[] precision = press.finger.describeprecision(); swiper.status status = swiper.status.failure; for(int tries = 0; tries < 3 && status != swiper.status.success; ++tries) { try { status = swipe.slow.sendswipe(uicontroller, startcoordinates, endcoordinates, precision); } catch (runtimeexception var9) { throw (new performexception.builder()).withactiondescription(this.getdescription()).withviewdescription(humanreadables.describe(navigationview)).withcause(var9).build(); } int duration = viewconfiguration.getpressedstateduration(); if(duration > 0) { uicontroller.loopmainthreadforatleast((long)duration); } } //end c/p android/support/test/espresso/action/generalswipeaction.class if (returnafteronemoreswipe) { 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(); } }; }
i not love solution, not cleanest since reason have swipe again after says visible works.
to use call following:
onview(isroot()).perform(customviewactions.swipefortexttobevisible(getactivity().getstring(r.string.contact_us),2000, getactivity().findviewbyid(r.id.navigation_view)));
Comments
Post a Comment