AppCrawler AppCrawler 自动遍历工具 1.7.0 版本

思寒_seveniruby · 2016年09月28日 · 最后由 思寒_seveniruby 回复于 2017年05月03日 · 17 次阅读

新版本已经发布请关注 https://testerhome.com/topics/node83. 暂时结贴.

关于 AppCrawler 的先前介绍

相关文章: https://testerhome.com/search?q=appCrawler
腾讯安全部门也有使用 https://security.tencent.com/index.php/blog/msg/105
开源仓库地址: https://github.com/seveniruby/AppCrawler 最新版本在 1.7.0 分支

获取方式

百度网盘: https://pan.baidu.com/s/1bpmR3eJ
在线帮助文档: https://seveniruby.gitbooks.io/appcrawler/content/
AppCrawler 交流专区: https://testerhome.com/topics/node83 论坛帖我会有问必答
问答 QQ 群:177933995 能获取最新的内测版本参与交流,

自动遍历的价值

  • 回归测试.遍历基本的界面, 了解主要界面的可用性. 比如兼容性, 基本功能
  • 利用遍历获取 app 的加载时间和性能数据, 需要借助其他的性能数据抓取工具,比如 OneApm, NewRelic
  • 利用遍历验证 app 的内存泄漏以及稳定性等功能, 需要借助 LeakCanary 和 MLeaksFinder
  • UI diff 验证新老版本的功能差异. 并识别细节的问题
  • 抓取接口请求 辅助验证一些模块基本接口, 并辅助分析接口调用流程. 为接口测试做准备

1.7.0 版本改进

增加点击前后的截图

action 字段支持 scala 编程语句

配置文件已经转向 YAML 格式. 并提供了注释
beforeElementAction afterElementAction triggerActions 中的 action 都可以执行 scala 语句. 方便自定义.

---
triggerActions:
- action: "click"
  xpath: "//*[@resource-id='com.xueqiu.android:id/button_login']"
  times: 1
- action: "1560053xxxx"
  xpath: "//*[@resource-id='com.xueqiu.android:id/login_account']"
  times: 1
- action: "click"
  xpath: "//*[@resource-id='com.xueqiu.android:id/login_account']"
  times: 1
- action: "xxxxxx"
  xpath: "//*[@resource-id='com.xueqiu.android:id/login_password']"
  times: 1
#特定控件多遍历几次
tagLimit:
- xpath: //*[../*[@selected='true']]
  count: 12
- xpath: //*[../../*/*[@selected='true']]
  count: 12
startupActions:
- swipe("left")
- swipe("left")
- swipe("down")
- println(driver)
beforeElementAction:
- Thread.sleep(3000)
- println(driver.getPageSource())
afterElementAction:
- println(driver)
- println(driver.getPageSource)
- Thread.sleep(3000)

对比报告

一个简陋粗糙的 diff 报告. 这个只是初版. 具体什么范围需要对比需要工具使用者自己判断和控制
下个版本也会重点扩展这个功能. 增加字段的黑白名单和自定义规则控制.
如何遍历 app 并定义每个控件的命名是一门艺术. 请先看文档.

appcrawler --diff --master /Volumes/RamDisk/xueqiu_2/ --candidate /Volumes/RamDisk/xueqiu_6/ --report /tmp/diff/

动态插件和普通插件, 把插件文件放到工具的 plugins 目录下可以自动加载.

import com.xueqiu.qa.appcrawler._

//继承Plugin类
class DynamicPlugin extends Plugin{
  //重载start方法, 启动时执行
  override def start(): Unit ={
    log.info("hello from seveniruby")
  }
  //在每个element的动作执行前进行针对性的处理. 比如跳过
  override def beforeElementAction(element: UrlElement): Unit ={
    log.info("you can add some logic in here")
    log.info(element)
  }
  //当进入新页面会回调此接口
  override def afterUrlRefresh(url:String): Unit ={
    log.info(s"url=${getCrawler().currentUrl}")
  }
}

技术内幕

截图加红框是如何实现的

使用了 java 的 ImageIO 库, 可以对已有的图片进行标记. appcrawler 在点击前会先识别元素的位置, 并加上一个红框用于提示.

为什么用很慢的 xpath 来定位控件

希望是为每个控件赋予一个唯一的标记, 这样后续就可以进行定位分析和各种 diff 了. 对于大部分没有 id 和 name 的控件. 只有 xpath 能完整表示一个控件
appcrawler 用一种虚拟 dom 来代表实体 dom, 具体的类是 UrlElement

界面对比技术是怎么实现的

每个控件点击前后的截图和 dom 结构需要先拿到. PageSource 是一种 xml 结构. (WDA 里面是 json 结构).
需要先把 xml 和 json 等结构 flatten. 也就是扁平化. 然后对比简单的 kv 关系即可. 思路借鉴与 Twitter 的 Diffy.

版本计划

跳过了中间的 1.6.0 版本. 直接对外发布刚开发完成的 1.7.0 版本

# 1.8.0 [计划]
对子菜单的支持, 智能判断是否有子菜单
支持断点续传机制
支持自动重启appium机制, 用于防止iOS遍历内存占用太大问题
分离插件到独立项目

# 1.7.0
android跳到其他app后自动后退[完成]
截图复用优化提速 [完成]
报告增加点击前后的截图 [完成]
独立的report子命令 [完成]
配置支持动态指令 [完成]
配置不兼容 [重要]
支持自定义报告title [完成]

