Appium appium 定位问题讨论帖

思寒_seveniruby · 2013年12月24日 · 最后由 pinkanguser 回复于 2018年11月21日 · 3521 次阅读
本帖已被设为精华帖!

appium 的定位估计也是个坑. 所以开个帖子讨论下大家遇到的问题.

我遇到的问题如下

  1. 无法点击"粘贴"按钮. 比如在文本中长按, 会出现粘贴按钮, 但是通过 uiautomator view 定位不到, appium 貌似也定位不到. 但是 uiautomator 的 events 却可以捕获到.
  2. dumpsys window 跟 uiautomator view, 以及跟 page source 的差别, 这块也不清楚.

大家还有其他的问题吗, 欢迎讨论

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 50 条回复 时间 点赞

我知道 iOS 下, instruments 在开始写自动化的时候,先会把 UI 树 打印出来。 用的是

UIATarget.localTarget().frontMostApp().logElementTree();

因为 iOS 里面有一个 Accessibility APIs 的东西, 在设置了 accessibility 之后, instruments 才能使用 name 定位到它。 否者估计只能遍历数组。

#1 楼 @lihuazhang 能获取到输入法的界面吗

我用 uiautomator 的 event 命令也获取到了粘贴的消息.
但是在自动化的时候找不到

12-24 16:59:53.933 EventType: TYPE_VIEW_CLICKED; EventTime: 34572995; PackageName: com.taobao.taobao; MovementGranularity: 0; Action: 0 [ ClassName: android.widget.TextView; Text: [粘贴]; ContentDescription: null; ItemCount: -1; CurrentItemIndex: -1; IsEnabled: true; IsPassword: false; IsChecked: false; IsFullScreen: false; Scrollable: false; BeforeText: null; FromIndex: -1; ToIndex: -1; ScrollX: -1; ScrollY: -1; MaxScrollX: -1; MaxScrollY: -1; AddedCount: -1; RemovedCount: -1; ParcelableData: null ]; recordCount: 0

android 原生应用 无法根据资源 id 获取到控件.

#5 楼 @shenkai600 原生的也可以获取, 比如系统设置里面的所有控件, 对于 paste 按钮无法点击, 貌似是跟布局有关.

#6 楼 @seveniruby 粘贴操作时属于 ime 里头的。。。不是个 activity

#7 楼 @spikeshen 我指的粘贴, 也不是搜狗的粘贴, 是长按操作出来的那个, 的确属于 IME, 但是 uiautomator 应该是可以抓到的. 因为它是跨 app 的

#9 楼 @spikeshen 问题是我用的是 uiautomator, 我不能操作内部方法, 只能在外部模拟. 我昨天查 sdk, 好像说有个什么事件, 是可以直线复制粘贴的. 貌似只要发送一个特殊的按键就可以了. 但是没找到细节.

#10 楼 @seveniruby 可以尝试用 adb 发个 ctrl+v,应该有效,不过我没找到 ctrl 对应的 keyevent code 是多少。。。

#10 楼 @seveniruby 找到标准文件了。。不过我这里下的好慢,你可以看看,然后试试发个 ctrl+v 吧。。。http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf

#12 楼 @spikeshen 跟 usb 没什么关系吧, 我从 sdk 中翻到了这个资料..http://developer.android.com/about/versions/android-4.3.html

Select text and copy/paste

The AccessibilityNodeInfo now provides APIs that allow an AccessibilityService to select, cut, copy, and paste text in a node.

To specify the selection of text to cut or copy, your accessibility service can use the new action, ACTION_SET_SELECTION, passing with it the selection start and end position with ACTION_ARGUMENT_SELECTION_START_INT and ACTION_ARGUMENT_SELECTION_END_INT. Alternatively you can select text by manipulating the cursor position using the existing action, ACTION_NEXT_AT_MOVEMENT_GRANULARITY (previously only for moving the cursor position), and adding the argument ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN.

You can then cut or copy with ACTION_CUT, ACTION_COPY, then later paste with ACTION_PASTE.

Note: These new APIs are also available for previous versions of Android through the Android Support Library, with the AccessibilityNodeInfoCompat class.

#13 楼 @seveniruby 他们的 key code 都是标准的,我的意思是,尝试发个键盘事件 ctrl + v 去做粘贴这活。但我不知道 ctrl 对应的 key code 是多少。。。

#13 楼 @seveniruby 这个是说 AccessibilityService 可以做到选择文本,复制粘贴的功能了。。。跟你说的两码事啊。。。

