手机自动化测试: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的方法来执行
手机自动化测试:appium源码分析之bootstrap十七的更多相关文章
- 手机自动化测试:appium源码分析之bootstrap三
手机自动化测试:appium源码分析之bootstrap三 研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对app ...
- 手机自动化测试:appium源码分析之bootstrap二
手机自动化测试:appium源码分析之bootstrap二 在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是对应的指令类, priva ...
- 手机自动化测试:appium源码分析之bootstrap一
手机自动化测试:appium源码分析之bootstrap一 前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...
- 手机自动化测试:appium源码分析之bootstrap十六
手机自动化测试:appium源码分析之bootstrap十六 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十五
手机自动化测试:appium源码分析之bootstrap十五 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十四
手机自动化测试:appium源码分析之bootstrap十四 poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开 ...
- 手机自动化测试:appium源码分析之bootstrap十三
手机自动化测试:appium源码分析之bootstrap十三 poptest(www.poptest.cn)是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开 ...
- 手机自动化测试:appium源码分析之bootstrap十一
手机自动化测试:appium源码分析之bootstrap十一 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十二
手机自动化测试:appium源码分析之bootstrap十二 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
随机推荐
- 3553: [Shoi2014]三叉神经树(树链剖分)
这道题特别恶心,首先我们可以发现更改的就是出现连续的一或二,那么就用线段树+树链剖分找到这个范围 想到是不难想,就是打起来恶心罢了= = CODE: #include<cstdio> #i ...
- JavaScript 基本类型值-Number类型
▓▓▓▓▓▓ 大致介绍 在JavaScript的内部采用IEEE754格式来表示数字,所以不区分整数和浮点数,都是用64位浮点数的形式储存.就是说,在JavaScript内部,就根本没有小数.但是有些 ...
- 包装一个php的验证码类
验证码是我们开发的时候经验到的功能,所以在此本人包装了一个验证码类,应该可以作为php的类插件用,在此分享给各位博客园的读友. 实现的原理也是很简单,就是利用画布的几个元素,再加上一些字符串的获取,东 ...
- noi 1.8 11图像旋转
水题不解释 其实我偷懒了 直接输出,,,,,,, 个人QQ:757394026团队QQ:466373640个人博客:www.doubleq.winc++/noi/信息学奥数博客:http://www. ...
- phpcms中用到的几个重要的代码
{pc:content action="lists" catid="12" moreinfo="1" order="id ASC& ...
- 【Zookeeper】源码分析之网络通信(三)
一.前言 前面已经学习了NIOServerCnxn,接着继续学习NettyServerCnxn. 二.NettyServerCnxn源码分析 2.1 类的继承关系 public class Netty ...
- 事件日志:无法加载站点/服务的所有 ISAPI 筛选器。因此启动中止。
事件日志:无法加载站点/服务的所有 ISAPI 筛选器.因此启动中止. Service Unavailable解决 故障状态:Internet 信息服务(IIS)管理器 里 应用程序池出现错误 “应用 ...
- C++ 11 学习3:显示虚函数重载(override)
5.显示虚函数重载 在 C++ 里,在子类中容易意外的重载虚函数.举例来说: struct Base { virtual void some_func(); }; struct Derived : B ...
- 1232: [Usaco2008Nov]安慰奶牛cheer
1232: [Usaco2008Nov]安慰奶牛cheer Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 612 Solved: 431[Submi ...
- CLR查找和加载程序集的方式(二) 流程图
在前一篇文章<CLR查找和加载程序集的方式(一)>中详细介绍了CLR查找和加载程序的方式,分别介绍了配置与代码的实现方式. 本篇通过一个具体的流程图来帮助大家更加直观明了深入的掌握CLR查 ...