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

Popular posts from this blog

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -

javascript - oscilloscope of speaker input stops rendering after a few seconds -