#15 楼 @spikeshen 所有的 keyevent 在http://developer.android.com/reference/android/view/KeyEvent.html, 貌似 adb shell input keyevent 还不行, 需要使用 adb shell sendevent ..

#16 楼 @seveniruby 额,这页面咋 403 了。。难道又被墙了么。。。 我觉得只能靠这个方式了,android 毕竟是 linux 内核,复制粘贴这种都跟 linux 是一样的

#14 楼 @spikeshen ctrl+v 貌似 android 不支持, 我用了如下代码

driver.execute_script("mobile: keyevent", :keycode=>50 )
driver.execute_script("mobile: keyevent", :keycode=>50 , :metastate=>113)

v 输入进去了, 但是 ctrl+v 没有生效.

#19 楼 @seveniruby 113 是 ctrl 的映射号? keyevent 基本都是单次点击,组合是特殊情况,我看 android 貌似就支持两种 ctrl 相关的组合操作:KEYCODE_CTRL_LEFT Control+Left 还有 KEYCODE_CTRL_RIGHT Control+Right。回头看下 adb shell input 里能不能实现长按 ctrl 然后按 v。。。。

#19 楼 @seveniruby 貌似只能用 sendevent 来尝试了,或者,换个思路吧。你如果能得到所选择的文本框焦点在屏幕的坐标,大概就能得出粘贴的坐标区域。。。然后,点吧。。。。

#20 楼 @spikeshen
我跟了下 uiautomator 的源代码, 发现底层是调用的这个函数.
http://developer.android.com/tools/help/uiautomator/UiDevice.html#pressKeyCodeint(, int)
我困惑的是第二个参数, 他到底应该如何写, 是不是 keyevent 里面的 KEYCODE_CTRL_LEFT ?

Parameters
keyCode the key code of the event.
metaState   an integer in which each bit set to 1 represents a pressed meta key

#21 楼 @spikeshen send event 我也试过了, 在我的手机上不生效, back 和 muenu 都行, 但是唯独 combo 组合键不生效, 你可以试试

#21 楼 @spikeshen 因为 appium 暂时没法输入中文,所以我才使用复制粘贴的方法去自动化, 但是粘贴实现不了.另外一个思路是直接调用 android 的输入法底层的框架, 直接使用 InputConnection.commitText 来实现输入, 因为其他的输入法也是直接调用这个方法的. 如果粘贴这个搞不定, 我就只能使用输入法底层函数了.

为什么 uiautomator 找不到"粘贴"这个按钮, 我还在查.

#24 楼 @seveniruby commitText 得考虑编码问题=。=

#26 楼 @spikeshen 在文档中翻到了这么一段内容, 貌似是 uiautomator 并没有返回所有的控件, 需要显式的设置标记才可以拿到那个粘贴按钮

Important: The ability to investigate the view hierarchy from an AccessibilityEvent potentially exposes private user information to your accessibility service. For this reason, your service must request this level of access through the accessibility service configuration XML file, by including the canRetrieveWindowContent attribute and setting it to true. If you do not include this setting in your service configuration xml file, calls to getSource() fail.
Note: In Android 4.1 (API Level 16) and higher, the getSource() method, as well as AccessibilityNodeInfo.getChild() and getParent(), return only view objects that are considered important for accessibility (views that draw content or respond to user actions). If your service requires all views, it can request them by setting the flags member of the service's AccessibilityServiceInfo instance to FLAG_INCLUDE_NOT_IMPORTANT_VIEWS.

#27 楼 @seveniruby 今天尝试用 sendevent 发物理键盘的操作指令。。。结果死活都没反应,到是发音量键或者电源键什么的都挺好使。。。很奇怪,回头问问 android 研发的人,看他们知道不知道怎么搞。

#28 楼 @spikeshen 我也试过 action_paste 了 也不好用 我在看输入法的实现 还打算读读 edittext 的源码试试

#28 楼 @spikeshen 我看了下 editview 的代码, 是支持的

public boolean onKeyShortcut(int keyCode, KeyEvent event) {
        final int filteredMetaState = event.getMetaState() & ~KeyEvent.META_CTRL_MASK;
        if (KeyEvent.metaStateHasNoModifiers(filteredMetaState)) {
            switch (keyCode) {
            case KeyEvent.KEYCODE_A:
                if (canSelectText()) {
                    return onTextContextMenuItem(ID_SELECT_ALL);
                }
                break;
            case KeyEvent.KEYCODE_X:
                if (canCut()) {
                    return onTextContextMenuItem(ID_CUT);
                }
                break;
            case KeyEvent.KEYCODE_C:
                if (canCopy()) {
                    return onTextContextMenuItem(ID_COPY);
                }
                break;
            case KeyEvent.KEYCODE_V:
                if (canPaste()) {
                    return onTextContextMenuItem(ID_PASTE);
                }
                break;
            }
        }
        return super.onKeyShortcut(keyCode, event);
    }