# 1.6.0 [内测]
增加动态插件 [完成]
支持beforeElementAction的afterElementAction配置 [完成]
修复app的http连接支持 [完成]
支持url白名单 [完成]
支持defineUrl的xpath属性提取 [完成]
未遍历控件用测试用例的cancel状态表示 [完成]
两次back之间的时间间隔设定为不低于4s防止粘连 [完成]

开源计划

  • 项目会在十一期间开源, 希望这种设计思路可以传播开造福整个测试行业.
  • 不过代码是 scala 编写请做好心理准备. 我也鼓励用 java 重新造轮子. 我会在开源的时候公布设计图

商业与开发者计划

为了更好的推进这个工具的发展. 这个产品的发展方向借鉴 burpsuite. 但是更开放, 框架主体开源. 靠好用的插件来为企业做商业化服务.

  • 插件收费体系. 后面会不断开发更好用的插件做商业服务. 比如用 OCR 技术做游戏 app 的自动遍历. 比如遍历的时候接口测试用例自动生成, 自动化的性能分析和代码流 diff 等
  • 服务收费. 可以付费定向为企业提供自动遍历的规则文件编写. 帮助企业更好的遍历自己的 app 并生成报告.
  • 开发者计划. 任何有能力的人都可以编写插件并提交给社区. 社区会协助帮助这些插件进行销售并把钱分成为插件开发者. 类似 app store, 开发者可以用 python java ruby 写插件.
  • 收入分成. 收入 5% 捐赠给社区. 90% 返回开发者. 5% 分给主框架负责开源的同学.

如果你有志于成为插件的开发者或者公司想快速的实现 app 的自动遍历. 可以联系我的微信 seveniruby

硬广

我和 stuq 业余合作了一个小的平民价格 (大约初级工程师两天的工资) 的培训体系, 讲解移动测试技术的. 主要面向希望在技术方向上有所提升的同学. 欢迎有需求的同学报名.
介绍地址在 https://testerhome.com/topics/5867 收入也会捐给社区 5% 快过年了, 攒点路费回家.

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

@seveniruby 出现这种错误如何解决

#1 楼 @18964835583 这是个一直遗留的 windows 的问题, 我晚上更新个版本给你. 作为临时方案. 可以添加这样一个配置

xpathAttributes:
- "name"
- "label"
- "value"
- "resource-id" 
- "content-desc"
- "index"
#- "text"

其实就是把 text 属性去掉. 一面文本内的内容有非法 windows 目录字符

#2 楼 @seveniruby说昨晚针对 windows 更新的版本呢?我在哪获取?

@seveniruby
版本迭代好快啊,非常好用的一款遍历工具!(汗!,刚才弹出页面,发错位置了。。。) 有个问题想请教,获取界面元素后,操作某控件后,跳转界面后,那么之前界面上未遍历的元素肯定是需要存储的,以便下次识别遍历情况,我看是存入到了 UrlElement 中,其中 UrlElement 中的 loc 我理解就是该控件的 xpath 规则,下次遍历到该界面就采用这个 xpath 规则获取控件,不知我理解是否准确。问题是,比如下面这个 “注册” 控件元素,获取到 WebElement 后,很想了解如何组装成 loc 存入 UrlElement 的?

Element='<android.widget.LinearLayout bounds="[0,435][360,484]" checkable="false" checked="false" class="android.widget.LinearLayout" clickable="true" content-desc="" enabled="true" focusable="false" focused="false" index="0" instance="2" long-clickable="false" package="com.xueqiu.android" password="false" resource-id="com.xueqiu.android:id/button_register_container" scrollable="false" selected="false" text="">
  <android.widget.TextView bounds="[0,435][360,484]" checkable="false" checked="false" class="android.widget.TextView" clickable="false" content-desc="" enabled="true" focusable="false" focused="false" index="0" instance="0" long-clickable="false" package="com.xueqiu.android" password="false" resource-id="com.xueqiu.android:id/button_register" scrollable="false" selected="false" text="注册" />
</android.widget.LinearLayout>'

#4 楼 @victors 恩, loc 后续会改名为 xpath 为了更好的表示控件, 搞了一层虚拟 dom UrlElement. 自动生成 xpath 只是一个小的算法. macaca-insepector 也实现了. 根据 xml 的结构一步步生成即可.

很幸运作为内测群的使用者,感谢。

#5 楼 @seveniruby 恩,看了一下 macaca-insepector 的 xpath, js 写的,目测 appcrawler 的算法和它还是有点小区别,加入了 index,resouce-id,text ... etc,更直观,我用的语言是 java,尝试 java 重造一下。 十一期间开源,这是大礼包啊,感谢思寒!😃 期待

@seveniruby 针对 windows 遗留问题 更新的版本呢?

看好公开设计图,用 node 重构

10楼 已删除

appcrawler -c xueqiu,yml 出现这个 Failed to load class "org.slf4j.impl.StaticLoggerBinder",不过好像没影响

试了下遍历雪球花 1 个小时,生成 400M 文件。 😆 看来雪球很稳定了,没一个错误

#1 楼 @18964835583 你确定用的是最新版本吗. 我本地测试了下. 没有这个问题

#12 楼 @jojotester 基本遍历的价值不大了. 该发现的问题都发现了. 以前动不动就崩溃的问题也很少了. 后面的重点会放到 Diff 上.

activity 的遍历覆盖率能统计吗?

#15 楼 @jojotester 暂时还没有,下个版本可以加

#13 楼 @seveniruby 我原来使用的是 1.4 版本 现在换成 1.5 版本不存在这个问题了 但是遍历内容中存在汉字的话 都变成了乱码

