前言
本次我們將會(huì)對(duì) uiautomator2 的一些基本操作進(jìn)行簡單的封裝捺癞,以便更好的應(yīng)用到UI自動(dòng)化中省艳。
重復(fù)多次滑動(dòng)
在 uiautomator2 中朽色,給我們提供了一些滑動(dòng)的操作 swipe()
,以及滑動(dòng)擴(kuò)展的操作 swipe_ext()
,基于此我們可以對(duì)重復(fù)多次的滑動(dòng)操作進(jìn)行簡單封裝水泉。
def up(self, scale=0.9, times=1, duration=1.0, **kwargs):
"""
上滑操作
:param scale: 滑動(dòng)單位,默認(rèn)0.9個(gè)單位
:param times: 滑動(dòng)次數(shù)窒盐,默認(rèn)1次
:param duration: 滑動(dòng)時(shí)間草则,默認(rèn)1.0秒
:return:
"""
for i in range(times):
self.d.swipe_ext("up", scale, duration=duration, **kwargs)
def down(self, scale=0.9, times=1, duration=1.0, **kwargs):
"""
下滑操作
:param scale: 滑動(dòng)單位,默認(rèn)0.9個(gè)單位
:param times: 滑動(dòng)次數(shù)蟹漓,默認(rèn)1次
:param duration: 滑動(dòng)時(shí)間,默認(rèn)1.0秒
:return:
"""
for i in range(times):
self.d.swipe_ext("down", scale, duration=duration, **kwargs)
def left(self, scale=0.9, times=1, duration=1.0, **kwargs):
"""
左滑操作
:param scale: 滑動(dòng)單位葡粒,默認(rèn)0.9個(gè)單位
:param times: 滑動(dòng)次數(shù)份殿,默認(rèn)1次
:param duration: 滑動(dòng)時(shí)間,默認(rèn)1.0秒
:return:
"""
for i in range(times):
self.d.swipe_ext("left", scale, duration=duration, **kwargs)
def right(self, scale=0.9, times=1, duration=1.0, **kwargs):
"""
右滑操作
:param scale: 滑動(dòng)單位嗽交,默認(rèn)0.9個(gè)單位
:param times: 滑動(dòng)次數(shù)卿嘲,默認(rèn)1次
:param duration: 滑動(dòng)時(shí)間,默認(rèn)1.0秒
:return:
"""
for i in range(times):
self.d.swipe_ext("right", scale, duration=duration, **kwargs)
間隔等待元素
我們?cè)谧鯱I自動(dòng)化時(shí)夫壁,如果需要在進(jìn)入某個(gè)APP頁面后點(diǎn)擊元素拾枣,那么一般先會(huì)等待一段時(shí)間,然后再進(jìn)行點(diǎn)擊操作盒让,但是在這個(gè)過程中梅肤,到底等待多長時(shí)間才比較合適,這個(gè)就不太好判斷邑茄。
因此姨蝴,我們可以用另一種思路來實(shí)現(xiàn):
- 檢查定位元素是否存在
- 如果定位失敗就間隔一段時(shí)間后重試
- 循環(huán)以上操作,直到元素定位成功就點(diǎn)擊肺缕,或超時(shí)拋出異常
def wait_until_element_found(self, param, timeout=30.0, retry_interval=2, wait_after_found=0.0):
"""
定位元素左医,如果不存在就間隔若干秒后重試授帕,直到元素定位成功或超時(shí)
:param param: xpath字符串 或 元素對(duì)象
:param timeout: 超時(shí), 默認(rèn)30秒
:param retry_interval: 間隔時(shí)間, 默認(rèn)2秒
:param wait_after_found: 找到元素后,原地等待時(shí)間
:return:
"""
element = self.d.xpath(param) if isinstance(param, str) else param
max_time = time.time() + timeout
while True:
try:
assert element.exists
if wait_after_found:
print("Element found炒辉,then sleep {} seconds".format(wait_after_found))
time.sleep(wait_after_found)
return element
except AssertionError:
param = param if isinstance(param, str) else param.selector
print("Element 【 {} 】 Not found, Retry...".format(param))
if time.time() > max_time > 0:
raise AssertionError("Element 【 {} 】 located failed after {} timeout".format(param, timeout))
time.sleep(retry_interval)
def wait_for_click(self, param, wait_after_click=0.0, **kwargs):
"""
判斷UI元素是否存在, 不存在則等待UI元素在一定時(shí)間內(nèi)出現(xiàn)豪墅,再進(jìn)行點(diǎn)擊
:param param: xpath字符串 或 元素對(duì)象
:param wait_after_click: 點(diǎn)擊后等待時(shí)間
:return:
"""
element = self.wait_until_element_found(param, **kwargs)
element.click()
if wait_after_click:
print("Element found and click泉手,then sleep {} seconds".format(wait_after_click))
time.sleep(wait_after_click)
重復(fù)多次點(diǎn)擊
在 uiautomator2 中黔寇,給我們提供了一些點(diǎn)擊的操作,如 單擊click()
斩萌,雙擊double_click()
缝裤,長按long_click()
等,基于此我們可以對(duì)重復(fù)多次的點(diǎn)擊操作進(jìn)行簡單封裝颊郎。
def repeat_click(self, param, times, wait_after_repeat_click=0.0):
"""
重復(fù)多次點(diǎn)擊UI元素
:param param: xpath字符串 或 元素對(duì)象
:param times: 點(diǎn)擊次數(shù)
:param wait_after_repeat_click: 重復(fù)點(diǎn)擊后等待時(shí)間憋飞,默認(rèn)為0.0
:return:
"""
element = self.wait_until_element_found(param)
for i in range(times):
element.click()
if wait_after_repeat_click:
print("Element click,then sleep {} seconds".format(wait_after_repeat_click))
time.sleep(wait_after_repeat_click)
滑動(dòng)查找元素
我們?cè)谧鯱I自動(dòng)化時(shí)姆吭,有時(shí)需要進(jìn)行多次上滑操作榛做,比如我進(jìn)入某個(gè)APP頁面,需要定位是否某個(gè)元素内狸,而這個(gè)元素可能位于頁面中間部分检眯,也可能位于頁面最底部,需滑到頁面底部時(shí)才出現(xiàn)昆淡,又或者頁面上不存在該元素锰瘸,在整個(gè)過程中,我們需在滑動(dòng)的過程中對(duì)元素進(jìn)行定位昂灵。
因此避凝,我們可以用以下思路來實(shí)現(xiàn):
- 檢查定位元素是否存在
- 如果定位失敗就進(jìn)行一次滑動(dòng),滑動(dòng)后重試
- 循環(huán)以上操作眨补,直到滑動(dòng)到頁面底部管削,若該過程中元素定位成功就點(diǎn)擊
def swipe_until_element_found(self, param, wait_after_found=0.0, **kwargs):
"""
檢查元素是否存在,若不存在則進(jìn)行上滑撑螺,滑動(dòng)后再次檢查佩谣,直到滑動(dòng)到頁面底部
若找到元素則返回,否則滑動(dòng)到頁面底部后实蓬,仍未找到元素茸俭,則拋出異常,提示找不到元素
:param param: xpath字符串 或 元素對(duì)象
:param wait_after_found: 找到元素后安皱,原地等待時(shí)間
:param kwargs:
:return:
"""
element = self.d.xpath(param) if isinstance(param, str) else param
param = param if isinstance(param, str) else param.selector
while True:
try:
assert element.exists
if wait_after_found:
print("Element found调鬓,sleep {} seconds".format(wait_after_found))
time.sleep(wait_after_found)
return element
except AssertionError:
print("Element 【 {} 】 Not found, Continue to swipe up...".format(param))
# 獲取滑動(dòng)前頁面下半部分的所有元素
page_content = self.d.dump_hierarchy()[(len(self.d.dump_hierarchy()) // 2):]
self.up(**kwargs)
time.sleep(0.5)
# 獲取滑動(dòng)后頁面下半部分的所有元素,并與上一次滑動(dòng)前的頁面元素對(duì)比酌伊,頁面元素沒有變化時(shí)跳出循環(huán)
if self.d.dump_hierarchy()[(len(self.d.dump_hierarchy()) // 2):] == page_content:
break
if not element.exists:
raise AssertionError("Element 【 {} 】 located failed in this page".format(param))
def swipe_for_click(self, param, wait_after_click=0.0, **kwargs):
"""
判斷UI元素是否存在, 不存在則持續(xù)向上滑動(dòng)到底部腾窝,直到UI元素在頁面內(nèi)出現(xiàn)缀踪,再進(jìn)行點(diǎn)擊
:param param: xpath字符串 或 元素對(duì)象
:param wait_after_click: 點(diǎn)擊后等待時(shí)間
:return:
"""
element = self.swipe_until_element_found(param, **kwargs)
element.click()
if wait_after_click:
print("Element found and click,then sleep {} seconds".format(wait_after_click))
time.sleep(wait_after_click)