#28 楼 @spikeshen 呵呵,解决了.edittext 继承自 textview, 支持我上面列举的方法.
第一个坑是 ctrl+v 对应的 event 其实是 meta_ctrl_mask+v, 好几个 ctrl 相关的 event, 当时没测试这个.

第二个坑是搜狗输入法, 搜狗输入法会截获 ctrl+v, 会让你的输入变成了 v. 所以需要切换为系统默认的输入法.

两个大坑
另外 appium 是支持发送 keyevent 的. 我会补充对应的测试用例给官方. 不容易啊.

#31 楼 @seveniruby 牛逼,哈哈

#31 楼 @seveniruby 啥时候上个实例代码?

#33 楼 @spikeshen 我目前是手工复制, 然后使用 appium 发送粘贴操作, 如果让 appium 完整的支持自动复制和粘贴, 需要修改他们的代码。我也在考虑用什么样子的方式比较好。 可能需要在 appium 上开启一个插件机制来支持更多的功能。 比如开关 wifi 等, 这样也可以融合 cafe 和 althrun

#33 楼 @spikeshen 我目前是手工复制, 然后使用 appium 发送粘贴操作, 如果让 appium 完整的支持自动复制和粘贴, 需要修改他们的代码。我也在考虑用什么样子的方式比较好。 可能需要在 appium 上开启一个插件机制来支持更多的功能。 比如开关 wifi 等, 这样也可以融合 cafe 和 althrun

#35 楼 @seveniruby 思寒,appium 中复制粘贴是怎么做的呀,能不能上个实例代码

#35 楼 @seveniruby 请问你说 ctrl+v 对应的 event 其实是 meta_ctrl_mask+v,那么我实际使用的时候代码该怎么写,keycode113 你已经说不行了,那你是怎么解决的

#37 楼 @fantasy5074 @xiang2743 看我以前写的 ppt 吧, 里面有具体的例子代码。

#38 楼 @seveniruby 我自己试出来了,还是感谢你了,我还是贴出来,方便以后的人使用
driver.sendKeyEvent(50,AndroidKeyMetastate.META_CTRL_ON);

#38 楼 @seveniruby 还有个事情想麻烦问下,我来论坛没多久,不知道你以前写的 ppt 链接能发个不

#40 楼 @fantasy5074 你可以搜索以前的帖子。 地址我也忘记了。因为当时讲的那个 appium 版本太老了,很多地方不太适用了, 所以我基本不提了。帖子也埋没了。

#41 楼 @seveniruby 好的,谢谢,虽然已经解决问题了,但是还是要去拜读一下你的 ppt 的,学习一下

#42 楼 @fantasy5074 我们鼓励分享和交流。有收获可以多 show 下。希望每个人可以迅速的成长起来。 因为我最近工作忙, 所以每个问问题的人, 我都要让他们发帖到论坛。 一个是为了活跃论坛, 再一个也希望帖子的讨论可以为将来别人提供很好的参考。

#43 楼 @seveniruby 恩,这是个好的交流方案,我那个问题的解决也是看了你的帖子后照着你的思路来的。其实我开始的做法就是长按输入框,等粘贴按钮出来后点击手机上的某个坐标位置,这样只能局限在一些特定的环境运行,换了手机后要调整坐标,非常麻烦。

#25 楼 @seveniruby 我也碰到类似的困扰,测试的 app 里有类似的弹出的按钮,uiautomatorviewer 识别不到那个按钮控件,有什么解决的办法么。

我的一直定位不到元素不知什么问题,我的是 phonegap 开发的,contexts 中只有 nativeapp,没有 webview,有谁知道原因吗

#46 楼 @xtitmq 用 selendroid 模式, 或者在 4.4 版本上验证下

能模糊定位么,就是根据正则表达式来 find。
好吧,其实我是想问 appium 里面有没有查找文本的方法。

#39 楼 @fantasy5074 那剪贴板上的内容是不是提前复制好的呢

请问作者,appium 怎么获取粘贴板的数据。我用的 python

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