不管如何,思寒的东西,必需顶!!!

#17 楼 @18964835583 现在都 1.7 了. 你吓了我一跳. 我这边汉字是没有问题的. 我想可能是你们的 app 的编码特殊导致的吧. 你可以把某个页面的 dom 文件和 appcrawler.log 通过百度网盘分享给我.

#18 楼 @mikezhou 应该是有你的名字才这么积极吧. 😎

1.7 没有 jar 包?

下载了个 xueqiu8.4.apk,一打开就 Crash😂

23楼 已删除

昨天研究了下,发现只生成了少数的 har,观察发现都是 HTTP 的,故有一下问题请教:

  1. 代理录制 HTTPS,证书怎么获取啊
  2. 抓取数据是加密的,是否可以直接嵌入解密的插件 #20 楼 @seveniruby

2016-10-18 16:30:34 WARN [AndroidCrawler.findElementByUrlElement.893] find by xpath error no element found 2016-10-18 16:30:34 WARN [AndroidCrawler.doElementAction.1128] not found by UrlElement(com.youxuan.youxuan_server-YXNewLoginActivity,android.widget.Button,login_btn,登 录,//android.widget.LinearLayout[@index="2" and @resource-id="com.youxuan.youxuan_server:id/ll_content"]/android.widget.LinearLayout[@index="0"]/android.widget.LinearLayout[@index="0"]/android.widget.Button[@index="2" and @resource-id="com.youxuan.youxuan_server:id/login_btn" and @text="登 录"])

这种控件定位不了 怎么解决

#25 楼 @xenos_liu  那就是那个控件不存在嘛? 还是当时点击的时候没出现? 还是之前出现过, 但是点击的时候消失了? 这 xpath 你写的?

#26 楼 @seveniruby 该登录 控件页面加载时是置灰的,输入手机号 + 密码后 才可用,相应日志

@ seveniruby 你好,近期我们公司也在做 UI 遍历工具,我想请教下,新老界面的比对,你采用的是什么方式去做的,我们使用的是 uiautomator dump xml,然后进行解析

#28 楼 @ouyang995948959 我用的就是 appium 的 PageSource

@ seveniruby 我的设计方式跟你有些不一样, 我是将 app 所有元素看成一颗 元素树, 每个元素记录访问 计数, 所以我存在界面的判断, 点到当前 view ,需要判断跟之前出现过的界面的关系,来看是否保存 这个界面的元素; 不知道你的设计思路有没有这一块 怎样界定 这个界面与之前出现的界面是同一个,界面是动态变化的

@seveniruby uiautomator dump 的 xml,发现 会返回 当前界面 非可见元素,想请问下,appium 的 PageSource 有没有这个问题,我们一直用的 uiautomator,还没有接触过 appium

利用遍历获取 app 的加载时间和性能数据, 需要借助其他的性能数据抓取工具,比如 OneApm, NewRelic 利用遍历验证 app 的内存泄漏以及稳定性等功能, 需要借助 LeakCanary 和 MLeaksFinder

这两点,需要被测的 app,集成一些听云啊或者 leaks 这种 sdk 吗?

#32 楼 @addison 需要集成一定的 sdk. 不过听云的不付费几乎用不了. 我之前用过 oneapm 的. 还是不错的. 未付费的功能已经挺强了. 我们自己默认就集成了 bugly 的 sdk 以集成 LeakCanary 的研发内测版本. 其他的还有 iOS 的内存泄漏的 MLeaksFinder 和 facebook 发布的检测内存使用的几个 sdk. 现在基本每个功能都有对应的 sdk 可以用. 这个对测试人员的要求可能会高点.

#33 楼 @seveniruby 我刚去集成了 LeakCanary,改了一下 bulid grandle 文件,还需要修改 Application 里面的 onCreate 的代码。 bugly 的 sdk 在哪 可以共享下嘛 嘻嘻 那个是测试性能的?

#33 楼 @seveniruby 看到 bugly 了 是腾讯的啊,你们主要用来集成收集 crash 吗?我还以为你说的论坛里面的 bugly 呢😝

#35 楼 @addison 这是线上用的. umeng 和 bugly 用户群体还是挺多的. 我是顺便用来查崩溃. 其他的 sdk 都要求需要一定的代码功底. 入门有点难的.

一加配置文件就会报这个错 不加可正常运行 思寒大大 这个要怎么解决?@seveniruby

#37 楼 @superzhuo 别贴图, 贴错误信息.

#38 楼 @seveniruby E:\appcrawler1.7.1\appcrawler-1.7.1\appcrawler-1.7.1\bin>appcrawler -a customer1 026.apk -c customer.yml 2016-10-31 17:55:01 INFO [AppCrawler$.main.156] Find Conf E:\appcrawler1.7.1\app crawler-1.7.1\appcrawler-1.7.1\bin\customer.yml Exception in thread "main" java.nio.charset.MalformedInputException: Input lengt h = 1 at java.nio.charset.CoderResult.throwException(Unknown Source) at sun.nio.cs.StreamDecoder.implRead(Unknown Source) at sun.nio.cs.StreamDecoder.read(Unknown Source) at java.io.InputStreamReader.read(Unknown Source) at java.io.BufferedReader.fill(Unknown Source) at java.io.BufferedReader.readLine(Unknown Source) at java.io.BufferedReader.readLine(Unknown Source) at scala.io.BufferedSource$BufferedLineIterator.hasNext(BufferedSource.s cala:72) at scala.collection.Iterator$class.foreach(Iterator.scala:742) at scala.collection.AbstractIterator.foreach(Iterator.scala:1194) at scala.collection.TraversableOnce$class.addString(TraversableOnce.scal a:355) at scala.collection.AbstractIterator.addString(Iterator.scala:1194) at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala :321) at scala.collection.AbstractIterator.mkString(Iterator.scala:1194) at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala :323) at scala.collection.AbstractIterator.mkString(Iterator.scala:1194) at com.xueqiu.qa.appcrawler.CrawlerConf.load(CrawlerConf.scala:178) at com.xueqiu.qa.appcrawler.AppCrawler$.main(AppCrawler.scala:157) at com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala)

E:\appcrawler1.7.1\appcrawler-1.7.1\appcrawler-1.7.1\bin>

#39 楼 @superzhuo 配置文件的语法不正确. 第一行里面估计是混入了什么字符. windows 下用记事本编辑的话, 容易混入一个 BOM 字符. 得删掉.

#40 楼 @seveniruby 谢谢思寒大大 已解决👏

diff 功能不错, 学习了。

#31 楼 @ouyang995948959 你这个思路我试过,效率不是很高的,为什么不直接用选择子去递归获取页面元素,不过我一直解决不好的问题是一个元素被点击后导致页面位置变化了,但是元素是没有变的,这样的页面算是新页面吗?

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

版本 1.7 appcrawler -a 123.apk --capability noReset=true 报错
Error: Option --capability failed when given 'noReset'. Expected a key=value pai r Error: Unknown argument 'true' Try --help for more information.

#44 楼 @silly windows 下试试这样
appcrawler -a 123.apk --capability "noReset=true"

@seveniruby 直接 java -jar E:\自动化\appcrawler\appcrawler-1.7.1.jar -a E:\自动化\sfim_android.apk -t 300 -vv 出现应用启动界面后就退回了桌面,两台手机都这样。 执行雪球,一运行就异常终止了

#47 楼 @hsqzggg 你试试用最新版本的雪球试试. 你能说下你用的设备版本吗

雪球官网http://xqfile.imedao.com/android-release/xueqiu_871_11032322.apk刚下的。 两台手机: HHTC6C 5.1 平台; MX4pro 5.1 平台

#49 楼 @hsqzggg 你试试写上 appPackage 和 appActivity 吧.

@seveniruby 一样的。 测试 APK 通过你的工具运行后强制替换后,结束了一次运行,我再手动去运行,也是启动了 APK 的启动画面后就退出了,没报错也进不去。 而且应用没点开,工具也继续执行操作,不是加了参数就测什么 APK 么?这情况下,应该直接结束吧?

@seveniruby 日志。



2016-11-08 17:22:40 TRACE [AndroidCrawler.getAllElements.249] xpath=(//*[@package!=''])[1]
2016-11-08 17:22:40 TRACE [AndroidCrawler.getAllElements.250] get list
2016-11-08 17:22:40 TRACE [AndroidCrawler.apply.252] Map(long-clickable -> false, package -> com.meizu.flyme.launcher,
ame -> , clickable -> false, android.widget.FrameLayout -> null, checked -> false, tag -> android.widget.FrameLayout, c
ntent-desc -> , enabled -> true, label -> , checkable -> false, focusable -> false, focused -> false, selected -> false
 instance -> 0, text -> , bounds -> [0,0][1536,2560], xpath -> //hierarchy/android.widget.FrameLayout[@index="0"], clas
 -> android.widget.FrameLayout, scrollable -> false, resource-id -> , value -> , index -> 0, password -> false)
2016-11-08 17:22:40 INFO [AndroidCrawler.parsePageContext.548] appName = com.meizu.flyme.launcher
2016-11-08 17:22:40 INFO [DataRecord.append.13] append com.meizu.flyme.launcher
2016-11-08 17:22:41 INFO [AndroidCrawler.apply.48] get activity name null
2016-11-08 17:22:41 INFO [MiniAppium$.asyncTask.415] async task success
Exception in thread "main" java.lang.NullPointerException
        at scala.collection.immutable.StringLike$class.split(StringLike.scala:208)
        at scala.collection.immutable.StringOps.split(StringOps.scala:30)
        at com.xueqiu.qa.appcrawler.AndroidCrawler.getUrl(AndroidCrawler.scala:50)
        at com.xueqiu.qa.appcrawler.Crawler.parsePageContext(Crawler.scala:551)
        at com.xueqiu.qa.appcrawler.Crawler.refreshPage(Crawler.scala:535)
        at com.xueqiu.qa.appcrawler.Crawler$$anonfun$runStartupScript$1.apply(Crawler.scala:192)
        at com.xueqiu.qa.appcrawler.Crawler$$anonfun$runStartupScript$1.apply(Crawler.scala:190)
        at scala.collection.immutable.List.foreach(List.scala:381)
        at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
        at scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
        at com.xueqiu.qa.appcrawler.Crawler.runStartupScript(Crawler.scala:190)
        at com.xueqiu.qa.appcrawler.Crawler.start(Crawler.scala:155)
        at com.xueqiu.qa.appcrawler.AppCrawler$.startCrawl(AppCrawler.scala:283)
        at com.xueqiu.qa.appcrawler.AppCrawler$.main(AppCrawler.scala:262)
        at com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala)

@seveniruby 晕死了,现在卸载了测试 APK 的包名,重新安装,也进不去 APK 了。其他应用还正常启动。重启也这样。病毒呀?

#53 楼 @hsqzggg @seveniruby 拷贝到手机上安装就可以进入测试 APK 了。用 adb install 的话就无法进入。工具在后台做了什么呢?

@seveniruby 现在通过手动安装还有去掉-a 参数,可以进入测试 APK 的登录界面了。但进去后点了密码输入框后,就切到了桌面乱点,登录界面的 “忘记密码” 和登录按钮都没操作。加了包名后,不能像 monkey 一样限定在测试包名里么?

2016-11-08 18:47:29 ERROR [AndroidCrawler.start.167] key not found: xpath
2016-11-08 18:47:29 ERROR [AndroidCrawler.start.168]
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.collection.MapLike$cl
ass.default(MapLike.scala:228)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.collection.AbstractMa
p.default(Map.scala:59)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.collection.mutable.Ha
shMap.apply(HashMap.scala:65)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler$$anonfun$getElementByElementActions$2.apply(Crawler.scala:1171)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler$$anonfun$getElementByElementActions$2.apply(Crawler.scala:1170)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.collection.immutable.
List.foreach(List.scala:381)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.collection.generic.Tr
aversableForwarder$class.foreach(TraversableForwarder.scala:35)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.collection.mutable.Li
stBuffer.foreach(ListBuffer.scala:45)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler.getElementByElementActions(Crawler.scala:1170)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler.crawl(Crawler.scala:723)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler$$anonfun$1.apply$mcV$sp(Crawler.scala:160)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler$$anonfun$1.apply(Crawler.scala:160)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler$$anonfun$1.apply(Crawler.scala:160)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] scala.util.Try$.apply(Try.s
cala:192)
2016-11-08 18:47:29 ERROR [AndroidCrawler.apply.169] com.xueqiu.qa.appcrawler.Cr
awler.start(Crawler.scala:160)

