Android KEYCODE键值对应大全
KEYCODE列表
电话键
键名 描述 键值
KEYCODE_CALL 拨号键5
KEYCODE_ENDCALL 挂机键6
KEYCODE_HOME 按键Home3
KEYCODE_MENU 菜单键82
KEYCODE_BACK 返回键4
KEYCODE_SEARCH 搜索键84
KEYCODE_CAMERA 拍照键27
KEYCODE_FOCUS 拍照对焦键80
KEYCODE_POWER 电源键26
KEYCODE_NOTIFICATION 通知键83
KEYCODE_MUTE 话筒静音键91
KEYCODE_VOLUME_MUTE 扬声器静音键164
KEYCODE_VOLUME_UP 音量增加键24
KEYCODE_VOLUME_DOWN 音量减小键25
控制键
键名 描述 键值
KEYCODE_ENTER 回车键66
KEYCODE_ESCAPE ESC键111
KEYCODE_DPAD_CENTER 导航键 确定键23
KEYCODE_DPAD_UP 导航键 向上19
KEYCODE_DPAD_DOWN 导航键 向下20
KEYCODE_DPAD_LEFT 导航键 向左21
KEYCODE_DPAD_RIGHT 导航键 向右22
KEYCODE_MOVE_HOME 光标移动到开始键122
KEYCODE_MOVE_END 光标移动到末尾键123
KEYCODE_PAGE_UP 向上翻页键92
KEYCODE_PAGE_DOWN 向下翻页键93
KEYCODE_DEL 退格键67
KEYCODE_FORWARD_DEL 删除键112
KEYCODE_INSERT 插入键124
KEYCODE_TAB Tab键61
KEYCODE_NUM_LOCK 小键盘锁143
KEYCODE_CAPS_LOCK 大写锁定键115
KEYCODE_BREAK Break/Pause键121
KEYCODE_SCROLL_LOCK 滚动锁定键116
KEYCODE_ZOOM_IN 放大键168
KEYCODE_ZOOM_OUT 缩小键169
组合键
键名 描述
KEYCODE_ALT_LEFT Alt+Left
KEYCODE_ALT_RIGHT Alt+Right
KEYCODE_CTRL_LEFT Control+Left
KEYCODE_CTRL_RIGHT Control+Right
KEYCODE_SHIFT_LEFT Shift+Left
KEYCODE_SHIFT_RIGHT Shift+Right
基本
键名 描述 键值
KEYCODE_0 按键'0'7
KEYCODE_1 按键'1'8
KEYCODE_2 按键'2'9
KEYCODE_3 按键'3'10
KEYCODE_4 按键'4'11
KEYCODE_5 按键'5'12
KEYCODE_6 按键'6'13
KEYCODE_7 按键'7'14
KEYCODE_8 按键'8'15
KEYCODE_9 按键'9'16
KEYCODE_A 按键'A'29
KEYCODE_B 按键'B'30
KEYCODE_C 按键'C'31
KEYCODE_D 按键'D'32
KEYCODE_E 按键'E'33
KEYCODE_F 按键'F'34
KEYCODE_G 按键'G'35
KEYCODE_H 按键'H'36
KEYCODE_I 按键'I'37
KEYCODE_J 按键'J'38
KEYCODE_K 按键'K'39
KEYCODE_L 按键'L'40
KEYCODE_M 按键'M'41
KEYCODE_N 按键'N'42
KEYCODE_O 按键'O'43
KEYCODE_P 按键'P'44
KEYCODE_Q 按键'Q'45
KEYCODE_R 按键'R'46
KEYCODE_S 按键'S'47
KEYCODE_T 按键'T'48
KEYCODE_U 按键'U'49
KEYCODE_V 按键'V'50
KEYCODE_W 按键'W'51
KEYCODE_X 按键'X'52
KEYCODE_Y 按键'Y'53
KEYCODE_Z 按键'Z'54
符号
键名 描述
KEYCODE_PLUS 按键'+'
KEYCODE_MINUS 按键'-'
KEYCODE_STAR 按键'*'
KEYCODE_SLASH 按键'/'
KEYCODE_EQUALS 按键'='
KEYCODE_AT 按键'@'
KEYCODE_POUND 按键'#'
KEYCODE_APOSTROPHE 按键''' (单引号)
KEYCODE_BACKSLASH 按键'\'
KEYCODE_COMMA 按键','
KEYCODE_PERIOD 按键'.'
KEYCODE_LEFT_BRACKET 按键'['
KEYCODE_RIGHT_BRACKET 按键']'
KEYCODE_SEMICOLON 按键';'
KEYCODE_GRAVE 按键'`'
KEYCODE_SPACE 空格键
小键盘
键名 描述
KEYCODE_NUMPAD_0 小键盘按键'0'
KEYCODE_NUMPAD_1 小键盘按键'1'
KEYCODE_NUMPAD_2 小键盘按键'2'
KEYCODE_NUMPAD_3 小键盘按键'3'
KEYCODE_NUMPAD_4 小键盘按键'4'
KEYCODE_NUMPAD_5 小键盘按键'5'
KEYCODE_NUMPAD_6 小键盘按键'6'
KEYCODE_NUMPAD_7 小键盘按键'7'
KEYCODE_NUMPAD_8 小键盘按键'8'
KEYCODE_NUMPAD_9 小键盘按键'9'
KEYCODE_NUMPAD_ADD 小键盘按键'+'
KEYCODE_NUMPAD_SUBTRACT 小键盘按键'-'
KEYCODE_NUMPAD_MULTIPLY 小键盘按键'*'
KEYCODE_NUMPAD_DIVIDE 小键盘按键'/'
KEYCODE_NUMPAD_EQUALS 小键盘按键'='
KEYCODE_NUMPAD_COMMA 小键盘按键','
KEYCODE_NUMPAD_DOT 小键盘按键'.'
KEYCODE_NUMPAD_LEFT_PAREN 小键盘按键'('
KEYCODE_NUMPAD_RIGHT_PAREN 小键盘按键')'
KEYCODE_NUMPAD_ENTER 小键盘按键回车
功能键
键名 描述
KEYCODE_F1 按键F1
KEYCODE_F2 按键F2
KEYCODE_F3 按键F3
KEYCODE_F4 按键F4
KEYCODE_F5 按键F5
KEYCODE_F6 按键F6
KEYCODE_F7 按键F7
KEYCODE_F8 按键F8
KEYCODE_F9 按键F9
KEYCODE_F10 按键F10
KEYCODE_F11 按键F11
KEYCODE_F12 按键F12
多媒体键
键名 描述
KEYCODE_MEDIA_PLAY 多媒体键 播放
KEYCODE_MEDIA_STOP 多媒体键 停止
KEYCODE_MEDIA_PAUSE 多媒体键 暂停
KEYCODE_MEDIA_PLAY_PAUSE 多媒体键 播放/暂停
KEYCODE_MEDIA_FAST_FORWARD 多媒体键 快进
KEYCODE_MEDIA_REWIND 多媒体键 快退
KEYCODE_MEDIA_NEXT 多媒体键 下一首
KEYCODE_MEDIA_PREVIOUS 多媒体键 上一首
KEYCODE_MEDIA_CLOSE 多媒体键 关闭
KEYCODE_MEDIA_EJECT 多媒体键 弹出
KEYCODE_MEDIA_RECORD 多媒体键 录音
手柄按键
键名 描述
KEYCODE_BUTTON_1 通用游戏手柄按钮 #1
KEYCODE_BUTTON_2 通用游戏手柄按钮 #2
KEYCODE_BUTTON_3 通用游戏手柄按钮 #3
KEYCODE_BUTTON_4 通用游戏手柄按钮 #4
KEYCODE_BUTTON_5 通用游戏手柄按钮 #5
KEYCODE_BUTTON_6 通用游戏手柄按钮 #6
KEYCODE_BUTTON_7 通用游戏手柄按钮 #7
KEYCODE_BUTTON_8 通用游戏手柄按钮 #8
KEYCODE_BUTTON_9 通用游戏手柄按钮 #9
KEYCODE_BUTTON_10 通用游戏手柄按钮 #10
KEYCODE_BUTTON_11 通用游戏手柄按钮 #11
KEYCODE_BUTTON_12 通用游戏手柄按钮 #12
KEYCODE_BUTTON_13 通用游戏手柄按钮 #13
KEYCODE_BUTTON_14 通用游戏手柄按钮 #14
KEYCODE_BUTTON_15 通用游戏手柄按钮 #15
KEYCODE_BUTTON_16 通用游戏手柄按钮 #16
KEYCODE_BUTTON_A 游戏手柄按钮 A
KEYCODE_BUTTON_B 游戏手柄按钮 B
KEYCODE_BUTTON_C 游戏手柄按钮 C
KEYCODE_BUTTON_X 游戏手柄按钮 X
KEYCODE_BUTTON_Y 游戏手柄按钮 Y
KEYCODE_BUTTON_Z 游戏手柄按钮 Z
KEYCODE_BUTTON_L1 游戏手柄按钮 L1
KEYCODE_BUTTON_L2 游戏手柄按钮 L2
KEYCODE_BUTTON_R1 游戏手柄按钮 R1
KEYCODE_BUTTON_R2 游戏手柄按钮 R2
KEYCODE_BUTTON_MODE 游戏手柄按钮 Mode
KEYCODE_BUTTON_SELECT 游戏手柄按钮 Select
KEYCODE_BUTTON_START 游戏手柄按钮 Start
KEYCODE_BUTTON_THUMBL Left Thumb Button
KEYCODE_BUTTON_THUMBR Right Thumb Button
待查
键名 描述
KEYCODE_NUM 按键Number modifier
KEYCODE_INFO 按键Info
KEYCODE_APP_SWITCH 按键App switch
KEYCODE_BOOKMARK 按键Bookmark
KEYCODE_AVR_INPUT 按键A/V Receiver input
KEYCODE_AVR_POWER 按键A/V Receiver power
KEYCODE_CAPTIONS 按键Toggle captions
KEYCODE_CHANNEL_DOWN 按键Channel down
KEYCODE_CHANNEL_UP 按键Channel up
KEYCODE_CLEAR 按键Clear
KEYCODE_DVR 按键DVR
KEYCODE_ENVELOPE 按键Envelope special function
KEYCODE_EXPLORER 按键Explorer special function
KEYCODE_FORWARD 按键Forward
KEYCODE_FORWARD_DEL 按键Forward Delete
KEYCODE_FUNCTION 按键Function modifier
KEYCODE_GUIDE 按键Guide
KEYCODE_HEADSETHOOK 按键Headset Hook
KEYCODE_META_LEFT 按键Left Meta modifier
KEYCODE_META_RIGHT 按键Right Meta modifier
KEYCODE_PICTSYMBOLS 按键Picture Symbols modifier
KEYCODE_PROG_BLUE 按键Blue “programmable”
KEYCODE_PROG_GREEN 按键Green “programmable”
KEYCODE_PROG_RED 按键Red “programmable”
KEYCODE_PROG_YELLOW 按键Yellow “programmable”
KEYCODE_SETTINGS 按键Settings
KEYCODE_SOFT_LEFT 按键Soft Left
KEYCODE_SOFT_RIGHT 按键Soft Right
KEYCODE_STB_INPUT 按键Set-top-box input
KEYCODE_STB_POWER 按键Set-top-box power
KEYCODE_SWITCH_CHARSET 按键Switch Charset modifier
KEYCODE_SYM 按键Symbol modifier
KEYCODE_SYSRQ 按键System Request / Print Screen
KEYCODE_TV 按键TV
KEYCODE_TV_INPUT 按键TV input
KEYCODE_TV_POWER 按键TV power
KEYCODE_WINDOW 按键Window
KEYCODE_UNKNOWN 未知按键
手册
https://zimaoxy.com/m/post/for/
循环定时器学习Timer
Timer 对象
- from threading import Timer
- def hello():
- print "hello, world"
- t = Timer(10.0, hello)
- t.start()
- 复制代码
10秒后输出:
- hello, world
- 复制代码
重点研究 t = Timer(10.0, hello)
这句代码,python 提供了一个Timer 对象,它会在指定的时间后执行某一操作;它的完整形式:
- class threading.Timer(interval, function, args=[], kwargs={})
- 复制代码
interval
是时间间隔,function
是可调用的对象,args
和 kwargs
会作为 function
的参数。
注意:这里只会执行一次 function,而不会一直定时执行,且 Timer 在执行操作的时候会创建一个新的线程。
Timer
在 python2 和 python3 有点区别:
- # python2.7
- def Timer(*args, **kwargs):
- return _Timer(*args, **kwargs)
- # python3.7
- class Timer(Thread):
- pass
- 复制代码
在 python3,Timer
是 Thread
的子类;在 python2,_Timer
是 Thread
的子类,而 Timer
只是 _Timer
类的工厂方法。
上面的代码只会打印一次 hello, world
后退出,那么如何循环间隔打印呢?
粗陋的循环定时器
一种方法是在 function
里继续注册一个 Timer,这样就可以在下一个 interval
继续执行 function
;
- from threading import Timer
- def hello():
- print "hello, world"
- Timer(10.0, hello) .start()
- t = Timer(10.0, hello)
- t.start()
- 复制代码
每隔 10 秒输出一个 hello, world
。
达到效果了,但是这里面好像有点问题。回到 Timer 本身,它是一个 thread,每次循环间隔操作,系统都要创建一个线程,然后再回收,这对系统来说开销很大。如果时间间隔 interval 很短,系统会一下子创建很多线程,这些线程很难快速回收,导致系统内存和cpu资源被消耗掉。 所以不提倡在 function 里继续注册一个 Timer。
更 pythonic 循环定时器
这里有更 pythonic 的方法:
- from threading import _Timer
- def hello():
- print "hello, world"
- class RepeatingTimer(_Timer):
- def run(self):
- while not self.finished.is_set():
- self.function(*self.args, **self.kwargs)
- self.finished.wait(self.interval)
- t = RepeatingTimer(10.0, hello)
- t.start()
- 复制代码
重点研究 RepeatingTimer
类,它继承了 threading._Timer
,但是重写了父类的 run
方法。这是 Python2 的写法,python3 中 RepeatingTimer
应该继承 threading.Timer
。
为什么要重写 Thread
的 run
方法?
_Timer
是一个 Thread
子类,我们先看看 Thread
类的 run
用法。
- from threading import Thread
- def hello():
- print "hello, world"
- # 继承 Thread
- class MyThread(Thread):
- # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
- def run(self):
- hello()
- t = MyThread()
- t.start()
- 复制代码
Thread 对象的完整定义:
- class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
- 复制代码
其中 run
方法代码:
- class Thread(_Verbose):
- def run(self):
- try:
- if self.__target:
- self.__target(*self.__args, **self.__kwargs)
- finally:
- # Avoid a refcycle if the thread is running a function with
- # an argument that has a member that points to the thread.
- del self.__target, self.__args, self.__kwargs
- 复制代码
标准的 run
方法用于执行用户传入构造函数的 target
方法。 子类可以重写 run
方法,把要执行的代码写到 run
里面,线程在创建后,用户调用 start()
方法会运行 run()
方法。
所以 RepeatingTimer
重写 _Timer
的 run() 方法,可以改变线程的执行体,当我们调用 RepeatingTimer
的 start() 方法时会执行我们重写的 run() 方法。
再看看 RepeatingTimer 类中的 while not self.finished.is_set()
语句,self.finished.is_set()
直到 True
才会退出循环,定时器才结束。finished
是 threading.Event
对象。一个 Event
对象管理着一个 flag 标志,它能被 set()
方法设置为 True,也能被 clear()
方法设置为 False,调用 wait([timeout])
线程会一直 sleep 到 flag 为 True 或超时时间到达。
我们知道定时器有一个 cancel()
方法可以提前取消操作。它其实是调用 Event.clear()
方法提前让 wait
方法结束等待,并且判断在 flag 为 true 的情况下不执行定时器操作。具体的代码:
- class _Timer(Thread):
- """Call a function after a specified number of seconds:
- t = Timer(30.0, f, args=[], kwargs={})
- t.start()
- t.cancel() # stop the timer's action if it's still waiting
- """
- def __init__(self, interval, function, args=[], kwargs={}):
- Thread.__init__(self)
- self.interval = interval
- self.function = function
- self.args = args
- self.kwargs = kwargs
- self.finished = Event()
- def cancel(self):
- """Stop the timer if it hasn't finished yet"""
- self.finished.set()
- def run(self):
- self.finished.wait(self.interval)
- if not self.finished.is_set():
- self.function(*self.args, **self.kwargs)
- self.finished.set()
- 复制代码
所以 RepeatingTimer
的 run 方法会一直执行 while
循环体,在循环体了会执行用户传入的 function
对象,并等待指定的时间。当用户想退出定时器时,只需要调用 cancel
方法,将 flag 置为 True 便不会继续执行循环体了。这样便完成了一个还不错的循环定时器。
随机数
- random() 函数中常见的函数如下:
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- import random
- print( random.randint(1,10) ) # 产生 1 到 10 的一个整数型随机数
- print( random.random() ) # 产生 0 到 1 之间的随机浮点数
- print( random.uniform(1.1,5.4) ) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数
- print( random.choice('tomorrow') ) # 从序列中随机选取一个元素
- print( random.randrange(1,100,2) ) # 生成从1到100的间隔为2的随机整数
- a=[1,3,5,6,7] # 将序列a中的元素顺序打乱
- random.shuffle(a)
print(a)
冷面做的梦
冷面做的梦
675***721@qq.com
3年前 (2018-05-23)
- wwoo55
229***8519@qq.com
278
Python 生成随机数、随机字符串
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import random
import string
# 随机整数:
print random.randint(1,50)
# 随机选取0到100间的偶数:
print random.randrange(0, 101, 2)
# 随机浮点数:
print random.random()
print random.uniform(1, 10)
# 随机字符:
print random.choice('abcdefghijklmnopqrstuvwxyz!@#$%^&*()')
# 多个字符中生成指定数量的随机字符:
print random.sample('zyxwvutsrqponmlkjihgfedcba',5)
# 从a-zA-Z0-9生成指定数量的随机字符:
ran_str = ''.join(random.sample(string.ascii_letters + string.digits, 8))
print ran_str
# 多个字符中选取指定数量的字符组成新字符串:
print ''.join(random.sample(['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'], 5))
# 随机选取字符串:
print random.choice(['剪刀', '石头', '布'])
# 打乱排序
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print random.shuffle(items)
元素定位
APP元素定位和操作
webdriver 提供了八种元素定位方法:
在 Python 语言中对应的定位方法如下:
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
Appium 完全继承了 WebDriver 中所定义的这些方法,除此之外对其进行了扩展,以便适合移动端对象的定位与操作
定位详解
1.常用定位方式:
通过id定位
(取resource-id的值):
driver.find_element_by_id("com.wuba.zhuanzhuan:id/azo")
也可以直接用id后面的内容driver.find_element_by_id("azo")
通过class_name定位
(取class的内容)
driver.find_element_by_class_name("android.widget.RelativeLayout")
通过xpath定位
(取xpath得内容)
driver.find_element_by_xpath("//android.widget.LinearLayout[1]/android.widget.XXX")
通过text定位
(需要使用uiautomator的定位方式,使用text的内容)
driver.find_elements_by_android_uiautomator("new UiSelector().text(\"+关注\")")
使用这里需要注意一下,通过text定位的结果是个list,不能直接click。所以如果要点击需要取数组的值,比如下面是点击找到的第一个元素
driver.find_elements_by_android_uiautomator("new UiSelector().text(\"+关注\")")[0].click()
通过css_selector定位(webview)
只适用于webview的html页面,继承自webdriver,与pc版本的UI测试一致
driver.find_element_by_css_selector()
通过link_text定位(webview)
只适用于webview容器中的html页面,继承自webdriver,与pc版本的UI测试一致
driver.find_element_by_link_text()
通过name定位
web view容器中的html页面可以用name定位,native并没有name属性
driver.find_element_by_name()
2.定位元素的另一种写法:find_element(by,value)
find_element_by_方式(value)实际调用的都是find_element(by,value)
需要导入这个包:from selenium.webdriver.common.by import By
例如:定位id为ag2的元素
方式一:driver.find_element_by_id("ag2”)
方式二:driver.find_element(By.ID,"ag2")
这个操作的好处是可以直接把操作的by和value放到一个元组里,然后调用通用方法来传参获得元素结果
cateid=(By.ID,"ag2")
driver.find_element(*cateid).click()
by的操作可以是:
By.ID 相当于by_id
By.CLASS_NAME 相当于by_class_name
By.XPATH 相当于by_xpath
By.NAME 相当于by_name
By.TAG_NAME 相当于by_tag_name
By.CSS_SELECTOR 相当于by_css_selector
By.LINK_TEXT 相当于by_link_text
3.find_elements_by_定位方式(value)返回元素数组
用法与find_element_by_方式(value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果
例如:通过class_name定位到多个元素,我想点击第一个元素
driver.find_elements_by_class_name("android.widget.RelativeLayout”)[0].click()
4.返回元素数组的另一种写法:find_elements(by,value)
用法与find_element(by,value)一致,但是返回一个数组。可以通过数组的索引来访问具体的某个结果
例如:通过class_name定位到多个元素,我想点击第一个元素
driver.find_elements(By.CLASS_NAME,"android.widget.RelativeLayout”)[0].click()
5.通过元素定位元素
可以先找到某个元素,然后再进一步定位元素
find_element_by_class_xpath(“xxx”).find_element_by_name(“yyy")
ClassName
Android
Android的class属性对应ClassName定位方式,ClassName一般都是会重复的,可以通过index来获取需要的元素。(从0开始查找dom树中的同名class属性)
iOS
iOS的type属性对应CLassName定位方式,ClassName一般都是会重复的,可以通过index来获取需要的元素。(从0开始查找dom树中的同名class属性)
ID
Android
Android的resource-id对应ID定位方式,这个id也可能存在重复情况,可以通过index来获取需要的元素。(从0开始查找dom树中的同名resource-id属性)
使用appium-desktop来获取元素时,如果提示有id的定位方式,则可以只接获取,代表唯一。
XPATH
Android
Android的Xpath定位与PC的XPATH定位大同小异,可以通过相对路径的定位方式定位,区别在于,这里相对路径定位的//后只可以接Android的class属性或*。(//android.widget.Button[@text="登 录"])
iOS
iOS10 以上使用XCUITest框架后,原生框架不支持XPATH,Appium进行了转换,速度很慢不建议使用。
AccessibilityId
Android
Android的content-desc属性对应AccessibilityId定位方式,这个content-desc属性专门为残障人士设置,如果这个属性不为空则推荐使用。
iOS
iOS的label和name属性都对应AccessibilityId定位方式,如果有则推荐使用。
AndroidUIAutomator
Android的源生测试框架的定位方式,定位速度快。推荐使用牢记常用的几种。
打开方法:
常用定位方法
# 这个在运行时,调用的是Android自带的UI框架UiAutomator的Api
# 介绍几个简单常用的,text、className、resource-id
# text
# 匹配全部text文字
driver.find_element_by_android_uiautomator('new UiSelector().text("手机号")')
# 包含text文字
driver.find_element_by_android_uiautomator('new UiSelector().textContains("机")')
# 以text什么开始
driver.find_element_by_android_uiautomator('new UiSelector().textStartsWith("手")')
# 正则匹配text
driver.find_element_by_android_uiautomator('new UiSelector().textMatches("^手.*")')
# className
driver.find_elements_by_android_uiautomator('new UiSelector().className("android.widget.TextView")')
# classNameMatches
driver.find_elements_by_android_uiautomator('new UiSelector().classNameMatches("^android.widget.*")')
# resource-id、resourceIdMatches 类似我们html id 这个可能重复,
driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.syqy.wecash:id/et_content")') # description driver.find_element_by_android_uiautomator('new UiSelector().description("S 日历")') # descriptionStartsWith driver.find_element_by_android_uiautomator('new UiSelector().descriptionStartsWith("日历")') # descriptionMatches driver.find_element_by_android_uiautomator('new UiSelector().descriptionMatches(".*历$")')
#组合定位
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/tab_name").text("我的")').click()
#父子关系定位
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/title_container").childSelector(text("股票"))')
#兄弟关系定位
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("com.xueqiu.android:id/title_container").fromParent(text("股票"))')
#滚动查找
self.driver.find_element_by_android_uiautomator('new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text("查找的元素文本").instance(0));')
iOSPredicateString
仅支持iOS10以上,可以多个属性同时定位,推荐。(替代XPATH)
driver.find_elements_by_ios_predicate("label == '登录'")
driver.find_elements_by_ios_predicate("type='XCUIElementTypeOther' and name='联系人,标签, 第2个按钮,共3个'")
iOSUIAutomation
iOS9.3以下使用,现在已经废弃,iOSPredicateString代替了iOSUIAutomation