Appium Appium 实现 LockViewPatter 手势密码输入方法之一

网球王子 · 2016年08月09日 · 最后由 网球王子 回复于 2017年11月10日 · 2814 次阅读
本帖已被设为精华帖!

问题描述
问题的产生是这样滴,俺们公司的 app 登录时有一步需要输入手势密码,九宫格那种的,看下图:

解决目标是需要用 appium 自动的输入手势密码。

搜解决方案
于是乎,上网搜现成的经验,有了如下结果:

遇到了问题
按照图示,九宫格的 9 个点应该为 9 个 ImageView 对象,如法炮制使用 UIAutomator 撸一遍咱要测试的 app,发现现实有点骨干 😂 看下图

原来咱公司的 app 手势密码键盘用了 LockViewPattern,没有办法拿到 9 个点对象;

也就是说网上搜到的现成方法不适用我遇到的问题😓

换个思路 另辟蹊径
那咋办呢,这时理所应当的想到了 TouchAction;利用触摸动作行为,直接做相应的手势。上网一搜就可以找到一段示例代码

touchAction.press(beginX,beginY).moveTo(xStep,yStep).moveTo(xStep,yStep).release().perform();

虽然之前我没有接触过 app 的自动化测试,但是从这段例子代码中我得到了一些暗示;我猜他的意思是 在 (beingX,beginY) 点按下手指,然后先移动 (xStep,yStep), 再移动 (xStep,yStep) 最后松开。

实操办法
为了简化测试难度,我设定的手势密码是沿中间三个点 从上往下画一条直线;

但是直接用坐标点找会有一些问题,比如手机屏幕大小不同,找点的位置可能会有偏差,所以输入 hardcode 坐标点是绝对不可取的;怎么办呢,看下图

目前我从 LockPatternView 对象上可以拿到它的左上角起点的坐标 (beginX,beginY), 高度 height, 宽度 width;如果是从中间第 2 点 垂直往下一条直线,那么第二个点的 x 轴坐标肯定是 beginX + width/2 ,毕竟在中点; 它的 Y 轴坐标 大约为 beginY + height/4 ; 从第二个点起始,先往下走到第 5 点 然后再是 第 8 点; 它们大约要移动 2 个 1/4 * height 的高度;有了这些可变的相对坐标位置,就不怕屏幕大小变化了 😊

尝试了几款屏幕大小不同的手机,均获成功 😆

当然这应该只是解决思路之一,欢迎大家补充其他更好的办法😃

代码参考

public static void setLockPattern(AppiumDriver driver) throws Exception{
    List<WebElement> view = Toolkit.waifForExistence("//android.view.View[contains(@resource-id,'view_lock_pattern')]",driver); //九宫格键盘view
    WebElement welem = view.get(0);
    int startX = welem.getLocation().getX();
    int startY = welem.getLocation().getY();
    int height = welem.getSize().getHeight();
    int width = welem.getSize().getWidth();
    int yStep = height / 4;
    int beginX = (2 * startX + width) / 2;
    int beginY = startY + yStep;

    //手势密码设置
    logger.info("开始设置手势密码,中间垂直直线 上->下");
    TouchAction touchAction1 = new TouchAction(driver);
    touchAction1.press(beginX,beginY).moveTo(0,yStep).moveTo(0,yStep).release().perform();
    Toolkit.wait(1);
    logger.info("再次设置手势密码,中间垂直直线 上->下");
    touchAction1.press(beginX,beginY).moveTo(0,yStep).moveTo(0,yStep).release().perform();
    logger.info("手势密码设置完毕");
}
共收到 17 条回复 时间 点赞

老钱 你用 markdown 语法修饰下你的代码和内容

#1 楼 @seveniruby 欧克 回去整

4 个点你试试,你这个是 3 个点,还是比较容易的,4 个点的难度比较大,需要连续并且不能中断

思寒_seveniruby 将本帖设为了精华贴 08月10日 11:02

加精理由: 用解锁的案例演示了 TouchAction 的用法. 弥补了这块的知识面.

#4 楼 @ftvbftvbq
尝试了一下 4 个点 也可以; 只是貌似 moveTo 里面的步长不能有负值,有了负值 appium 会报错 org.openqa.selenium.interactions.InvalidCoordinatesException ;

touchAction1.press(point1X,point1Y).moveTo(xStep,0).moveTo(0,yStep).moveTo(xStep,0).moveTo(0,yStep).release().perform();

赞一个


在 IOS 上应用类似方法同样获得成功,此方法也可以适用于 IOS

TouchAction action1 = new TouchAction(driver); 
action1.press(xx.xx).moveTo(xx, xx).moveTo(xx, xx).moveTo(xx, xx).release().perform(); 

坐标是要相对坐标

手机锁住了怎么用?

—— 来自 TesterHome 官方 安卓客户端

赞一个,思路可以,但是可能不能解决根本问题,对于分辨率奇葩的屏幕可能就无法获得到,最好的办法还是计算出 9 个点的确定坐标

我想问下 有遇到 release 不释放的童鞋么,最后一直处于长按的状态 release 好像不起作用 未释放

三个点可以转弯就不可以了这个是怎么回事呀

网球王子 回复

ios 9.3 以上设备成功了吗?

操作一次:
TouchAction action1 = new TouchAction(driver);
action1.press(xx.xx).moveTo(xx, xx).moveTo(xx, xx).moveTo(xx, xx).release().perform();
操作第二次:
TouchAction action1 = new TouchAction(driver);
action1.press(xx.xx).moveTo(xx, xx).moveTo(xx, xx).moveTo(xx, xx).release().perform();

预期:操作第二次跟第一次画的图相同
结果:会报错,看日志是元素偏移了
请问:请问大侠,这有办法解决吗?

刘发财 回复

请把具体移动坐标与错误日志贴来看看

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册