是我的定位用錯了方式嗎?配置文件一定要使用 xpath 定位嗎?

#56 楼 @l84222780 是的, 统一使用 XPath 定位. 你把 id 的定位换成 xpath 行为即可比如 //*[@id='ddd']

#55 楼 @hsqzggg 支持, 你多研究下吧. 有 app 的白名单的. 默认放的很松.

#57 楼 @seveniruby 了解,謝謝!~

#43 楼 @erickyang 不算新页面,你说的这个 直接用选择子去递归获取页面元素?能详细说下,目前做到什么进度了?方便交流下吗

#31 楼 @ouyang995948959 请问您是采用什么方式判断是否是新界面的,我也在做 UI 遍历测试,希望探讨一下,谢谢。

前辈能否详细讲解一下判断界面是否是新界面的过程,具体对 xml 进行了什么操作,又是如何对比的?谢谢。

配置文件里的每个参数可以提供下具体的使用意思吗?谢谢。

请问运行结果中什么情况定义为 faile 呢? 发生 crash 么? 如果 android crash 了能抓到 log 么?

2016-12-01 18:26:19 INFO [AppCrawler$.main.156] Find Conf D:\appUi\kr.yml
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type scala.collection.immutable.Map from String value ('deviceName:"emulator-5554" appPackage:"com.jr36.guquan" appActivity:".ui.activity.MainActivity"'); no single-String constructor/factory method
 at [Source: java.io.StringReader@7857fe2; line: 18, column: 4] (through reference chain: com.xueqiu.qa.appcrawler.CrawlerConf["androidCapability"])
        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:255)
        at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:993)
        at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:316)
        at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromString(ValueInstantiator.java:207)
        at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:335)
        at com.fasterxml.jackson.module.scala.deser.UnsortedMapDeserializer.deserialize(UnsortedMapDeserializerModule.scala:76)
        at com.fasterxml.jackson.module.scala.deser.UnsortedMapDeserializer.deserialize(UnsortedMapDeserializerModule.scala:39)
        at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:490)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:260)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3807)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2797)
        at com.xueqiu.qa.appcrawler.DataObject$class.fromYaml(DataObject.scala:36)
        at com.xueqiu.qa.appcrawler.DataObject$.fromYaml(DataObject.scala:128)
        at com.xueqiu.qa.appcrawler.CrawlerConf.load(CrawlerConf.scala:184)
        at com.xueqiu.qa.appcrawler.AppCrawler$.main(AppCrawler.scala:157)
        at com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala)

