Click by bounds / coordinates

前端 未结 3 638
清酒与你
清酒与你 2020-12-06 04:11

I know it is possible for Espresso to click by bounds the way UiAutomator does. (x and y coordinates) I have read through the documentation but I can\'t seem to find it. Any

相关标签:
3条回答
  • 2020-12-06 04:49

    The valid answer helped me although that method is deprecated. Now you have to specify the inputDevice (for example InputDevice.SOURCE_MOUSE) and buttonState (for example MotionEvent.BUTTON_PRIMARY

    Example in Kotlin:

    companion object {
        fun clickIn(x: Int, y: Int): ViewAction {
            return GeneralClickAction(
                    Tap.SINGLE,
                    CoordinatesProvider { view ->
                        val screenPos = IntArray(2)
                        view?.getLocationOnScreen(screenPos)
    
                        val screenX = (screenPos[0] + x).toFloat()
                        val screenY = (screenPos[1] + y).toFloat()
    
                        floatArrayOf(screenX, screenY)
                    },
                    Press.FINGER,
                    InputDevice.SOURCE_MOUSE,
                    MotionEvent.BUTTON_PRIMARY)
        }
    }
    
    0 讨论(0)
  • 2020-12-06 04:52

    @haffax's answer is great and works well.

    However, if you want to click in a certain part of a View that may change from screen to screen, it might be useful to click based on percents (or ratios) as even the dp numbers may not be stable across all screens. So, I made an easy modification to it:

        public static ViewAction clickPercent(final float pctX, final float pctY){
        return new GeneralClickAction(
                Tap.SINGLE,
                new CoordinatesProvider() {
                    @Override
                    public float[] calculateCoordinates(View view) {
    
                        final int[] screenPos = new int[2];
                        view.getLocationOnScreen(screenPos);
                        int w = view.getWidth();
                        int h = view.getHeight();
    
                        float x = w * pctX;
                        float y = h * pctY;
    
                        final float screenX = screenPos[0] + x;
                        final float screenY = screenPos[1] + y;
                        float[] coordinates = {screenX, screenY};
    
                        return coordinates;
                    }
                },
                Press.FINGER);
    }
    

    I thought I would share it here so others can benefit.

    0 讨论(0)
  • 2020-12-06 05:01

    Espresso has the GeneralClickAction, this is the underlying implementation of ViewActions click(), doubleClick(), and longClick().

    The GeneralClickAction's constructor takes a CoordinatesProvider as second argument. So the basic idea is to create a static ViewAction getter which provides a custom CoordinatesProvider. Something like this:

    public static ViewAction clickXY(final int x, final int y){
        return new GeneralClickAction(
            Tap.SINGLE,
            new CoordinatesProvider() {
                @Override
                public float[] calculateCoordinates(View view) {
    
                   final int[] screenPos = new int[2];
                   view.getLocationOnScreen(screenPos);
    
                   final float screenX = screenPos[0] + x;
                   final float screenY = screenPos[1] + y;
                   float[] coordinates = {screenX, screenY};
    
                   return coordinates;
                }
            },
            Press.FINGER);
    }
    

    A general advice with Espresso: instead of looking for documentation (there's virtually none), look at the source code. Espresso is open source and the source code itself is of really good quality.

    0 讨论(0)
提交回复
热议问题