Appium [请教] appium 测试微信时 app 中的元素有 id 却无法定位

wenkaichou · April 20, 2018 · Last by TD replied at November 08, 2019 · 4189 hits

感谢论坛,在这里查到了很多关于 appium webview 的资料,解决了项目的问题。

进入正题,
问题是这样的:使用微信扫描二维码后,进入一个 订单确认页面,如下图,这个页面上的元素怎么都无法定位,不管是通过 id,classname,还是 xpath

比如这样:
self.driver.find_element_by_id('com.tencent.mm:id/dyg').click()

执行的时候一直提示找不到元素,appium 日志如下:

> info: [debug] Waiting up to 15000ms for condition
> info: [debug] Pushing command to appium work queue: ["find",{"strategy":"id","selector":"com.tencent.mm:id/dyg","context":"","multiple":false}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.tencent.mm:id/dyg","context":"","multiple":false}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: find
> info: [debug] [BOOTSTRAP] [debug] Finding com.tencent.mm:id/dyg using ID with the contextId:  multiple: false
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.tencent.mm:id/dyg]
> info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying.
> info: [debug] [BOOTSTRAP] [debug] Finding com.tencent.mm:id/dyg using ID with the contextId:  multiple: false
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.tencent.mm:id/dyg]
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"status":7,"value":"No element found"}
> info: [debug] Waited for 3071ms so far
> info: [debug] Pushing command to appium work queue: ["find",{"strategy":"id","selector":"com.tencent.mm:id/dyg","context":"","multiple":false}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.tencent.mm:id/dyg","context":"","multiple":false}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: find
> info: [debug] [BOOTSTRAP] [debug] Finding com.tencent.mm:id/dyg using ID with the contextId:  multiple: false
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.tencent.mm:id/dyg]
> info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying.
> info: [debug] [BOOTSTRAP] [debug] Finding com.tencent.mm:id/dyg using ID with the contextId:  multiple: false
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.tencent.mm:id/dyg]
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"status":7,"value":"No element found"}
> info: [debug] Waited for 13779ms so far
> info: [debug] Pushing command to appium work queue: ["find",{"strategy":"id","selector":"com.tencent.mm:id/dyg","context":"","multiple":false}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"id","selector":"com.tencent.mm:id/dyg","context":"","multiple":false}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: find
> info: [debug] [BOOTSTRAP] [debug] Finding com.tencent.mm:id/dyg using ID with the contextId:  multiple: false
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.tencent.mm:id/dyg]
> info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying.
> info: [debug] [BOOTSTRAP] [debug] Finding com.tencent.mm:id/dyg using ID with the contextId:  multiple: false
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.tencent.mm:id/dyg]
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"status":7,"value":"No element found"}
> info: [debug] Condition unmet after 16839ms. Timing out.

环境:appium 1.4.0.0,手机 Android 7.0

请教是什么问题导致这个问题的呢,要如何正确定位这个元素呢?
ps.(tap 坐标的方式可以点击,不过还是想了解一下 这个原因),如果有大神知道,请指点😫 😫


问题补充:
执行到当前页面的时候,使用 driver.page_source 输出的竟然不是当前页面的内容,而是 Android 屏幕首页的元素信息(按 Home 键之后 返回的屏幕首页),好奇怪
其他页面 使用 driver.page_source 输出的内容 是当前页面的内容,元素也可以正常识别
发现这个支付界面 是一个新的 activity,但是输出 current_activity 的时候,appium 已经自动切换到了这个新的 activity,不知道元素无法识别是否跟这个有关系呢.
经确认,没关系,删除


结论:
感谢大家的回复和关注,这几天空余的时候一直在查资料,终于找到了原因
确实是 Android 7.0 在切换 activity 后的一个 bug,bug 链接如下,是说在切换 activity 后导致元素无法定位:
https://github.com/appium/appium/issues/8956
先试着换了一台 Android 6.0 的机器,发现脚本运行没问题,对象也可以正常识别😖 😖
本来想 换成 uiautomator2 继续测试这个问题,发现 论坛上一个帖子介绍说 uiautomator2 需要 appium 1.63 以上的版本,不然会有冲突(感谢 wuranxu 同学)
https://testerhome.com/topics/9684

我这边 appium 的版本是 1.4.0.0,项目一直在用,怕升上去后 这个问题修复了 又出现其他未知的错误,出于稳定方面的考虑,暂时就保持现状,这个问题先用 tap 解决。总算明白了问题的原因😖 😖

有同样问题的同学可以尝试下这个解决方案,用 UIautomator2 来识别。

ps. 切换 activity 后 元素不能正常识别的问题 应该是小范围存在,不是每次切换 必然出现,之前一直不敢确认 是 activity 切换导致的,就是因为 支付页面也是切换了 activity,但是元素就能正常识别,被误导了,走了好多弯路😖 😖

共收到 35 条回复 时间 点赞

为什么不用 text,微信支付定位?这个 id 可能是混淆后的

笑哼 回复

对,‘立即支付’ 按键的定位
self.driver.find_element_by_xpath('//*[@text="立即支付"]').click()
self.driver.find_element_by_android_uiautomator('new UiSelector().text("立即支付")').click()
两种方式试了都不行

我也同样遇到这种问题,id、text 都不行

wenkaichou 回复

我碰到过一种情况
界面总共有相同 id 的元素 0,1,2,3,操作步骤是要重复点击两次 3,点击第一次 3 的时候正常,第二次的时候要选择 7 才能点击到正确的元素,选择 3 的话会告诉你找不到元素。
所以,我猜测,会不会是被一层看不到的 UI 覆盖了什么的?

