Appium+python自動化(二十八)- 滑呀滑,滑到奈何橋喝碗孟婆湯 - 高階滑動(超詳解)
簡介
奈何橋上嘆奈何,三生石前憾三生,彼岸花下非彼岸,奈何三生彼岸人。
相傳過了鬼門關便上一條路叫黃泉路,路上盛開著只見花,不見葉的彼岸花。花葉生生兩不見,相念相惜永相失,路盡頭有一條河叫忘川河,河上有一座橋叫奈何橋。走過奈何橋有一個土臺叫望鄉臺。望鄉臺邊有個亭子叫孟婆亭,有個叫孟婆的女人守候在那裡,給每個經過的路人遞上一碗孟婆湯。忘川河邊有一塊石頭叫三生石。喝下孟婆湯讓人忘了一切。三生石記載著前世今生來世。
人死先到鬼門關,出了鬼門關,途經黃泉路,來到忘川河邊,便是奈何橋。奈何橋上有孟婆,要過奈何橋,就要喝孟婆湯,不喝孟婆湯,就過不得奈何橋,過不得奈何橋,就不得投生轉世。凡是喝過孟婆湯的人就會忘卻今生今世所有的牽絆,了無牽掛地進入輪迴道開始了下一世的輪迴。
孟婆湯又稱忘情水或忘憂散,一喝便忘前世今生。陽間的每個人在這裡都有自己的一隻碗,碗裡的孟婆湯,其實就是活著的人一生所流的淚。每個人活著的時候,都會落淚:因喜,因悲,因痛,因恨,因愁,因愛。孟婆將他們一滴一滴的淚收集起來,煎熬成湯,在他們離開人間,走上奈何橋頭的時候,讓他們喝下去,忘卻活著時的愛恨情愁,乾乾淨淨,重新進入六道,或為仙,或為人,或為畜。不是每個人都會心甘情願地喝下孟婆湯。
因為這一生,總會有愛過的人不想忘卻。孟婆會告訴他:你為她一生所流的淚都熬成了這碗湯,喝下它,就是喝下了你對她的愛。來的人眼中最後的一抹記憶便是他今生摯愛的人,喝下湯,眼裡的人影慢慢淡去,眸子如初生嬰兒般清徹。為了來生再見今生最愛,你可以不喝孟婆湯,那便須跳入忘川河,等上千年才能投胎。千年之中,你或許會看到橋上走過今生最愛的人,但是言語不能相通,你看得見她,她看不見你。
千年之中,你看見她走過一遍又一遍奈何橋,喝過一碗又一碗孟婆湯,你盼她不喝孟婆湯,又怕她受不得忘川河中千年煎熬之苦。千年之後若心念不滅,還能記得前生事,便可重入人間,去尋前生最愛的人。奈何橋邊有塊青石叫三生石,三生石記載著每個人的前世今生,石身上的字鮮紅如血,最上面刻著四個大字“早登彼岸”。
溜冰是香港目前流行的叫法,而國內則叫旱冰或輪滑,臺灣稱為溜冰,澳門則叫它做雪屐。不論叫法如何,其目的只是區別水冰地面或非水冰地面 (ICE SKATING)。然而在巨集哥這巨集哥把手機上的這種滑動稱其為溜冰,咱也當一回文藝人。
今天做自動化解鎖9宮格,本以為發現swipe不能滿足需求,於是用TouchAction去實現手勢滑動。但是不是想象中的那麼順利。
這篇文章寫的特別的痛苦,寫的死去活來,期間多次想放棄,但是最終堅持下來了,破繭成蝶,寫的巨集哥好像真的是奈何橋上走了一遭,。細心地小夥伴們或者童鞋們會發現巨集哥已經好多天沒有更新文章了。那是因為這篇文章中遇到了不少坑,耗費了大量時間,總的來說大約是兩個晚上的時間,每晚上大約3到4個小時。下邊慢慢的聽巨集哥給你一一道來。
高階溜冰的滑動
滑動操作一般是兩點之間的滑動,這種滑動巨集哥在這裡稱其為低階的溜冰滑動;就是巨集哥上一節給小夥伴們分享的。然而實際使用過程中使用者可能要進行一些多點連續滑動操作。如九宮格滑動操作,連續拖動圖片移動等場景。那麼這種高階絢麗的溜冰滑動在Appium中該如何模擬這類操作呢?下面聽巨集哥給你慢慢道來。
TouchAction
首先看一下官方文件
地址:https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.touch_actions.html
Touch Action包含一些列操作,比如按壓、長按、點選、移動、暫停。由著些不同操作可以組成一套動作。使用TochAction需要先匯入對應的模組
from appium.webdriver.common.touch_action import TouchAction
按壓
方法:press() 開始按壓一個元素或座標點(x,y)。通過手指按壓手機螢幕的某個位置。 press也可以接收螢幕的座標(x,y)。
press(self, el=None, x=None, y=None) TouchAction(driver).press(x=0,y=308)
長按
方法:longPress() 開始按壓一個元素或座標點(x,y)。 相比press()方法,longPress()多了一個入參,既然長按,得有按的時間吧。duration以毫秒為單位。1000表示按一秒鐘。其用法與press()方法相同。
long_press(self, el=None, x=None, y=None, duration=1000)
點選
方法:tap() 對一個元素或控制元件執行點選操作。用法參考press()。
tap(self, element=None, x=None, y=None, count=1)
移動
方法:move_to() 將指標從上一個點移動到指定的元素或點。
move_to(self, el=None, x=None, y=None)
注意:
移動到目位置有時是算絕對座標點,有時是基於前面一個座標點的偏移量,這個要結合具體App來實踐。
暫停
方法:Wait()
wait(self, ms=0)
暫停指令碼的執行,單位為毫秒。
釋放
方法:release() 結束的行動取消螢幕上的指標。
release(self)
執行
方法:perform() 執行的操作傳送到伺服器的命令操作。
perform(self)
TouchAction實戰——九宮格滑動操作
九宮格是一種比較常見的圖案加密方式,目前很多App都支援設定圖案鎖,Android原生系統也支援設九宮格圖案鎖屏。那麼我們該如何使用Appium進行滑動操作呢?
測試場景
安裝啟動隨手記App 啟動App後在密碼設定選項中開啟手機密碼並滑動九宮格設定如下“Z”字形的圖形密碼。
測試環境
1.巨集哥的系統環境是Windows 10版本 64位系統
2.巨集哥的dk版本:"1.8.0_181"
3.巨集哥的appium版本:1.4.16
4.selenium:3.141.0
安裝selenium:
輸入指令pip install selenium
驗證安裝成功:pip show selenium
5.測試裝置:Android 5.1.1 (不能低於5.0版本)
6.Python:3.7.2
命令:python -V ,回車即可。
7.測試App:隨手記Android app V9.7.1.5
想法與思路
- 安裝啟動隨手記APP
- 程式碼實現點選“下一步”,向左滑動首頁引導頁面
- 點選“開始隨手記”進入首頁頁面
- 點選“設定”按鈕,向上滑動,找到“高階”按鈕,點選進入
- 點選“手勢密碼”,開始設定手勢密碼(高階滑動)
程式碼實現
(1)安裝啟動隨手記
(2)程式碼實現點選“下一步”,向左滑動首頁引導頁面
(3)點選“開始隨手記”進入首頁頁面
(4)點選“設定”按鈕,向上滑動,找到“高階”按鈕,點選進入
(5)點選“手勢密碼”,開始設定手勢密碼,進行解鎖(高階滑動)
這個地方move_to到了按下的這個座標點,是因為不這樣的話實際結果忽略掉了第一個按下的點。release()釋放,perform()執行。
程式碼執行結果
執行過程appium和夜神模擬器
參考程式碼
1 # coding=utf-8 2 # 1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行 3 4 # 2.註釋:包括記錄建立時間,建立人,專案名稱。 5 ''' 6 Created on 2019-8-07 7 @author: 北京-巨集哥 QQ交流群:707699217 8 Project:學習和使用appium自動化測試-高階滑動 9 ''' 10 # 3.匯入模組 11 from appium import webdriver 12 from appium.webdriver.common.touch_action import TouchAction 13 from selenium.webdriver.support.ui import WebDriverWait 14 from selenium.common.exceptions import NoSuchElementException 15 from time import sleep 16 17 desired_caps={} 18 desired_caps['platformName']='Android' 19 desired_caps['deviceName']='127.0.0.1:62001' 20 desired_caps['platforVersion']='5.1.1' 21 22 desired_caps['app']=r'C:\Users\DELL\Downloads\mymoney.apk' 23 desired_caps['appPackage']='com.mymoney' 24 desired_caps['appActivity']='com.mymoney.biz.splash.SplashScreenActivity' 25 26 driver=webdriver.Remote('http://127.0.0.1:4723/wd/hub',desired_caps) 27 driver.implicitly_wait(5) 28 29 30 def get_size(): 31 x=driver.get_window_size()['width'] 32 y=driver.get_window_size()['height'] 33 return x,y 34 35 def swipeLeft(): 36 l=get_size() 37 x1=int(l[0]*0.9) 38 y1=int(l[1]*0.5) 39 x2=int(l[0]*0.1) 40 driver.swipe(x1,y1,x2,y1,1000) 41 42 def swipeUp(): 43 l = get_size() 44 x1 = int(l[0] * 0.5) 45 y1 = int(l[1] * 0.95) 46 y2 = int(l[1] * 0.35) 47 driver.swipe(x1, y1, x1, y2, 1000) 48 49 #等待啟動頁面元素,然後向左滑動兩次,跳過引導頁面 50 WebDriverWait(driver,6).until(lambda x:x.find_element_by_id('com.mymoney:id/next_btn')) 51 for i in range(2): 52 swipeLeft() 53 sleep(0.5) 54 #點選“開始隨手記”按鈕 55 driver.find_element_by_id('com.mymoney:id/begin_btn').click() 56 #檢測是否有活動頁面彈窗,如果有就點選關閉 57 try: 58 closeBtn=driver.find_element_by_id('com.mymoney:id/close_iv') 59 except NoSuchElementException: 60 pass 61 else: 62 closeBtn.click() 63 64 #點選設定 65 driver.find_element_by_id('com.mymoney:id/nav_btn_forth').click() 66 #等待介面選單加載出來,然後向上滑動 67 WebDriverWait(driver,6).until(lambda x:x.find_element_by_id('android:id/content')) 68 swipeUp() 69 #點選高階選單 70 driver.find_element_by_android_uiautomator('new UiSelector().text("高階")').click() 71 #點選密碼與手勢密碼選單 72 driver.find_element_by_id('com.mymoney:id/password_protect').click() 73 #點選手勢密碼保護 74 driver.find_element_by_id('com.mymoney:id/ll_gesture_psd').click() 75 #連續滑動兩次設定圖案密碼 76 for i in range(2): 77 TouchAction(driver).press(x=212, y=296).wait(100)\ 78 .move_to(x=148, y=0).wait(100)\ 79 .move_to(x=148,y=0).wait(100)\ 80 .move_to(x=-148,y=148).wait(100)\ 81 .move_to(x=-148,y=148).wait(100)\ 82 .move_to(x=148,y=0).wait(100)\ 83 .move_to(x=148,y=0).wait(100) \ 84 .release().wait(200).perform()
連續滑動設定手勢密碼座標計算
首先使用工具獲取到元素座標位置,可以看到起始位置是【138,218】,終點位置是【581,661】
分析:
該圖形可以橫豎劃分六等分
那麼第一個圓中心點的座標:
x=138+(581-138)/6
y=218+(661-218)/6
依次類推,想要畫一個z形狀,則需要計算第1、2,3,5,7,8,9這幾個圓的中心點座標
然後用TouchAction 的press和moveto方法將幾個步驟連結起來。程式碼如下
1 #引入包 2 from appium.webdriver.common.touch_action import TouchAction 3 4 def settingPassword(self): 5 6 #[138,218][581,661]夜神上的元素座標 7 8 xxx = (581-138) / 6 9 one_x = 138 + xxx 10 one_y = 218 + xxx 11 two_x = 138 + xxx * 3 12 two_y = 218 + xxx #與第二個縱座標相等 13 three_x=138 + xxx*5 14 three_y=218 + xxx #與第二個縱座標相等 15 five_x=138 + xxx * 3 16 five_y=218+xxx*3 17 seven_x=138 + xxx 18 seven_y=218+xxx*5 19 eight_x=138 + xxx * 3 20 eight_y=218+xxx*5 21 nine_x=138 + xxx*5 22 nine_y=218+xxx*5 23 24 TouchAction(self.driver).press(x=one_x, y=one_y).wait(300).move_to(x=two_x, y=two_y).wait(300).move_to(x=three_x,y=three_y).wait(300).move_to(x=five_x,y=five_y).wait(300).move_to(x=seven_x,y=seven_y).wait(300).move_to(x=eight_x,y=eight_y).wait(300).move_to(x=nine_x,y=nine_y).release().perform()
小結
1.實現的時候總是報錯:
The coordinates provided to an interactions operation are invalid.
解決方案:在release後邊加上wait,即可。這可是巨集哥查了好多資料,才找到的解決辦法,具體原因巨集哥也有點蒙圈,等找到原因了,後期補上,或者有知道的大佬可以分享一下心得體會 。
期間巨集哥想不用for迴圈了,直接寫了兩個一樣的TouchAction還是報錯,然後巨集哥實在是搞不定了,第二天晚上巨集哥決定既然可以畫一個Z字形,要不把設定密碼的文章改成解鎖密碼文章 ,前者需要畫兩個Z字形,後者需要畫一個Z字形。而且剛好解鎖,需要一個就可以,內心的小鬼在打架,最終還是理性打敗了取巧和任性,硬著頭皮解決遇到的各種問題,才有了這篇文章的產生。這也側面的反應學習和工作是不能偷奸取巧的。
1 for i in range(2): 2 TouchAction(driver).press(x=212, y=296).wait(100)\ 3 .move_to(x=148, y=0).wait(100)\ 4 .move_to(x=148,y=0).wait(100)\ 5 .move_to(x=-148,y=148).wait(100)\ 6 .move_to(x=-148,y=148).wait(100)\ 7 .move_to(x=148,y=0).wait(100)\ 8 .move_to(x=148,y=0).wait(100) \ 9 .release().wait(100).perform()
2.這段程式碼裡面有倆個坑,呃,關鍵點:
(1)press方法中的座標為絕對座標,move_to方法中的座標都是相對座標,具體來說第一個move_to中的座標相對於press方法中的座標,第二個move_to方法中的座標相對於第一個move_to方法中的座標。以此類推下去,以前好像不是這個樣子的。直接計算完就可以用了。巨集哥期間犯的錯誤:
a.就是直接算完就用結果報錯;然後查資料說是相對座標;
b.然後把後邊move_to 的座標都相對第一個絕對座標了,結果可想而知,還是報錯。
繼續查資料,才找到以上的解決辦法了。
(2)wait是必須的:這裡ms表示為毫秒,ms=100就是等待100毫秒。不用的話太快會出錯
3.分成六等份,小夥伴們有點蒙圈,給小夥伴們看一幅比較直觀的圖
4. 好了,奈何橋走了一遭,終於搞定了,獲得了新生。不過遺憾的事是:實在太忙了,寫文章,解決問題和各種坑,沒來得及喝一碗孟婆湯,不知道它的味道是酸甜苦辣。。。。,還是其他什麼味道,然後把這個痛苦的過程忘記掉。友情提示:小夥伴們和童鞋們如果滑到奈何橋,可以喝一碗嘗一嚐鮮。
最後,今天是七夕節,祝大家七夕節快樂,吃好,玩好!!!
您的肯定就是我進步的動力。如果你感覺還不錯,就請鼓勵一下吧!記得點波 推薦 哦!!!(點選右邊的小球即可! :))
個人公眾號 微信群 (微信群已滿100,可以加巨集哥的微信拉你進群) 巨集哥微信(請備註:進群)
&n