加上配置文件报这个错是因为什么啊,求大神解答

求助,在 mac 上运行时,appium 经常给出 instruments exited with code 0,然后 app 就退出了,无法再进行遍历这种问题怎么解决啊

67楼 已删除

我试过了,貌似有些地方并没有遍历:

只遍历了黑色方形里面的两个,其他的区域没有遍历

手机已经安装了 apk,然后运行就出现这种问题,请问是什么原因呢?

我知道我的问题了。jar 包不能直接运行在盘的根目录下。

Caused by: org.openqa.selenium.WebDriverException: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:4723 [/127.0.0.1] failed: 拒绝连接 Build info: version: '2.53.1', revision: 'a36b8b1cd5757287168e54b817830adce9b0158d', time: '2016-06-30 19:26:09' System info: host: 'zengqingyi-OptiPlex-3020', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '3.5.0-36-generic', java.version: '1.8.0_05' Driver info: driver.version: AndroidDriver at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:84) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:644) ... 15 more Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:4723 [/127.0.0.1] failed: 拒绝连接 at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:158) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55) at org.openqa.selenium.remote.internal.ApacheHttpClient.fallBackExecute(ApacheHttpClient.java:144) at org.openqa.selenium.remote.internal.ApacheHttpClient.execute(ApacheHttpClient.java:90) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:142) at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:69) ... 16 more Caused by: java.net.ConnectException: 拒绝连接 at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:74) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141) ... 29 more

