appium-desktop定位元素原理
初衷
最近在编写Android App自动化用例,其中元素定位相对来说耗费的时间比较长。我们都知道Appium-desktop拥有自己的录制功能,我们就在想是不是可以把录制功能跟我司的自动化框架(ATK)打通,直接生成我们框架可以识别的自动化脚本,甚至可以产出java版的IDE。这样就可以节省大量的元素定位和脚本编写时间。所以最近通过debug分析Appium-desktop的源码,梳理了Appium-desktop定位/查找元素的原理。
由于appium-desktop使用react编写了大量的组件,且使用的是electron框架,所以先来了解一下几个概念以及调试代码需要的环境准备
一、写在前面
1、区分几个概念
| 名称 | 概念 | 下载链接 | 现状 |
|---|---|---|---|
| appium/appium server | 这是appium体系的核心,它本身也是一个web接口服务,所以也会被称为appium server,对外默认开启包括4723等多个端口 |
1、安装nodejs;2、安装appium server,命令npm install -g appium;3、运行appium server appium --session-override |
appium Server不在更新,后续使用Appium Desktop |
| Appium Desktop | 为了Appium更好用、入门更容易、让调试和界面分析更方便,官方开发了GUI的工具,因为它内嵌了appium,很多人会以为它叫appium,其实它是个综合性的桌面工具。只有分析时候才用,平时都是用appium。 | https://github.com/appium/appium-desktop/releases/ | 按照自己的节奏发布,并拥有自己的版本控制系统 |
| Appium Client | appium只是一个web接口,他接受http请求,所以各个语言都可以自己封装发送请求,于是就有appium下的各个子项目 | https://github.com/appium/appium/blob/master/docs/en/about-appium/appium-clients.md | 每个子项目各自迭代 |
| Appium GUI | 也是把Appium server封装成一个图形界面,降低使用门槛。前几年开始接触appium,大部分教程都是基于这个GUI来讲解的,所以很多人说起Appium就认为是这个 | https://bitbucket.org/appium/appium.app/downloads/ | 2015停止更新 |
2、一门语言(react)、一个框架(electron)
2.1、React
2.1.1、概念
React是Facrbook内部的一个JavaScript类库,不是一个完整的MVC框架,最多可以认为是MVC中的V。React推荐以组件的方式去重新思考UI构成,将UI上每一个功能相对独立的模块定义成组件,然后将小的组件通过组合或者嵌套的方式构成大的组件,最终完成整体UI的构建。
2.1.2、专注
它专注于两件事情--更新DOM和响应事件。
2.1.3、工作流
React以渲染函数为基础。这些函数读入当前的状态,将其转换为目标页面上的一个虚拟表现。只要React被告知状态有变化,他就会重新运行这些函数,计算出页面的一个新的虚拟表现,接着自动把结果转换成必要的DOM更新来反映新的表现
2.1.4、more
更多介绍:https://react.docschina.org
使用教程:http://www.runoob.com/react/react-component-life-cycle.html
2.2、electron
2.2.1、概念
Electron是用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。 Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来。
2.2.2、核心
electron核心可以分成2个部分,主进程和渲染进程。主进程连接着操作系统和渲染进程,可以把它看做页面和计算机沟通的桥梁。渲染进程就是我们所熟悉前端环境了。主进程与渲染进程之间不能直接互相访问,需要通过ipcMain和ipcRenderer进行通信。
主进程:有且只有一个主进程, package.json中的main字段标明脚本的进程称为主进程.比如appium-desktop的主进程为dist/main.js的进程。
渲染进程:每个页面都运行在自己的渲染进程。
通信:主进程和渲染进程通过消息监听机制通信。其中主进程通过ipcMain.on和event.sender.send实现监听渲染进程发来的消息和向渲染进程发送消息;渲染进程通过ipcRenderer.on和ipcRenderer.send实现监听主进程发来的消息和向主进程发送消息。
2.2.3、调试
渲染进程调试:可以在开发者工具里的 Sources进行断点调试。开发者工具通过这段代码开启mainWindow.webContents.openDevTools(),需要查看该段断码是否被注释。appium-desktop是通过是否dev环境来判断是否开启,启动脚本传递NODE_ENV=development即为dev环境。package.json中有写好的脚本(start-dev),直接npm run start-dev即可。
主进程调试:通过electron进行调试,配置在Run/Debug Configurations中的Node.js运行环境中。如下图

2.2.4、more
使用教程:https://www.w3cschool.cn/electronmanual/
2.3、环境
2.3.1、安装cnpm
因为npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,我们一般使用淘宝cnpm。
命令:
npm install -g cnpm --registry=https://registry.npm.taobao.org
npm config set registry http://registry.cnpmjs.org
2.3.2、install和build
下载依赖:cnpm install
编译:cnpm run build. 一般Electron工程不需要build,直接运行就可以,appium-desktop因为主进程在build后的dist目录下,所以需要build。
二、流程图
获取页面dom文件,重新解析并渲染出来

三、主要步骤源码解析
appium-desktop定位元素主要是把获取到的当前页面的DOM文件解析为json,并增加key字段作为后续操作的唯一标示,然后通过React把解析后的DOM文件重新渲染出来。通过事件点击获取到key,通过唯一key就可以从json中获取到控件的所有属性信息
3.1、获取页面dom文件

