2015-06-10 10 views
5

W jaki sposób klikasz element menu w NavigationView z biblioteki projektu używając Espresso? Działa to dobrze na większych urządzeniach, gdzie całe menu jest widoczne, ale w poziomych lub mniejszych urządzeniach dno mojego menu jest poza ekranem i nie mogę znaleźć sposobu na przewinięcie/przesunięcie do tych elementów menu, więc mogę je kliknąć.Jak klikasz element menu w NavigationView na Androidzie podczas testów z Espresso?

numerem:

onView(withText(R.string.contact_us)).perform(scrollTo()).check(matches(isDisplayed())).perform(click()); 

generuje następujący:

Spowodowany przez: java.lang.RuntimeException: Działanie nie zostanie wykonane ponieważ widok target nie pasuje jedno lub więcej z po ograniczeniach : (widok ma efektywną widoczność = WIDOCZNY i jest potomkiem z: (można przypisać z klasy: klasa android.widget.ScrollView lub jest możliwe do przypisania z klasy: klasa android.widget.Horizon talScrollView)) Widok celu: "NawigacjaMenuItemView {id = -1, widoczność = WIDOCZNA, szerokość = 888, wysokość = 144, ma-fokus = fałsz, ma-fokus = fałsz, ma-okno-fokus = prawda, jest -clickable = false, is-enabled = true, is-focused = false, is-focusable = false, is-layout-requested = false, jest wybrany = false, root-jest-layout-requested = false, ma-input-connection = false, x = 0,0, y = 1653,0, text = Kontakt, input-type = 0, ime-target = false, HAS-linki = false}”

NavigationView dziedziczy FrameLayout i wykonują przesunięcie płótna do przewijania. https://developer.android.com/reference/android/support/design/widget/NavigationView.html

Próbowałem napisać customViewAction powoli przewinąć ekran za pomocą poniższego działania i sprawdzić czy MENUITEM jest widoczny, a jeśli nie zatrzymać przewijanie, ale nie mogę zmusić go do pracy.

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()); 

Czy ktoś wymyślił jak przetestować nawigacjęView na Espresso jeszcze? Jestem prawie pewien, że moja logika stojąca za niestandardową funkcjąViewView będzie działała, ale nie będę mógł jej uruchomić.

Odpowiedz

3

I zorientowaliśmy się, kiedyś zwyczaj 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 for a specific view with 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); 

       do { 
        boolean returnAfterOneMoreSwipe = false; //not sure why I have to do one more swipe but it works 

        for (View child : TreeIterables.breadthFirstViewTraversal(view)) { 
         // found view with 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 is c/p from 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 from 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(); 
      } 
     }; 
    } 

Nie kocham tego rozwiązania, to nie jest najczystszy, ponieważ z jakiegoś powodu muszę przesuń ponownie po to mówi jego widoczne, ale to działa .

Aby użyć go nazwać to z następujących powodów:

onView(isRoot()).perform(CustomViewActions.swipeForTextToBeVisible(getActivity().getString(R.string.contact_us),2000, getActivity().findViewById(R.id.navigation_view))); 
0

Musisz użyć Ekspres contrib:

import android.support.test.espresso.contrib.DrawerActions; 

Aby otworzyć menu, można to zrobić:

onView(withId(R.id.drawer_layout)).perform(DrawerActions.open()); 

Możesz przewinąć do pozycji menu i sprawdzić, czy jest ona wyświetlana:

onView(withId(R.id.my_menu_item)).perform(scrollTo()).check(matches(isDisplayed())); 

I kliknąć na menu:

onView(withId(R.id.my_menu_item)).perform(click()); 
1

ten pracował dla mnie, nawet jeśli pozycja menu nie był widoczny (gdzieś w dół listy)

OnView (withId (R.id. nav_view)). perform (NavigationViewActions.navigateTo (R.id.nav_login));

Powiązane problemy