启动 appcrawler 用命令 java -jar appcrawler.jar -a **.apk 的时候报错。 在 Linux 系统 , 哪位大神遇到过这个问题,指点一下呀

@seveniruby 好久没有更新了,最近刚把 1.2.1 更新到 1.7.1.发现直接用原来能跑的 config 文件,跑起来会有一个 NoSuchElementException,这个是哪里需要调整么? 2016-12-26 15:20:56 INFO [IOSCrawler.apply.151] client 2016-12-26 15:20:56 INFO [IOSCrawler.runStartupScript.188] run startup script 2016-12-26 15:20:56 INFO [IOSCrawler.runStartupScript.189] ListBuffer() Exception in thread "main" java.util.NoSuchElementException at scala.collection.LinearSeqOptimized$class.last(LinearSeqOptimized.scala:148) at scala.collection.immutable.List.last(List.scala:84) at scala.collection.generic.TraversableForwarder$class.last(TraversableForwarder.scala:58) at scala.collection.mutable.ListBuffer.last(ListBuffer.scala:45) at com.xueqiu.qa.appcrawler.DataRecord.last(DataRecord.scala:40) at com.xueqiu.qa.appcrawler.Crawler.start(Crawler.scala:156) at com.xueqiu.qa.appcrawler.AppCrawler$.startCrawl(AppCrawler.scala:283) at com.xueqiu.qa.appcrawler.AppCrawler$.main(AppCrawler.scala:262) at com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala)

现在回退次数限制好像没有了?怎么设置呢

看了 appcrawler 的介绍,感觉很不错,想让大神评估一下: 0.appcrawler 可以遍历 app 的所有组件和功能吗?需要配置文件来指导吗? 1.用 appcrawler 可以实现批量 app 遍历吗?比如从应用市场下载的 100000 个 app 都要遍历。 2.假如可以批量遍历,每个都需要单独写配置文件吗,有没有比较简单的通用方法或想法?

已经设置了 backButton,但是在 1.7.1 上遍历的时候还是碰到 urlBlackList should return,找不到返回按钮是什么错误呢,输出 you should define you back button in the conf file? urlBlackList 需要单独配置啥么 backButton:

  • "//*[@name='nav_icon_back']"
  • "//*[@name='Back']"
  • "//*[@name='返回']"
  • "//UIAButton[@name='取消']"
  • "//UIAButton[@label='返回']"
  • "//UIAButton[@name='关闭']"
  • "//UIAButton[@name='首页']"

#75 楼 @guaixiaomei 他貌似没没找到你的 backButton 配置, 或者 backButtton 里面的返回按钮都没找到. 才会报错. 你确定@name是对的吗, 会不会是 label 什么的.

#72 楼 @guaixiaomei 配置文件不兼容. 有些配置项名字修改了

各位在实际使用过程中,发现 app 的 bug 大概多少呢?

你好 当我在 yml 文件里使用 swipe 方法时,Appcrawler 不能触发事件

 ERROR [IOSCrawler.apply.169] com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala)
2017-01-12 14:23:39 ERROR [IOSCrawler.start.170] create new session
2017-01-12 14:23:39 ERROR [IOSCrawler.setupAppium.44] error
2017-01-12 14:23:39 ERROR [IOSCrawler.setupAppium.45] A new session could not be created. Details: Problem getting session data for driver type IosDriver; does it implement 'get driverData'? (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 24 milliseconds
Build info: version: '2.53.1', revision: 'a36b8b1cd5757287168e54b817830adce9b0158d', time: '2016-06-30 19:26:09'
80楼 已删除

#80 楼 @CleverPotato override 是什么意思. 你是怎么用的? 错误信息里面提示的是不能 create session. 还没到执行 action 的阶段.

我这边已经好使了 刚才我把 xpath 写错了就变成那样了 打扰了😂

思寒真棒!用起来!

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

求解答:一直报这个错,求帮忙! 命令:java -jar appcrawler-1.7.1.jar -a xueqiu.apk --capability"appPackage=com.xueqiu.android,appActivity=.view.WelcomeActivityAlias"

报错: Exception in thread "main" org.openqa.selenium.remote.UnreachableBrowserExceptio n: Could not start a new session. Possible causes are invalid address of the rem ote server or browser start-up failure. Build info: version: 'unknown', revision: 'unknown', time: 'unknown' System info: host: 'FH2GSADPEVC4GUC', ip: '10.88.122.10', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_101' Driver info: driver.version: AndroidDriver at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.ja va:665) at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGener icMobileDriver.java:40) at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1) at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.jav a:1) at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriv er.java:249) at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.jav a:131) at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.jav a:144) at io.appium.java_client.DefaultGenericMobileDriver.(DefaultGeneri cMobileDriver.java:36) at io.appium.java_client.AppiumDriver.(AppiumDriver.java:114) at io.appium.java_client.AppiumDriver.(AppiumDriver.java:132) at io.appium.java_client.android.AndroidDriver.(AndroidDriver.java :92) at com.xueqiu.qa.appcrawler.AndroidCrawler.setupAppium(AndroidCrawler.sc ala:37) at com.xueqiu.qa.appcrawler.Crawler.start(Crawler.scala:130) at com.xueqiu.qa.appcrawler.AppCrawler$.startCrawl(AppCrawler.scala:283)

at com.xueqiu.qa.appcrawler.AppCrawler$.main(AppCrawler.scala:262) at com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala) Caused by: org.openqa.selenium.WebDriverException: org.apache.http.conn.HttpHost ConnectException: Connect to 127.0.0.1:4723 [/127.0.0.1] failed: Connection refu sed: connect Build info: version: 'unknown', revision: 'unknown', time: 'unknown' System info: host: 'FH2GSADPEVC4GUC', ip: '10.88.122.10', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_101' Driver info: driver.version: AndroidDriver at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumComm andExecutor.java:84) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.ja va:644) ... 15 more Caused by: org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:4 723 [/127.0.0.1] failed: Connection refused: connect at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect (DefaultHttpClientConnectionOperator.java:158) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect( PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClie ntExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec. java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java :184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java :110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttp Client.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttp Client.java:71) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttp Client.java:55) at org.openqa.selenium.remote.internal.ApacheHttpClient.fallBackExecute( ApacheHttpClient.java:144) at org.openqa.selenium.remote.internal.ApacheHttpClient.execute(ApacheHt tpClient.java:90) at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExe cutor.java:142) at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumComm andExecutor.java:69) ... 16 more Caused by: java.net.ConnectException: Connection refused: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketI mpl.java:85) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.ja va:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocket Impl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java :188) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocke t(PlainConnectionSocketFactory.java:74) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect (DefaultHttpClientConnectionOperator.java:141) ... 29 more

