Appium 关于 H5 动画页面元素坐标超出边界的探讨

lion · 2016年06月20日 · 最后由 lion 回复于 2016年11月10日 · 3682 次阅读

遇到的具体问题是:自动化操作到某一界面后,能找到页面的元素,但是点击它或者输入值,页面没反应,也没报错,但不是自己想要的结果

分析原因:通过分析,找到操作不了的元素,可以正常定位到所有该元素的信息,分析发现该元素的坐标超出边界,再通过直接调用 tap 方法点击该元素的坐标,appium 会报错:点击的坐标超出边界。所以最终得到的结论是,操作不了该元素的原因是坐标超出边界

目前的解决方案:上面已经得到操作不了的原因,那么要解决此问题,我想到的办法是重新让页面渲染一次,重新布局之后让想要操作的元素坐标回到屏幕范围内就可以正常操作,目前已经尝试的方法,①锁屏再解锁②按 home 键再回到应用③等待几秒钟再获取元素,这三种方法全都失败;成功的方法是,找到页面一个输入框并点击,这时候会弹出键盘(这里页面就会重新布局并计算坐标了),然后隐藏键盘,再查找元素就可以正常操作。本方法的关键点是调起输入框,以达到让页面重新布局的效果。

意见征求:如果页面根本就没有输入框则此方法行不通,那么还有什么办法能让页面重新布局,或者大家有什么更好的方法来操作这种坐标超出边界的元素

11 月 10 日更新:
经过不懈努力重要找到办法解决了,遇到此问题的时候先切换到 webview 页面,然后再打印出当前页面元素,注意这一步不能少,后面会提到原因。根据当前页面元素的里面想要的元素的信息定位出来并操作它。亲测可行(原理我也不清楚,网上查资料得到的结果应该是切换到 webview 页面后再操作元素是通过事件来完成,而普通情况下是通过坐标来完成)

这里一个大坑是:
appium 切换到 webview 之后,定位元素后操作,这里如果定位不到或者定位错了 appium 不会抛异常而是直接进行下一步了。。。。所以如果在切换到 webview 页面不打印页面元素来查找的话会找不到当前页面元素

共收到 23 条回复 时间 点赞

其实我读下来有一个疑问,这种超出的问题是常见的?by design 的?还是说 bug 的一种?

没有明白为什么重新渲染一次就好了。。= =

元素越界的话,不是应该是不可见的吗。。。不可见就让他变成可见呗

lion #3 · 2016年06月20日 Author

#1 楼 @monkey 这种问题不是很常见,目前发现只有在 H5 页面并且有动画效果的页面才会出现,不是 bug 吧,设计的时候重构就是这么设计的:进入一个页面你能看到页面内的元素是一些东西,还有一些东西在页面外面(你看不到),然后触发某些条件后,这个动画效果就实现了,具体就是外面那个元素移动到屏幕内了,但是 appium 获取的时候坐标还是在外面,我的理解是,系统认为它的坐标还是在外面,只是它有一些变化而已,再页面重新布局之前这个坐标永远不会变化

#3 楼 @gpslion 哦~你这样说我就理解了。简单来讲就是说一个 X*Y 的 View 放在了一个手机上,其他界面只不过是通过逻辑在界面上进行展现,但本身 View 的大小其实是很大的,是这个意思吧

lion #5 · 2016年06月20日 Author

#4 楼 @monkey 差不多是这个意思,H5 的布局 view 可能远大于手机的屏幕,我测的 APP 是个混合应用,H5 页面还是挺多,凡是有动画效果的都有这个问题

lion #6 · 2016年06月20日 Author

#2 楼 @eurekasaber 元素本身是可见的。。但是坐标在屏幕范围外,appium 又规定死了不能点击屏幕范围外的坐标,所以不能操作该元素

解决方案:

1、强制重新渲染 UI 界面。

操作方法:
a) 点击输入框弹出输入法
b) 点击各种弹出框按钮 例:

2、切换到 webdriver 模式

appium 的话就是切到 content 中去 (具体叫什么忘记了)
方案 1 是使用 的 UIautomator 去识别 webview 对象,各种问题的主要原因是 webview 的各种缓存机制问题.,如果使用 webdriver 模式去识别控件,可以更好的识别控件元素 (可用属性增加很多,相当于 web 自动化).

在 webdriver 模式下 你完全可以使用 click 事件而非click来进行元素操作.
click 事件 : 直接触发元素点击事件
click : 获取元素位置 进行坐标点击

这个方案的坑也比较多,大致列一下:

  • webview 内的元素坐标和手机实际坐标是 2 个参数
  • 非原生 webview 会出现各种莫名奇妙的问题

#6 楼 @gpslion 不是 appium 规定不能点屏幕外的元素....是 appium 根本就是坐标点击 你让他怎么点屏幕外的元素啊?

lion #9 · 2016年06月21日 Author

#8 楼 @dongdong 谢谢,你提供的切换 webdriver 这种思路我去试试看,如果有效果我再去修复下帖子内容,万分感谢

#7 楼 @dongdong 请问 『webview 内的元素坐标和手机实际坐标是 2 个参数』,是不是这个意思:获取的元素坐标 (webElement.getLocation()) != 手机屏幕分辨率坐标,因为我用 webElement.getLocation() 实际拿到的值好像不是该元素在屏幕中的像素位置

#10 楼 @jira 这个就是我说的两个坐标 一个是基于 uiautomator 的屏幕坐标,一个是基于 webview 内部 html 的坐标

#11 楼 @dongdong 恩 但是我再实验了下,native 界面拿到的 webElement.getLocation()也不等于实际屏幕中的坐标,再问下 getLocation 到底拿到的是啥玩意呢

#11 楼 @dongdong 一直以为是返回元素在屏幕中的绝对坐标

#12 楼 @jira 坐标不同有很多原因 但是 getlocation 确实是获取元素在手机屏幕上的实际坐标

#13 楼 @jira 屏幕拖动后 这个坐标会变化的,如果不变化那么是其他原因

#15 楼 @dongdong 并没有拖动,会是啥原因呢

#15 楼 @dongdong

注意看下我点的位置是屏幕右下角,inspector 返回的 point 信息貌似只是分辨率的 1/2

#17 楼 @jira 分辨率和 坐标不是一个东西

#18 楼 @dongdong 好吧~~我好好适应下,之前弄 android 的 一直用分辨率当坐标点击

#18 楼 @dongdong 像这种 webview Location 和实际屏幕坐标 Location 不一致,怎么处理呢?

楼主有更好的方法了麽?我也是测 H5 的,偶尔会出现,脚本的代码是找到页面元素了,但是实际 click() 的时候,是偏离这个元素的,搞得我头都大了。只能通过坐标去点击页面这个元素。

@gpslion @pys_moving 测试微信上的一些可以滑动切换页面的 H5 时,如何解决网络不稳定的问题呢?表现为有时页面可以正常刷出来,有时需要反复操作几次才能刷新出来。

#22 楼 @superbaby11 网络不稳定导致页面无法正常加载,然后找不到元素?出现这种情况手工测试是怎么处理的?如果是反复操作即可,那脚本就设置一个异常判断,直到页面正常加载再去查找页面上的元素。

lion 关闭了讨论 11月10日 18:43
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册