Appium Hybrid App 中,WebView 界面滑动后控件坐标错误!

water · 2015年06月03日 · 最后由 water 回复于 2015年06月03日 · 2565 次阅读

这是我在调试我们 App 时候发现的一个很奇怪的问题,目前还没有找到有效的解决办法。

环境:
Appium 1.3.1
华为荣耀 6Plus,分辨率:1080*1920
Android 4.4.2

首先,我们的 App 某个界面是这样的:(应该很多人用过)

这是可以上下滑动的 WebView 界面,直接在此界面定位元素是可以正确点击的。

然后,我们进行了滑动操作,滑到了最底下,界面如下:

这时候我在脚本中点击就会出现点错的情况。例如我想点"济宁",实际上点击到的是"济南"!
dump XML 文件查看其坐标:

<node index="1" text="" resource-id="" class="android.view.View" package="xxx.xxx" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[333,1641][582,1776]">
  <node index="0" text="" resource-id="" class="android.view.View" package="xxx.xxx" content-desc="济宁 Link" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[333,1641][582,1776]" /> 
  </node>

在 XML 中看到,“济宁” 的边界坐标为"[333,1641][582,1776]",很明显,我们的手机分辨率是 1080*1920,而"济宁"是在最底下,其边界最下面的值应该是接近 1900 的,这里的坐标就是出错了!

那么问题来了,为何会出现这种情况呢?我应该如何解决 T_T,欢迎探讨。@chenhengjie123@mads

不能叫解决方案的解决方案:
绕过去!在遇到这种情况的时候,加个特例,把获取到的纵坐标 Y 值,加上个 100,就点到了。

CMDCommand("adb shell input tap " + x.toString() + " " + (y+100).toString());
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 15 条回复 时间 点赞

获取手机分辨率都是错误的。会不会就是这个问题导致的控件坐标计算错误?

Web 控件点击是按坐标点的吗?实现贴来看看 我也有这个问题

#2 楼 @zb460989093 点击就是简单的 element.click()。分辨率应该是没问题的,使用 adb shell dumpsys window displays 来获取的。

#3 楼 @weamylady 你好,你的 hybrid app 实现了么?求 qq,我想咨询咨询

water #11 · 2015年06月03日 Author

#4 楼 @mads 实现了呀~ ~! Appium 不是本来就支持么?

#5 楼 @weamylady 能把脚本发来看看么

#6 楼 @mads 主要方法是在本 Context 找不到控件,就转换一下 Context。由于 Selendroid 模式下有 bug,我们现在只支持 4.4+ 的 Hybrid,也就是要在 WebView Context 下识别。
下面这个是关键的方法,C#:

private void ChangeToNextContext()
        {
            String curContext = driver.GetContext();
            List<string> webcontexts = driver.GetContexts();
            Logger.LogHelper.debug("...[Debug]Context number: " + webcontexts.Count);

            if(webcontexts.Count > 1){

                if (webcontexts[0] != curContext)
                {
                    try
                    {
                        Logger.LogHelper.debug("...[Debug]Change SetContext to: " + webcontexts[0]);
                        driver.SetContext(webcontexts[0]);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogHelper.debug("[Error]SetContext error:" + ex.ToString());
                    }
                }
                else
                {
                    try
                    {
                        Logger.LogHelper.debug("Change SetContext to: " + webcontexts[1]);
                        driver.SetContext(webcontexts[1]);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogHelper.debug("SetContext error:" + ex.ToString());
                    }
                }
            }

        }

#3 楼 @weamylady 1080*1920 你可以看下 appium 的日志,实际取到的好像是 1080*1760 反正不是 1920

#3 楼 @weamylady appium 的分辨率用的是 uiautomator 的接口。你的点击实现如果用的是 element.click 方法应该没问题,但是针对 webview 元素点击时我又遇到没有点击的现象。你滑动之后,点击的元素不是你设置的那个,是不是滑动导致 elementid 发生了变化。比如滑动之前 hashmap 里的为 1,滑动之后的那个 1 已不是那个元素了

water #10 · 2015年06月04日 Author

#8 楼 @zb460989093 elementid 发生变化应该没关系的,我手动 dump xml 查看它的坐标都有问题,这才是重点~

#10 楼 @weamylady 我说了 appium 本身计算的手机分辨率就有问题。实际为 1080*1920。而其获取到的为 1080*1776。济宁在最下面,坐标不是靠近 1900 不就很正常了。appium 获取分辨率的方法是调用的 uidevice 的 getDisplayWidth 和 getdisplayHeight 方法。dum xml 的关于坐标的处理应该和这个分辨率获取方法有关

water #12 · 2015年06月04日 Author

#11 楼 @zb460989093 看来是需要修改 Appium 源码,重新编译,才可以根本上解决这个问题哦~

#11 楼 @zb460989093 如果 Appium 本身计算的手机分辨率有问题,那为何平时控件点击都没问题呢?只有滑动 WebView 以后,才会出现点击错误~

#13 楼 @weamylady 我猜测下,手机实际分辨率高度为 1920,然而 appium 的为 1776,这个是不是把手机上边的状态栏给减去了?然后 dum 时左边就按减去的 1776 来处理。但是点击时又变成了按 1920 来算了,产生了误差。然后你补正位移,就可以点击到正确的坐标了

#14 楼 @zb460989093 如果是按照你说的,那么点击的误差应该是偏下而不是偏上吧?

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