实在不行,写个坐标点击嘛

感谢回复,我也怀疑无法定位元素是因为 比如有多个窗口或者 UI 弹窗之类。
今天继续研究了下,发现有个很奇怪的现象:
打开这个支付界面的时候,通过 self.driver.current_context 输出的结果确实是 NATIVE_APP,但是 通过 print self.driver.page_source
输出的结果 竟然是 Android 屏幕首页的信息(没错,就是按 Home 键之后的首页),
但是在 微信主界面输出 print self.driver.page_source 结果是正常的。
想试着切换 handle,发现 native app 似乎不支持这个方法。

感觉有点像窗口切换的问题,不知道 native app 这边要如何切换 handle 呢,或者有没有其他可能的原因呢?

皆非 回复

坐标点击可以,目前的折中方案就是先用坐标点击。主要是想了解一下为什么会有这个问题,以便后续如果不是点击,而是获取页面某个元素的时候,还是会遇到这个问题😫

@Lihuazhang 冒昧的问下大佬,可否指点一下,谢谢啦😫 😫

支付相关的按钮或者输入框通常在开发的时候会做特殊处理,防止被不良应用劫持...

wenkaichou 回复

估计是加了安全防护了。我看看我有没有 Android 机器。。。

恒温 回复

感谢大佬回复。
晚上一直在搜这个问题,顺便问一下,这个 这个支付页面是一个新的 activity,打印 current_activity 的时候 发现是一个新的值,跟这个有没有关系? appium 是否会自动识别这个新的 activity 中的元素呢

wenkaichou 回复

和 activity 没有关系吧。我看你的 uiautomatorviewer 可以 dump 出来,说明应该就能识别到。

恒温 回复

原来如此,继续求答案😿

这个问题我也遇见了,测试的是公司开发的 APP,页面是原生的,没有 webview,用 uiautomatorviewer 可以定位出来元素,
但是用 appium 跑用各种方法都定位不到元素,
我在这里提一个方法不一定管用,但是可以当作一个测试的方法,
element = driver.find_elements_by_xpath("//*")
for i in element:
print (i)
print (i.text)
这样能把当前页面全部可定位元素找出来
但是我用这个方法依然定位不到页面任何元素
我会继续关注这个问题的回答的

我这边试着运行了一下,这段代码只打印出了一个元素。
你那边可以确认 输出的所有元素就是当前测试页面的所有元素是么
另外 我这边用 driver.page_source 输出的内容 竟然不是当前页面,好奇怪
这个问题我也会继续查找,估计短期内没什么眉目😫

@seveniruby 冒昧的打扰下大佬,能给一点建议么,感激不尽。好困惑😫 😫

wenkaichou 回复

http://www.iteye.com/news/32324
我比较认同 Lihuazhang 说的,有可能是加了防护...

😭 😭 安全防护的内容我不太了解,不知道有没有同学可以研究一下,另外目前发现无法定位元素的页面 只有这一个金额确认的页面,连需要输入支付密码的支付页面 都可以正常识别呢

Author only
20Floor has deleted
wenkaichou · #21 · April 24, 2018 Author
Author only
22Floor has deleted
wenkaichou · #23 · April 24, 2018 Author
Author only

@Lihuazhang @Fengyongming0311 @qwerty 非常感谢,问题的原因查到了,总结了一下放到了帖子结尾😺 😺

appium 不能测试多进程,不同进程展示的数据不能获取到

看了你的结论以后我试了不同的机型,安卓 6.0 安卓 7.1.2 和安卓 8.0,定位不到元素的情况下在安卓 7.1.2 和安卓 8.0 中都出现了,测试安卓 6.0 同样的脚本元素能定位到,我会去尝试一下 uiautomator2
如果这个问题 appium 不修复的话这块就很难过去了,只要切换了 activity 就定位不到元素了....

👏 等待 uiautomator2 的测试结果

wenkaichou 回复

看到这么多朋友也一样遇到这个问题,感觉像找到了组织。最近在 7.0 上运行之前的自动化代码时也发现了这个问题,在我们自己 app 其他页面都可以获取到元素,独在特定页面怎么也拿不到元素,也苦恼了这几天,都找不到答案。感谢楼主解答了我的困惑,这期间也尝试过用 Uiautomator2 是可以正常获取到元素的。

嗯,和我的结论是一样的,uiautomator2 已经试过是可以获取到元素的,你可以试过,接下来我准备将 appium driver 切换到 appium-uiautomator2-driver 应该可以解决这个问题。

cordell 回复

论坛确实氛围挺好的,提出的问题很多同学解答,就顺便把结果写在这里了,遇到同样问题的同学可以参考一下😺

我也遇到这个问题了

我用 appium1.4.16 版本也遇到明明有这个元素但是提示找不到这个元素 did not match any elements.我不想通过坐标点击和升级 appium,请问还有什么办法吗?

cordell 回复

你是在 appium1.4 版本的上面切 uiautomator2 吗?我升级了 appium1.6.5 用这个是可以点击找到元素了,但是有的元素点击要很久很久最后 socket 超时了

wenkaichou 回复

您好!按照您说的方法,利用 UIAutomator2 对安卓 7.0 手机 APP 定位还是不能够定位到按键,请问您是怎么解决的,能否指点一下😊

TD 回复

你好,请问你这个问题解决了吗?我用 uiautomator2 也是定位不到😫

Jodie 回复

之前是升级了 appium 解决了,现在是不用 appium 做自动化了😂

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up