求助,想在 startupActions 中添加 点击控件操作,需要怎样添加呢, tap() / click()

2017-02-06 16:19:15 ERROR [IOSCrawler.setupAppium.46] A new session could not be created. Details: Appium's IosDriver does not support xcode version 8.2.1. Apple has deprecated UIAutomation. Use the "XCUITest" automationName capability instead. (WARNING: The server did not provide any stacktrace information)

不支持 XCUITest 吗? 安装的 appium 版本是 1.6.3

#86 楼 @edisonye-github 你把英文翻译下就知道答案了

启动已安装过的 app,一直报错,求助。

E:\bianli\share\appcrawler\appcrawler-1.7.1\bin>appcrawler --capability appPacka
ge=com.transsion.phoenix,appActivity=.com.proj.sun.activity.LaunchActivity
Error: Option --capability failed when given 'appPackage'. Expected a key=value
pair
Error: Unknown argument 'com.transsion.phoenix'
Error: Unknown argument 'appActivity'
Error: Unknown argument '.com.proj.sun.activity.LaunchActivity'
Try --help for more information.

E:\bianli\share\appcrawler\appcrawler-1.7.1\bin>

Appium's IosDriver does not support xcode version 8.2.1. Apple has deprecated UIAutomation. Use the "XCUITest" automationName capability instead. Xcode8 和 iOS10 之后,appium 获取元素的方法变了,试了貌似不能运行了。有什么解决办法吗?

@seveniruby 很高兴能够用到你的工具,但是目前有两个问题请指教,一是 APP 主页面没有返回的 Button,但是遍历之后回到主界面很容易触发返回按钮,应用就退出去了,测试也就结束了,请指教如何加入黑名单;二是目前大部分 APP 都是混合编程的,控件定位不是很方便,遍历的时候经常出现一个控件点来点去的,其它的控件不去点击,请问如何有效的让工具更高效的遍历呢?感激!

我想问一下,启动 app 后,向左滑动 3 次是默认的吗?还是通过配置文件控制的。。 我在配置文件都注释掉了 这个 startup,还是会滑动。。

移动互联 回复

我也遇到了这个问题,你现在解决了么

93楼 已删除

java -jar appcrawler-1.8.0.jar -p ios --capability udid=xxx,用不起来, Driver info: io.appium.java_client.ios.IOSDriver 2017-03-31 13:44:36 ERROR [IOSCrawler.setupAppium.47] 2017-03-31 13:44:36 INFO [IOSCrawler.start.136] init MiniAppium 2017-03-31 13:44:36 INFO [IOSCrawler.start.137] platformName=iOS driver=null 2017-03-31 13:44:36 INFO [IOSCrawler.start.139] waiting for app load 2017-03-31 13:44:44 INFO [IOSCrawler.start.141] driver=null 2017-03-31 13:44:44 INFO [IOSCrawler.start.142] get screen info Exception in thread "main" java.lang.NullPointerException at com.xueqiu.qa.appcrawler.Crawler.getDeviceInfo(Crawler.scala:212) at com.xueqiu.qa.appcrawler.Crawler.start(Crawler.scala:143) at com.xueqiu.qa.appcrawler.AppCrawler$.startCrawl(AppCrawler.scala:311) at com.xueqiu.qa.appcrawler.AppCrawler$.main(AppCrawler.scala:291) at com.xueqiu.qa.appcrawler.AppCrawler.main(AppCrawler.scala)

是不是,是 webview 的原因?解决了吗?😀

刚用这个工具,若若的问下,在遍历元素的时候,点击了程序退出的确定,无法往下执行了,这个问题通过黑名单解决吗? 好像文档中没有提过 json 文件格式的定义,-c 参数文件的 json 文件是 json 格式的吗?

开始用的 1.8 的 jar 包,换成 1.7.1 的 zip 工具,没有问题了,还没做看源码,但使用文档中没有看到关于遍历什么时候算结束?apk 只跑了一半的 tab 页,就 finish 了。

2017-04-06 18:42:15 WARN [AndroidCrawler.isExit.358] backRetry 6 > backMaxRetry 5 need exit backButton:

这里如何设置,设置其他 TAB 的 xpath 路径好像不生效