通过bootstrap脚本执行命令 获取页面dom文件,返回文件类似:
<?xml version=\"1.0\" encoding=\"UTF-8\"?><hierarchy rotation=\"0\"><android.widget.FrameLayout index=\"0\" text=\"\" class=\"android.widget.FrameLayout\" package=\"com.zhangdan.app\" content-desc=\"\" checkable=\"false\" checked=\"false\" clickable=\"false\" enabled=\"true\" focusable=\"false\" focused=\"false\" scrollable=\"false\" long-clickable=\"false\" password=\"false\" selected=\"false\" bounds=\"[0,0][1080,1920]\" resource-id=\"\" instance=\"0\">
可以看出文件中显示关于控件的所有信息
3.2、把dom文件解析为json

3.2.1、xmlDoc
通过xmlDoc = (new DOMParser()).parseFromString(source, 'application/xml'); 获取到的xmlDoc其实已经是树状的控件信息,如图

3.2.2、element
返回元素信息包括 children,tagname,attributes,xpath,path. xpath是元素的全路径;path是控件在json中的顺序,这个是后面识别的唯一标示;attributes元素的属性信息

3.3、重新定义元素

appium-desktop 重新根据自己的需求增加了key=path的属性作为后续操作的标示,并使用react的功能渲染一个虚拟DOM显示。
3.4、加载各个功能组件
appium-desktop 把各个功能点都作为组件来使用,所以源码中compenents下面都是功能组件,然后利用react动态渲染DOM。如图:

appium-desktop定位元素原理的更多相关文章
- appium desktop 定位弹出框时报错
今天在定位真机APP的时候,弹出框的内容死活定位不到,只能定位到背景的内容. 问题:appium desktop 定位弹出框时报错,定位不到,只能定位到背景的内容. 分析: 定位工具找不到弹出框的元素 ...
- appium关于定位元素
Windows上定位元素我用的是uiautomatorviewer 这个工具在你的SDK-tools目录下,点击uiautomatorviewer.bat启动,注意appium在跑的时候是取不到的 工 ...
- Appium Android定位元素与操作
文章写得很好,转载备用 一.常用识别元素的工具 uiautomator:Android SDK自带的一个工具,在tools目录下 monitor:Android SDK自带的一个工具,在tools目录 ...
- Appium Inspector定位元素与录制简单脚本
本次以微信为例, 使用Appium自带的Inspector定位工具定位元素, 以及进行最最最简单脚本的录制: capabilities = { "platformName": &q ...
- Selenium 定位元素原理,基本API,显示等待,隐式等待,重试机制等等
Selenium 如何定位动态元素: 测试的时候会遇到元素每次变动的情况,例如: <div id="btn-attention_2030295">...</di ...
- Appium之定位元素
常用的appium元素定位工具: (1)Android SDK 中提供的元素定位工具uiautomatorviewer: (2)AppiumDesktop提供的元素定位工具Appium Inspec ...
- appium -- Xpath定位元素
如文章<Appium基于安卓的各种FindElement的控件定位方法实践>所述,Appium拥有众多获取控件的方法.其中一种就是根据控件所在页面的XPATH来定位控件. 本文就是尝试通过 ...
- python+appium-desktop:安卓(android)7.0以上使用appium无法定位元素(无法refresh)且 无法运行脚本
--解决方法: 启动appium时配置中添加: "automationName":"uiautomator2" --扩展: 想支持安卓7.0及以上版本需要满足一 ...
- Appium与Appium Desktop的区别
Appium-Server的配置,在之前的博文已有介绍,基于Python的Appium环境搭建合集,所以在此处就不详细介绍了.今天主要来分享下Appium-Server和Appium desktop在 ...
随机推荐
- 配置服务器nginx 教程
https://www.cnblogs.com/wangzhongqiu/p/6527346.html
- 软件配置管理及SVN的使用
一.配置管理 1. 管理整个软件生命周期中的配置项 配置项:软件生命周期中产出的各种输出成果,如需求文档.设计文档.代码.测试相关文档 2.管理配置项的变化(核心) 3.使用配置管理 ...
- .net core使用App.Metrics+InfluxDB+Grafana进行APM监控
一.InfluxDB 1.下载InfluxDB wget https://dl.influxdata.com/influxdb/releases/influxdb-1.5.2.x86_64.rpm 2 ...
- 【源码解析】Sharding-Jdbc模块分析
最新的2.0版本的Sharding-Jdbc版本,由于需要支持动态配置加载,所以最新的模块信息如下: |-sharding-jdbc |-sharding-jdbc-core |-api |-cons ...
- BZOJ_4238_电压_树上差分+dfs树
BZOJ_4238_电压_树上差分+dfs树 Description 你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)” ...
- Error【0003】:配置桥接网络报错
1.1 问题背景 在配置cosole宿主机的桥接网络环境时,在修改完/etc/sysconfig/ifcg-ethx和/etc/sysconfig/ifcg-brx后,执行service networ ...
- poj 3687
Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them ...
- Flash与EEPROM
网上找的,感觉说的不错 FLASH 和EEPROM的最大区别是FLASH按扇区操作,EEPROM则按字节操作,二者寻址方法不同,存储单元的结构也不同,FLASH的电路结构较简单,同样容量占芯片面积较小 ...
- dubbo+zookeeper的使用
我们讨论过Nginx+tomcat组成的集群,这已经是非常灵活的集群技术,但是当我们的系统遇到更大的瓶颈,全部应用的单点服务器已经不能满足我们的需求,这时,我们要考虑另外一种,我们熟悉的内容,就是分布 ...
- js继承之组合继承(结合原型链继承 和 借用构造函数继承)
在我的前两篇文章中,我们已经介绍了 js 中实现继承的两种模式:原型链继承和借用构造函数继承.这两种模式都存在各自的缺点,所以,我们考虑是否能将这二者结合到一起,从而发挥二者之长.即在继承过程中,既可 ...