• 手机自动化测试:appium源码分析之bootstrap十七


    手机自动化测试:appium源码分析之bootstrap十七

     

       

       poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。如果对课程感兴趣,请大家咨询qq:908821478。

    MultiPointerGesture

    package io.appium.android.bootstrap.handler;

    import android.view.MotionEvent.PointerCoords;

    import com.android.uiautomator.common.ReflectionUtils;

    import io.appium.android.bootstrap.*;

    import org.json.JSONArray;

    import org.json.JSONException;

    import org.json.JSONObject;

    import java.lang.reflect.Method;

    import static io.appium.android.bootstrap.utils.API.API_18;

    public class MultiPointerGesture extends CommandHandler {

      private double computeLongestTime(final JSONArray actions)

          throws JSONException {

        double max = 0.0;

        for (int i = 0; i < actions.length(); i++) {

          final JSONArray gestures = actions.getJSONArray(i);

          final double endTime = gestures.getJSONObject(gestures.length() - 1)

              .getDouble("time");

          if (endTime > max) {

            max = endTime;

          }

        }

        return max;

      }

      private PointerCoords createPointerCoords(final JSONObject obj)

          throws JSONException {

        final JSONObject o = obj.getJSONObject("touch");

        final int x = o.getInt("x");

        final int y = o.getInt("y");

        final PointerCoords p = new PointerCoords();

        p.size = 1;

        p.pressure = 1;

        p.x = x;

        p.y = y;

        return p;

      }

      @Override

      public AndroidCommandResult execute(final AndroidCommand command)

          throws JSONException {

        try {

          final PointerCoords[][] pcs = parsePointerCoords(command);

          if (command.isElementCommand()) {

            final AndroidElement el = command.getElement();

            if (el.performMultiPointerGesture(pcs)) {

              return getSuccessResult("OK");

            } else {

              return getErrorResult("Unable to perform multi pointer gesture");

            }

          } else {

            if (API_18) {

              final ReflectionUtils utils = new ReflectionUtils();

              final Method pmpg = utils.getControllerMethod("performMultiPointerGesture",

                  PointerCoords[][].class);

              final Boolean rt = (Boolean) pmpg.invoke(utils.getController(),

                  (Object) pcs);

              if (rt) {

                return getSuccessResult("OK");

              } else {

                return getErrorResult("Unable to perform multi pointer gesture");

              }

            } else {

              Logger.error("Device does not support API < 18!");

              return new AndroidCommandResult(WDStatus.UNKNOWN_ERROR,

                  "Cannot perform multi pointer gesture on device below API level 18");

            }

          }

        } catch (final Exception e) {

          Logger.debug("Exception: " + e);

          e.printStackTrace();

          return new AndroidCommandResult(WDStatus.UNKNOWN_ERROR, e.getMessage());

        }

      }

      private PointerCoords[] gesturesToPointerCoords(final double maxTime,

          final JSONArray gestures) throws JSONException {

        // gestures, e.g.:

        // [

        // {"touch":{"y":529.5,"x":120},"time":0.2},

        // {"touch":{"y":529.5,"x":130},"time":0.4},

        // {"touch":{"y":454.5,"x":140},"time":0.6},

        // {"touch":{"y":304.5,"x":150},"time":0.8}

        // ]

        // From the docs:

        // "Steps are injected about 5 milliseconds apart, so 100 steps may take

        // around 0.5 seconds to complete."

        final int steps = (int) (maxTime * 200) + 2;

        final PointerCoords[] pc = new PointerCoords[steps];

        int i = 1;

        JSONObject current = gestures.getJSONObject(0);

        double currentTime = current.getDouble("time");

        double runningTime = 0.0;

        final int gesturesLength = gestures.length();

        for (int j = 0; j < steps; j++) {

          if (runningTime > currentTime && i < gesturesLength) {

            current = gestures.getJSONObject(i++);

            currentTime = current.getDouble("time");

          }

          pc[j] = createPointerCoords(current);

          runningTime += 0.005;

        }

        return pc;

      }

      private PointerCoords[][] parsePointerCoords(final AndroidCommand command)

          throws JSONException {

        final JSONArray actions = (org.json.JSONArray) command.params().get(

            "actions");

        final double time = computeLongestTime(actions);

        final PointerCoords[][] pcs = new PointerCoords[actions.length()][];

        for (int i = 0; i < actions.length(); i++) {

          final JSONArray gestures = actions.getJSONArray(i);

          pcs[i] = gesturesToPointerCoords(time, gestures);

        }

        return pcs;

      }

    }

    多点触控根据你传递过来的参数决定,如果参数是一个控件元素,那么就要调用performMultiPointerGesture方法,如果参数是一系列的点,那么就要调用反射。那么具体来看看2个方法细节。

    控件

    performMultiPointerGesture

    public boolean performMultiPointerGesture(PointerCoords[] ...touches) {

        try {

          if (API_18) {

            // The compile-time SDK expects the wrong arguments, but the runtime

            // version in the emulator is correct. So we cannot do:

            //   `return el.performMultiPointerGesture(touches);`

            // Instead we need to use Reflection to do it all at runtime.

            Method method = this.el.getClass().getMethod("performMultiPointerGesture", PointerCoords[][].class);

            Boolean rt = (Boolean)method.invoke(this.el, (Object)touches);

            return rt;

          } else {

            Logger.error("Device does not support API < 18!");

            return false;

          }

        } catch (final Exception e) {

          Logger.error("Exception: " + e + " (" + e.getMessage() + ")");

          return false;

        }

      }

    UiObject中有直接可以调用的performMultiPointerGesture方法,为什么还要用反射呢。上面的方法里的注释是这样解释的:编译的时候sdk会认为参数是错误的,但是运行时却认为是正确的,所以只有在运行时调用才能保证正确性。反射调用的就是运行时的环境,所以它使用了反射调用了performMultiPointerGesture。

    点组

    在api18以上的版本中才有传点组的方法可调用,所以先判断sdk的版本。如果api在18以上,那么就要调用InteractionController..performMultiPointerGesture的方法来执行

  • 相关阅读:
    在windows安装部署ShardingSphere-Proxy 分库分表中间件
    报错:fatal: unable to access 'https://github.com/xxx/': OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443
    一台Windows配置多个mysql服务
    解决.net core 部署IIS报错:HTTP Error 500.30
    vs code 不格式化注释
    .net工具类——URL请求数据
    .net工具类——URL处理
    .net工具类——读取写入cookie
    js没有权限
    ueditor图片上传
  • 原文地址:https://www.cnblogs.com/poptest/p/4953542.html
Copyright © 2020-2023  润新知