当前位置: 首页 > news >正文

(一)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 Clientappium只是一个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://electronjs.org

使用教程: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。如图:

 

转载于:https://www.cnblogs.com/leohou/p/10775854.html

相关文章:

  • 解密虚拟 DOM——snabbdom 核心源码解读
  • Python基础之列表
  • MyBatis配置多数据源
  • Asp.net core Identity + identity server + angular 学习笔记 (第三篇)
  • 【题解】四色定理
  • Android 实现动态背景“五彩蛛网”特效,让你大开眼界!
  • python高并发?
  • 雷林鹏分享:二级目录配置CI应用
  • Sym System Recovery 2013 ( 備份 操作 )
  • iOS-在项目中引入RSA算法
  • 简单的数学题
  • 关于JS引擎优化的理解
  • 如何优雅的备份账号相关信息
  • mybatis学习总结
  • 全球首个大规模光电芯片到来
  • 【React系列】如何构建React应用程序
  • android图片蒙层
  • cookie和session
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • iOS 系统授权开发
  • JavaScript的使用你知道几种?(上)
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • magento 货币换算
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • React Native移动开发实战-3-实现页面间的数据传递
  • React-Native - 收藏集 - 掘金
  • sublime配置文件
  • Zepto.js源码学习之二
  • 从0到1:PostCSS 插件开发最佳实践
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 微信小程序开发问题汇总
  • 译有关态射的一切
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​如何防止网络攻击?
  • #Z0458. 树的中心2
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (3)选择元素——(17)练习(Exercises)
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET Remoting学习笔记(三)信道
  • .net Stream篇(六)
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET中 MVC 工厂模式浅析
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • @Responsebody与@RequestBody
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [android] 切换界面的通用处理
  • [C#基础]说说lock到底锁谁?
  • [codeforces] 25E Test || hash
  • [E链表] lc83. 删除排序链表中的重复元素(单链表+模拟)
  • [HarekazeCTF2019]encode_and_encode 不会编程的崽