【问题标题】:Espresso: How to do custom swipe e.g. swipeTop or swipeBottom意式浓缩咖啡:如何进行自定义刷卡。向上滑动或向下滑动
【发布时间】:2015-03-28 21:09:58
【问题描述】:

到目前为止,我们可以做到:

  • 向左滑动
  • 向右滑动
  • 向上滑动
  • 向下滑动

我们如何 swipeTop(一直到顶部)或 swipeBottom(一直到底部)是 expresso。如果这些方法已经存在,请举个例子。

【问题讨论】:

    标签: android android-espresso ui-testing


    【解决方案1】:

    你试过这样的GeneralSwipeAction吗?

    private static ViewAction swipeFromTopToBottom() {
        return new GeneralSwipeAction(Swipe.FAST, GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER, Press.FINGER);
    }
    

    也许您必须为第二个和/或第三个参数提供自定义实现,正如 Anna 已经提到的:

    new CoordinatesProvider() {
        @Override
        public float[] calculateCoordinates(View view) {
            float[] coordinates =  GeneralLocation.CENTER.calculateCoordinates(view);
            coordinates[1] = 0;
            return coordinates;
        }
    }
    

    【讨论】:

      【解决方案2】:

      例如,如果你在你的应用程序中使用 recyclerView,你可以使用这样的东西:

      Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeUp())
      

      Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeDown())
      

      【讨论】:

        【解决方案3】:

        我知道我迟到了,但经过一番摸索后,我终于找到了可以从上到下、从左到右等滑动的东西——不需要任何资源 ID。

        我需要它的原因是为了一个动态填充的视图,其中一切都完全模棱两可。使用下面的方法,我可以一直滚动到底部,甚至可以将延迟更改为仅向下滚动一页。

        static void swiper(int start, int end, int delay) {
            long downTime = SystemClock.uptimeMillis();
            long eventTime = SystemClock.uptimeMillis();
            Instrumentation inst = getInstrumentation();
        
            MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 500, start, 0);
            inst.sendPointerSync(event);
            eventTime = SystemClock.uptimeMillis() + delay;
            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 500, end, 0);
            inst.sendPointerSync(event);
            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, 500, end, 0);
            inst.sendPointerSync(event);
            SystemClock.sleep(2000); //The wait is important to scroll
        }
        

        我不需要从左到右等,所以我在那里硬编码了 500(500 是 x 轴)。

        为了打电话给他们,我做到了,我做到了 -

         // This swipes all the way to the bottom of the screen
        public static void swipeToBottom(){
            swiper(1000, 100, 0);
        }
        
        // This scrolls down one page at a time
        public static void scrollSlowlyDown(){
            swiper(775, 100, 100);
        }
        
        // This swipes to the top
        public static void swipeToTop(){
            swiper(100, 1000, 0);
        }
        
        // This scrolls up one page at a time
        public static void scrollSlowlyUp(){
            swiper(100, 775, 100);
        }
        

        我希望这可以帮助任何遇到此问题的人。

        【讨论】:

        • 不知道为什么我被否决了 - 这很好用
        • 不幸的是,在 targetSdk 26 上,在 Android 7 上运行会抛出:java.lang.SecurityException:注入另一个应用程序需要 INJECT_EVENTS 权限,该权限仅授予系统应用程序。
        【解决方案4】:

        @testsingh 我认为没有开箱即用的方法来执行“swipeTop”或“swipeBottom” 以下循环可能是对我有用的最简单的方法(最愚蠢的)XDDD

        //swipeUp 100 次,swipeDown 反之亦然

        for(int i=0;i<=100;i++){
          onView(withText("label")).perform(swipeUp());
        }
        

        【讨论】:

          【解决方案5】:

          我认为可以通过执行滑动来编写复杂的ViewActions 来完成。

          public static ViewAction swipeToTop() {
              return new MySwipeAction(Swipe.FAST,
                  GeneralLocation.CENTER,
                  new CoordinatesProvider() {
                      @Override
                      public float[] calculateCoordinates(View view) {
                          float[] coordinates =  GeneralLocation.CENTER.calculateCoordinates(view);
                          coordinates[1] = 0;
                          return coordinates;
                      }
              }, Press.FINGER);
          }
          
          
          public static ViewAction swipeToBottom() {
              return new MySwipeAction(Swipe.FAST,
                  GeneralLocation.CENTER,
                  new CoordinatesProvider() {
                      @Override
                      public float[] calculateCoordinates(View view) {
                          float[] coordinates = GeneralLocation.CENTER.calculateCoordinates(view);
                          coordinates[1] = view.getContext().getResources().getDisplayMetrics().heightPixels;
                          return coordinates;
                      }
              }, Press.FINGER);
          }
          

          MySwipeAction 可能是这样的:

          public class MySwipeAction implements ViewAction {
              public MySwipeAction(Swiper swiper, CoordinatesProvider startCoordProvide, CoordinatesProvider endCoordProvide, PrecisionDescriber precDesc) { 
                     // store here in class variables to use in perform
                     ...
              }
          
              @Override public Matcher<View> getConstraints() {...}
          
              @Override public String getDescription() {...}
          
              @Override
              public void perform(UiController uiController, View view) {
                  ...
                  float[] startCoord = startCoordProvide.calculateCoordinates(view);
                  float[] finalCoord = endCoordProvide.calculateCoordinates(view);
                  float[] precision =  precDesc.describePrecision();
          
                  Swiper.Status status = Swiper.Status.FAILURE;
          
                  // you could try this for several times until Swiper.Status is achieved or try count is reached
                  try {
                      status = m_swiper.sendSwipe(uiController, startCoord, finalCoord, precision);
                  } catch (RuntimeException re) {
                      ...
                  }
          
                  // ensures that the swipe has been run.
                  uiController.loopMainThreadForAtLeast(ViewConfiguration.getPressedStateDuration());
              }
          }
          

          希望对你有帮助。

          【讨论】:

          • cmets 和点太多...如果您有“完整”代码示例,请显示。许多人不知道他们可以在你的'...'中输入什么
          • 我同意。排除代码中使用的变量定义和赋值是令人困惑的。如果它使代码更难阅读,那么节省几行是不值得的。
          【解决方案6】:

          //向上滑动

          for(int i=0;i<=3;i++){
              onView(allOf(withId(R.id.recycler_view),isDisplayed())).perform(actionOnItemAtPosition(4, swipeUp()));
          }
          

          //向下滑动

          for(int i=0;i<=3;i++){
               onView(allOf(withId(R.id.recycler_view),isDisplayed())).perform(actionOnItemAtPosition(7, swipeDown()));
          }
          

          【讨论】:

            猜你喜欢
            • 2019-12-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多