簡介
奈何橋上歎奈何,三生石前憾三生,彼岸花下非彼岸,奈何三生彼岸人。
相傳過了鬼門關便上一條路叫黃泉路,路上盛開着隻見花,不見葉的彼岸花。花葉生生兩不見,相念相惜永相失,路盡頭有一條河叫忘川河,河上有一座橋叫奈何橋。走過奈何橋有一個土台叫望鄉台。望鄉台邊有個亭子叫孟婆亭,有個叫孟婆的女人守候在那裡,給每個經過的路人遞上一碗孟婆湯。忘川河邊有一塊石頭叫三生石。喝下孟婆湯讓人忘了一切。三生石記載着前世今生來世。
人死先到鬼門關,出了鬼門關,途經黃泉路,來到忘川河邊,便是奈何橋。奈何橋上有孟婆,要過奈何橋,就要喝孟婆湯,不喝孟婆湯,就過不得奈何橋,過不得奈何橋,就不得投生轉世。凡是喝過孟婆湯的人就會忘卻今生今世所有的牽絆,了無牽挂地進入輪回道開始了下一世的輪回。
孟婆湯又稱忘情水或忘憂散,一喝便忘前世今生。陽間的每個人在這裡都有自己的一隻碗,碗裡的孟婆湯,其實就是活着的人一生所流的淚。每個人活着的時候,都會落淚:因喜,因悲,因痛,因恨,因愁,因愛。孟婆将他們一滴一滴的淚收集起來,煎熬成湯,在他們離開人間,走上奈何橋頭的時候,讓他們喝下去,忘卻活着時的愛恨情愁,幹幹淨淨,重新進入六道,或為仙,或為人,或為畜。不是每個人都會心甘情願地喝下孟婆湯。
因為這一生,總會有愛過的人不想忘卻。孟婆會告訴他:你為她一生所流的淚都熬成了這碗湯,喝下它,就是喝下了你對她的愛。來的人眼中最後的一抹記憶便是他今生摯愛的人,喝下湯,眼裡的人影慢慢淡去,眸子如初生嬰兒般清徹。為了來生再見今生最愛,你可以不喝孟婆湯,那便須跳入忘川河,等上千年才能投胎。千年之中,你或許會看到橋上走過今生最愛的人,但是言語不能相通,你看得見她,她看不見你。
千年之中,你看見她走過一遍又一遍奈何橋,喝過一碗又一碗孟婆湯,你盼她不喝孟婆湯,又怕她受不得忘川河中千年煎熬之苦。千年之後若心念不滅,還能記得前生事,便可重入人間,去尋前生最愛的人。奈何橋邊有塊青石叫三生石,三生石記載着每個人的前世今生,石身上的字鮮紅如血,最上面刻着四個大字“早登彼岸”。
溜冰是香港目前流行的叫法,而國内則叫旱冰或輪滑,***稱為溜冰,澳門則叫它做雪屐。不論叫法如何,其目的隻是差別水冰地面或非水冰地面 (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)點選“開始随手記”進入首頁頁面
Appium+python自動化(二十八)- 滑呀滑,滑到奈何橋喝碗孟婆湯 - 進階滑動(超詳解)
(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,可以加宏哥的微信拉你進群) 宏哥微信(請備注:進群)