appium定位学习
前面也介绍过appium的一些定位方法,今天看到一篇博客,里面的方法总结的,就转载过来。
本文转自:https://www.cnblogs.com/Mushishi_xu/p/7685966.html
6.3 List定位
List故名思义就是一个列表,在python里面也有list这一个说法,如果你不是很理解什么是list,这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合,那么他的个数也就成了不确定性,所以这里需要用复数,所以在我们定位时我们不能够接着用find_element_by_id等等定位方式了,我们需要用他的复数形式find_elements_by_id,所有的定位方式都一样需要采用复数加s。这里我们接着上面的案例讲,如何使用list定位想定位的元素。首先看一下图片:
我们查看图片可以知道我们能够很轻松的通过id定位到整个父节点,我们接下来需要做的事定位这个父节点下所有的“android.widget.RelativeLayout”节点,同样的首先我们看一张图:
这里我们需要直接使用定位复数的方法来操作,直接看代码:
1
2
|
element = driver.find_element_by_id( "cn.com.open.mooc:id/rv_child" ) elements = element.find_elements_by_class_name( "android.widget.RelativeLayout" ) |
通过上面的代码我们直接定位了cn.com.open.mooc:id/rv_child 父节点下的所有android.widget.RelativeLayout子节点,现在我们需要怎么去操作这个子节点了,这里有两种方法:
1、前面我们讲了List你可以理解为一个数组或者一个集合,这里定位的所有子节点最后就成了个list,如果我们要访问这个list里面的某一个元素我们可以像访问数组中的数据一样通过下标访问。最后的代码就是下面这个样子:
1
2
3
|
element = driver.find_element_by_id( "cn.com.open.mooc:id/rv_child" ) elements = element.find_elements_by_class_name( "android.widget.RelativeLayout" ) elements[ 1 ].click(); |
上面的代码最后的结果是选择了JavaScript这个标签页面,然后点击进入。
备注:如果初学者不理解是如何通过下标访问的,这里说一下下标是从0开始,如果要访问list i中的第一个元素结果就是i[0],这部分知识会在后面python基础中会讲到。
2、如果你要访问List里面的元素,那么我们是否可以通过for循环语句来依次访问呢?这个在自动化中会经常用到。下面你可以通过这个思路自己去实战一下,看能否达到预期效果。下面看我的代码:
1
2
3
4
|
element = driver.find_element_by_id( "cn.com.open.mooc:id/rv_child" ) elements = element.find_elements_by_class_name( "android.widget.RelativeLayout" ) for ele in elements: ele.click() |
看上面的代码,我们通过循环去访问这个list里面的每一个元素,因为每次循环得到的都是其中一个元素,那么我们只需要在这个元素上加上你想要的操作即可,所以我们这里可以直接点击进去。
如果你动手做到这里会发现一个问题,你进入到第一个标签后没一会儿系统就会报错,为什么呢?你也可以试着去解决这个问题,后面我们会讲解这块儿知识。
6.4 内嵌H5定位
6.4.1 hybrid定位思考
在web自动化中我们会遇见frame的问题,在遇见这些内嵌的标签后我们需要做的就是切换窗口,那么在app自动化测试也有类似的情况就是我们经常看见的内嵌html,在我们原生的app中增加一个由html做成的页面。大家可以思考一下这种情况怎么操作。
6.4.2 hybrid常见定位问题分析
首先我们看一下下面一张图片:
通过右边的结构图我们能够清晰的看见整个页面就是一个webview,无论从什么角度来定位我们都不能够很好的进行,如果这个时候我们需要操作页面的元素就需要通过切换contexts来完成。但是在讲这个知识点之前大家先按照网上的知识来试一下处理这个页面,看能否成功。下面先说大家会遇见的问题:
1、可能你看到有的文章显示我们不需要通过切换contexts就能够完成定位,这样的情况有,但是那种情况作者只在微博登录、qq登录等第三方登录时遇见过,如果不是这样的情况而像上面的情况就没办法通过类似的方法进行完成,所以我希望读者遇见这种情况时自己动手去操作,看什么方式更加适合自己的项目。
2、需要切换contexts那么就需要获取页面的所有contexts,此时你通过官网或者其他文章的知识通过下面的方法来获取,可能会报错,这种情况关系不大。
1
2
|
webview = self .driver.contexts print webview |
如果你通过上面的代码来调试但是却报错,但是其他资料却没问题时你也不要着急,这里你需要确定两件事情:(1)、app打包的时候需要开启webview 的debug属性setWebContentDebuggingEnabled(true),这个直接让开发加上就好。一般情况是开启的,毕竟他们也要调试。(2)、你用很多手机去调试,发现有一些可以有一些不可以,但是你用模拟器却都可以,根据官方给出的答案是这个时候你需要去将手机root,然后再试。目前作者遇见了这两种情况,第二种我也是调试了很久才找到原因。
6.4.3 hybrid定位讲解
这两个问题解决后那么定位webview就轻松搞定,直接看代码:
1
2
3
|
webview = driver.contexts driver.switch_to.context(webview[ 1 ]) driver.find_element_by_link_text( 'PHP' ).click() |
对于初学者对于上面的代码可能不是很理解,下面我们看一下日志:
大家这里不用管我执行代码和之前的区别(多了一个self),我们看下面控制台的输出,输出的是一个list,前面说过list和数组类似,在这个list里面有两个元素“NATIVE_APP”,“WEBVIEW_cn_com_open_mooc”,第一个元素是我们原生的app的contexts,后面的则是我们的webview的context,所以我们需要获取webview的context时只需要通过这个list的下表来进行访问。
我们获取到webview的context后只需要通过driver.switch_to.context()进行切换就好。当切换后我们就可以像定位web一样进行定位。
看下面一张图片我们通过浏览器将h5页面打开:
通过上面的图片我们就能够很轻松的像web一样进行定位,也就可以使用web的一些定位方式。看到这里是不是觉得解决了一个难题呢?动手去吧。
6.4.4 hybrid问题实战
通过前面的学习我相信你已经有了一些实战能力,这里给大家提一个问题,我们获取到的contexts每次一定是两个吗?如果不是两个那么我们上面的脚本是不是就没办法用了呢?可以思考一下这里怎么解决,在看我们下面的思路以及解决方案。
无论在什么页面我们去获取contexts时他无论有几个但是他的类型是不是肯定都是一个list呢?既然是list那么我们是否可以取到里面的每一个值,然后把每一个值进行判断,只要找出我们的webview就可以了呢?下面看代码:
1
2
3
4
5
6
7
8
9
|
#获取当前页面所有的contexts webview = driver.contexts #在获取到的contexts list里面去挨个循环 for context in webview: #判断循环中单个的context是否是webview,如果是就进行切换,并且跳出循环 if 'WEBVIEW' in context: driver.switch_to.context(context) break driver.find_element_by_link_text( 'PHP' ).click() |
通过上面的代码我们是否完美的解决了内嵌H5的定位问题呢?动手吧
6.5 滑动定位
6.5.1 滑动定位方式
在app自动化中我们经常会遇见一个问题,我们需要查找的元素不在当前可展示的屏幕,至于在什么地方我们不知道,如果这个时候我们一直使用在当前页面查找,那么系统就会报错,为了解决这个问题我们就需要使用滑动查找。
首先的思路是我们在需要查找对象的页面查找一下该元素,判断该元素是否在当前页面,如果该元素不在该页面那么我们就需要去互动屏幕,到我们的下一屏幕,然后再进行查找,依次类推到找到为止。
6.5.2 滑动定位思路分析
方式我们有了,那么我们就需要知道实现这个功能应该有哪些点。下面跟着我一起来分析一下:
1、需要查找的元素我们是不是需要知道是什么呢?这个需要先确定
2、我们需要找的页面是在我们的当前页面的上方还是下方还是左方还是右方,我们不能确定,那么我们是否需要确定我们需要滑动的方向?
3、元素和方向有了,但是你知道我们每次需要滑动屏幕的多少吗?那么我们是否需要先去获取屏幕的大小,然后针对不同的方向去计算一个滑动的值呢?
万事具备只欠东风,去按照这个思路动手练习一吧。
6.5.3 滑动定位实战
一、根据上面的思路我们能首先来确定我们需要查找的元素,看下面图片:
我们要找实战推荐后面的“换一换”按钮,然后进行点击。首先我们查看他的定位信息
最后我们查找元素的定位信息代码如下:
1
|
self .driver.find_element_by_id( 'cn.com.open.mooc:id/tv_replace' ).click() |
对于有一定基础的人可能会觉得这个很low,但是有没有思考过一个问题,我们可以通过这个代码去执行,在没有这按钮的时候却会报错,也就没有办法执行下去了,那么需要怎么处理呢?所以这个时候我们需要有一些python的容错知识,即使我们的代码执行出错了,那么也要让他按照我们的意思执行下去。try.......except.......,这个就是我们python中的容错处理 ,下面我们看添加后的代码:
1
2
3
4
|
try : self .driver.find_element_by_id( 'cn.com.open.mooc:id/tv_replace' ).click() except Exception,e: print e |
try的意思就是告诉编译器试着去执行他下面这一段代码,如果报错了,那么你就把except里面的错误信息打印出来。
二、有了元素现在我们需要知道的是不是就是该怎么滑动界面了呢?首先我们看一下下面这张图片:
在我们使用app的过程中存在上面几种滑动情况,我们把整个界面看作为一个坐标系(x,y),如果我们需要往上滑动,那么我们是不是就是x轴不动,y轴从下往上动呢?往下就是x轴不动,y轴从上往下呢?同理左右滑动是不是就是应该y轴不动x轴左右滑动呢?可以好好去体会一下,脑海中有个画面。
在appium中滑动我们所需要使用的方法就是swipe函数,至于往哪个方向滑动就是看我们里面的x,y的值,如果我们需要下往上滑动那么我们就应该是:
1
|
self .driver.swipe(x1,y1,x1,y2,t) |
上面的代码x轴的值不变,y轴的值进行了变化,所以是沿着上下进行滑动的,从y2滑动到了y1点。t代表的是多少时间完成这个动作,或者说这个时间持续多久。
备注:这里需要注意的是屏幕的x,y的值是从左上角开始取的,左上角为(0,0),右下角是最大。
三、上面滑动的方法看着是好用,但是我们不可能每次都去填写一个坐标,那样太low,所以我们需要获取屏幕大小,直接看代码:
1
2
|
x = self .driver.get_window_size()[ 'width' ] y = self .driver.get_window_size()[ 'height' ] |
上面的代码就是我们获取到的x,y轴。通过思路我们的代码都有了,下面我们要做的就是对原来的代码进行修改,进行一个封装。下面看代码,这个暂时看不懂没关系,到后面我们学了python'基础就能够看懂了。先思路,然后了解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#获取屏幕大小 def getSize( self ): x = self .driver.get_window_size()[ 'width' ] y = self .driver.get_window_size()[ 'height' ] return (x,y) #向左滑动 def swipeLeft( self ,t): l = self .getSize() x1 = int (l[ 0 ] * 0.9 ) y1 = int (l[ 1 ] * 0.5 ) x2 = int (l[ 0 ] * 0.1 ) self .driver.swipe(x1,y1,x2,y1,t) #向右滑动 def swipeRight( self ,t): l = self .getSize() x1 = int (l[ 0 ] * 0.25 ) y1 = int (l[ 1 ] * 0.5 ) x2 = int (l[ 0 ] * 0.75 ) self .driver.swipe(x1,y1,x2,y1,t) #向上滑动 def swipeUp( self ,t): l = self .getSize() x1 = int (l[ 0 ] * 0.5 ) y1 = int (l[ 1 ] * 0.8 ) y2 = int (l[ 1 ] * 0.4 ) self .driver.swipe(x1,y1,x1,y2,t) time.sleep( 5 ) #向下滑动 def swipeDown( self ,t): l = self .getSize() x1 = int (l[ 0 ] * 0.5 ) y1 = int (l[ 1 ] * 0.25 ) y2 = int (l[ 1 ] * 0.75 ) self .driver.swipe(x1,y1,x1,y2,t) #查找元素,没找到滑动 def findLocal( self ): x = 1 while x = = 1 : if self .fact() = = 1 : self .swipeUp( 2000 ) time.sleep( 3 ) self .fact() else : print "找到了" x = 2 #递归 def fact( self ): n = 1 try : self .driver.find_element_by_id( 'cn.com.open.mooc:id/tv_replace' ).click() except Exception,e: return n |
通过查看上面代码的整个逻辑就是1、首先去查找元素,如果找到了我就直接点击。2、如果没有找到元素那么我就往上滑动(这里可以自己选择),滑动后再次进行查找,如果找到就点击,没有找到继续滑动。动手动手,这里知识点很重要!虽然后面会有一些替代方法,但是思路、算法很重要。
appium定位学习的更多相关文章
- appium定位元素java篇【转】
1.关于没有name,没有ID的元素的定位---通用篇解题思路:因为没有name,id:其实剩下的选择已不多,要么xpath,要么className.xpath木有好印象(稳定性不高,加之1.0x后需 ...
- jQuery Mobile的学习 jQuery Mobile工具栏、标题栏、页脚栏的定位学习
程序猿都非常赖.你懂的! 近期在做html5页面的开发,主要做智能终端设备的开发.对于内容比較少的页面,领导提出了要将页眉和页脚定位到网页的最上方和最下方.对于这种要求,事实上一点也只是分.但对于新手 ...
- iOSNsPredicate Appium 定位元素
Appium使用WebDriverAgent之后,新增了一种定位方法iOSNsPredicate,总结了一下使用方法: MobileElement photo = driver.findElement ...
- appium定位
一.链接基本信息 二.在appium界面中 三,定位 三.通过ui automator viewer抓取手机页面元素,点击红框按钮会抓取当前手机界面app全部元素;路径在sdk>tools下面的 ...
- appium定位h5
1.手机安装Chrome浏览器 2.开启USB调试模式,并使用安装的Chrome浏览器打开待测H5页面 3.在电脑端的Chrome浏览器输入chrome://inspect ...
- appium定位之xpath定位
前面也说过appium也是以webdriver为基的,对于元素的定位也基本一致,只是增加一些更适合移动平台的独特方式,下面将着重介绍xpath方法,这应该是UI层元素定位最强大的方法啦! 以淘宝app ...
- Appium定位方式总结
通过appium-desktop定位元素 ClassName Android Android的class属性对应ClassName定位方式,ClassName一般都是会重复的,可以通过index来获取 ...
- appium定位方法
1.id定位 driver.find_element_by_id("这里是resource-id") 2.name定位 (新版本的appium 1.7 已经没有这个定位方法了) d ...
- Appium定位 5 ——xpath
今天我们先来和大家说一下appium,上一次说到了定位,不知道大家定位的怎么样了,今天来说如何定位xpath,五分钟即可学会: 例1: 现在我想定位下面这个登录按钮: xpath该怎么写呢? 先不管三 ...
随机推荐
- 阅读笔记02-读懂HTTPS及其背后的加密原理
1 为什么需要https 使用https的原因其实很简单,就是因为http的不安全. 当我们往服务器发送比较隐私的数据(比如说你的银行卡,身份证)时,如果使用http进行通信.那么安全性将得不到保障. ...
- C#后台验证含0的正整数
Regex r = new Regex(@"^([1-9]\d*|[0]{1,1})$");//含0正整数 if (!r.IsMatch(GNumber)) { return f ...
- python pip报错pip._ vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
AttributeError: module 'pip' has no attribute 'main报错 找到安装目录下 helpers/packaging_tool.py文件,找到如下代码: de ...
- MySQL数据库忘记密码如何重新设置?
前 言当我们忘记了MySQL数据库密码后,该如何重新进行设置? 操作步骤步骤1:cmd打开命名窗口 步骤2:关闭正在运行的MySQL服务(命令:net stop mysql)(如果:此时MySQL正在 ...
- python selenium无法清除文本框内容问题
正常是我们在清除文本框内容的时候,都会使用 clear() 函数进行清除,但是有时候会出现,清除完成后再点击查询时,文本框的内容会再次自动填充,这个时候我们可以选择以下方式: #清空查询条件drive ...
- Python模块之pdfkit
1.安装依赖 pip install python-docx #Python下的Microsoft Word 2007工具 pip install PyPDF2 #Python下的PDF工具 pip ...
- FireFox浏览器导出文件名乱码
解决方案1 String codedFileName = "导出文件名.xls"; String agent = request.getHeader("USER-AGEN ...
- Struts2之下载
下载页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnco ...
- hdu6333 Problem B. Harvest of Apples(组合数+莫队)
hdu6333 Problem B. Harvest of Apples 题目传送门 题意: 求(0,n)~(m,n)组合数之和 题解: C(n,m)=C(n-1,m-1)+C(n-1,m) 设 ...
- 【转】sed命令的基本操作
原文链接 sed命令行格式为: sed [-option] ‘command’ 输入文本/文件 常用选项: -n∶取消默认的输出,使用安静(sile ...