一、單點觸控
TouchAction類:將一系列的動作放在一個鏈條中,然后將該鏈條傳遞給服務器,服務器接受該鏈條后,解析各個動作,逐個執行,TouchAction類提供了以下幾種方法:
- 短按:press
- 長按:langPress
- 點擊:tap
- 移動到:move_to
- 等待:wait
- 釋放:release
- 執行:perform
- 取消:cancel
1.單點觸控
以繪制九宮格為例(假設繪制Z型的圖案):
該區域的元素屬性bounds的值為[90,542][990,1442],分別代表的是左上角的坐標位置和右下角的坐標位置,經計算是一個標准地正方形,從每個圓形按鈕的分布來看,我們可以將長寬平均六等分,就可以通過坐標值定位到每個點的中心位置,通過appium我們要實現九宮格的繪制,按如下步驟執行:
- 步驟1:定義起點坐標(左上角的坐標點),根據九宮格定位元素的webdriver對象,調用location方法,建議加上顯性等待
- 步驟2:確定整個九宮格的大小,根據九宮格定位元素的webdriver對象,調用size方法
- 步驟3:計算出步長,經上面分析得到的是平均分成了六等分,那么步長就為總長的1/6
- 步驟4:確定每個坐標點的位置,通過上一個點的位置逐個確定(對步長進行加減運算),也可以都已初始坐標為基准運算
- 步驟5:執行繪制的動作,第一個點短按住,接下來滑動,直到最后一個點釋放,即可完成整個繪制動作,每個動作需要加上適當的等待,代碼的最后需要調用perform()方法執行這些動作
九宮格實現的代碼如下:
# 定義起點坐標 loc_nine_button = (MobileBy.ID, 'com.xxzb.fenwoo:id/gesturepwd_create_lockview') wait.until(EC.visibility_of_element_located(loc_nine_button)) ele = driver.find_element(*loc_nine_button) start = ele.location # 起點坐標 # 確定整個九宮格的大小 size = ele.size # 計算出步長 step = size['width'] / 6 # 第一個點的坐標 P1 = (start['x'] + step, start['y'] + step) # 第二個點的坐標 P2 = (P1[0] + step * 2, P1[1]) # 第三個點的坐標 P3 = (P2[0] + step * 2, P2[1]) # 第四個點的坐標 P4 = (P3[0] - step * 2, P3[1] + step * 2) # 第五個點的坐標 P5 = (P4[0] - step * 2, P4[1] + step * 2) # 第六個點的坐標 P6 = (P5[0] + step * 2, P5[1]) # 第七個點的坐標 P7 = (P6[0] + step * 2, P6[1]) # 執行繪制的動作 TouchAction(driver).press( x=P1[0], y=P1[1]).wait(200).move_to( x=P2[0], y=P2[1]).wait(200).move_to( x=P3[0], y=P3[1]).wait(200).move_to( x=P4[0], y=P4[1]).wait(200).move_to( x=P5[0], y=P5[1]).wait(200).move_to( x=P6[0], y=P6[1]).wait(200).move_to( x=P7[0], y=P7[1]).wait(200).release().perform()
我們用一個動畫效果來展示九宮格的繪制過程
2.列表滑動
有一種場景,當我們使用手機淘寶篩選商品的時候,因為商品太多,我們會手動滑動屏幕,使后面的商品展示在我們的面前,像這種的列表滑動,如何用appium來實現呢?接下來以某題庫app來做示范,具體實現步驟如下分析:
- 步驟1:獲取整個手機屏幕的大小,調用driver下的get_window_size()方法
- 步驟2:列表滑動,調用driver.swipe()方法,傳入滑動的初始位置和末端位置,這里不需要精確到某一個點,估計一個大概的滑動起始位置就行,以百分比來計算
列表滑動的代碼如下:
# 滑動頁面,滑動到指定的元素位置,或者直到滑動過程中沒有新的頁面加載即停止滑動 # 獲取整個屏幕的大小 size = driver.get_window_size() # 向上滑動題庫 old = None new = driver.page_source loc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("第18套")') while old != new: try: WebDriverWait(driver, 10).until(EC.visibility_of_element_located(loc)) # 等待元素可見,可見則停止滑動 break except: driver.swipe(start_x=size['width'] * 0.5, start_y=size['height'] * 0.9, end_x=size['width'] * 0.5, end_y=size['height'] * 0.1, duration=200) old = new new = driver.page_source
我們用一個動畫效果來展示列表滑動的過程
二、多點觸控
MultiAction類:提供了多點觸控的方式,在放大和縮小的場景中使用偏多,該類下面只有add()和perform()方法,原理是將多條軌跡合並在一起同步執行,只需要將每條軌跡的動作添加到add()方法中即可
1.放大縮小
以高德地圖縮放為例,實現步驟分析如下:
- 步驟1:獲取整個屏幕的大小,調用driver下的get_window_size()方法
- 步驟2:定義地圖的中心點
- 步驟3:定義縮放初始位置的兩個點
- 步驟4:定義兩個縮放的滑動動作,單條滑動動作參考單點觸控的實現方法
- 步驟5:執行多點觸控,使用add()方法添加兩個滑動動作
- 步驟6:調用perform()方法執行多點觸控操作
高德地圖執行時拋出以下異常,縮小動作前添加了點擊屏幕的操作后解決
多點觸控的縮放代碼如下:
# 獲取整個屏幕的大小 size = driver.get_window_size() # 定義地圖的中心點 center_point = (size['width'] * 0.5, size['height'] * 0.5) # 定義兩個外點 out_point_01 = (size['width'] * 0.1, size['height'] * 0.1) out_point_02 = (size['width'] * 0.9, size['height'] * 0.9) # # 點擊一下屏幕 TouchAction(driver).tap(x=size['width'] * 0.5, y=size['height'] * 0.2).wait(200).perform() # 設置放大的動作 a1 = TouchAction(driver).press(x=out_point_01[0], y=out_point_01[1]).wait(200).move_to(x=center_point[0], y=center_point[1]).wait(200) a2 = TouchAction(driver).press(x=out_point_02[0], y=out_point_02[1]).wait(200).move_to(x=center_point[0], y=center_point[1]).wait(200) # 執行多點觸控 m = MultiAction(driver) m.add(a1, a2) m.perform()
我們用一個動畫效果來展示高德地圖縮放的過程
2.多指點擊
有一些場景需要用到多指點擊或者長按才能實現預期的結果,此時我們可以使用driver.tap()方法,參考源碼的描述,需要注意幾點:
- 最多支持5個指頭
- 只有點擊和長按兩種動作
- 當duration=None時為點擊,duration不為None時為長按,長按的時間根據傳入的duration值決定
- 第一個參數positions需要傳入坐標,並且格式為嵌套元組的列表,第二個參數為duration,單位ms,例如:[(100, 20), (100, 60), (100, 100)], 500