遇到了与@liwanyin 相同的问题 APP 主页面没有返回的 Button,但是遍历之后回到主界面很容易触发返回按钮,应用就退出去了,测试也就结束了

嗨,出现一个很奇怪的问题,问下你 xueqiu.yml 配置文件中,设置如下: triggerActions:

  • action: "18910942890" xpath: "//*[@resource-id='com.qshealthcare.com.wtmd:id/et_login_number']" times: 1
  • action: "7704" xpath: "//*[@resource-id='com.qshealthcare.com.wtmd:id/et_login_code']" times: 1
  • action: "click" xpath: "//*[@resource-id='com.qshealthcare.com.wtmd:id/bt_login_goto']" times: 1

最后的演示效果:输入手机号的位置,每次都是先自动输入 2017,然后自动清空后输入 201118910942 为什么不是 我设置的 18910942890 呢?

周小丽 回复

一定是你在其他地方设置了自动输入 2017 了吧

配置文件中 我全文搜索 就没搜到 2017 哦,但奇怪的是 我今天执行又正常了,真心没明白。对了问个问题,就是如何避免每次自动安装 app??因为我们的登陆密码是手机验证码,在配置文件中设置一个刚获取的验证码后,一但 app 重启到登录页面后,用配置文件中的验证码就告知过期了

周小丽 回复

appium 的选项里面可以配置不用重新安装.

appium --session-override --no-reset 是这样启动吗?我试过了,还是提示是否安装,我点击取消,然后重启 app 后还是进入到了登陆页面。(前提:已手动登陆 app 了的)

java -jar appcrawler-1.7.1.jar -a app-release.apk --capability "noReset=true" 试验了也会提示安装,取消后,自动重启 app 到登录页面

@seveniruby 我在 1.7.0 使用过程中,发现以下问题: 一、- action: "13067754297" xpath: "//*[@resource-id='com.xueqiu.android:id/login_account']" times: 1 页面有这个控件但不会输入,只会点击,与 appium 版本有关系吗?

二、自动遍历快结束了,会返回到桌面,执行了其他的应用,但次数不多

最后还想问一下,你例子的 xueqiu.apk 是哪个版本的?

大神,我们现在的产品多半使用混合框架,原生 +H5 的样式,如何使用 appcrawler 实现 H5 页面的遍历呢?后续是否有这样的 appcrawler 版本更新?

为什么我的 apk,一测到 dialog 就跳出来了,停止遍历了

陈琦 回复

告诉我你们的 app, 近期会发布支持 h5 的版本

wing 回复

问题解决了吗?

遍历之后回到主界面很容易触发返回按钮,应用就退出去了,测试也就结束了,请指教如何加入黑名单

yaowh 回复

看文档, 通过 backButton 设置和最后遍历两个机制, 都可以做到.

@seveniruby xueqiu.yml 基本没改,为什么我使用 xueqiu.apk,在登录页面,这两个控件不会输入,“com.xueqiu.android:id/login_account”,“com.xueqiu.android:id/login_password”,可能是什么原因?谢谢回复

勇少 回复

那就是雪球的新版本已经修改了这两个控件吧. 这个配置文件需要根据版本迭代进行持续维护的.

115楼 已删除

我是查看过控件 id 是没有错的,但还是不能输入,自动遍历时只会点击

android 控件查找 xpath 是自己拼凑的,还是全用 app-inpector 弄出来的呢

俊俊陈 回复

我是用 uiautomatorviewer 来获取控件的 ID,然后查看 xueqiu.yml,发现控件 ID 与思寒的一样,然后我就修改了 xueqiu.yml 里面参数 androidCapability,然后就愉快的自动遍历了 我目前使用的 Appium 版本:1.4.13。这个有关系吗???

我的常德,这个就是原生框架加 H5 页面的。 请问,支持 H5 的版本预计什么时候发布呢?

windows 命令行文字是乱码,APP 文字是繁体字,请问怎么解决?

如下:id="android:id/title_template"]/android.widget.TextView[@index="0" and @resource-id="android:id/alertTitle" and contains(@text, '瀹夎 Google ')]" classname="AppCrawler_5" time="0.0">

liu 回复

你问下其他的同学吧, 如果别人也是这个问题我再解决

好的,谢谢!~

Error: Cannot parse launchActivity from manifest.null @seveniruby 一般怎么解决啊?

启动 appium- desktop 1.6.4 beta 运行 AppCrawler 报错: Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: A new session could not be created. Details: Appium's IosDriver does not support xcode version 8.3.1. Apple has deprecated UIAutomation. Use the "XCUITest" automationName capability instead. (WARNING: The server did not provide any stacktrace information) 有什么解决的办法吗? @seveniruby

liu 回复

我也遇到这个问题。你解决了吗

淼淼淼 回复

没有,我以为只有我这样呢!~

liu 回复

把输出调整为 utf8 就可以了

好的,我试试,谢谢!~

@seveniruby yml 配置文件中,

startupActions:
- swipe("left")
- swipe("left")

运行的时候提示:

2017-05-03 10:34:03 INFO [AppCrawler$.saveReqDom.69] save reqDom to 4 2017-05-03 10:34:03 INFO [AppiumClient.dsl.105] eval swipe("left") 2017-05-03 10:34:03 INFO [Runtimes$.eval.66] swipe("left") :11: error: not found: value swipe swipe("left") ^

麻烦看看什么问题。

请用 2.0 版本. 目前这个已经过期了. 新版本中的 api 是 driver.swipe

思寒_seveniruby 关闭了讨论 05月03日 04:06
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册