『與善仁』Appium基礎 — 23、操作滑動的方式

繁華似錦Fighting發表於2021-12-12

在Appium中提供了三種滑動的方式,swipe滑動、scroll滑動、drag拖拽事件。

除了這三種滑動方式外,我們還可以自定義一些滑動方式。

下面我們來看看這三種滑動方式。

1、swipe滑動

從一個座標位置滑動到另一個座標位置,只能是兩個點之間的滑動。

swipe()方法說明:

swipe(start_x, start_y, end_x, end_y, duration=None)

引數:
1.start_x:起點X軸座標
2.start_y:起點Y軸座標
3.end_x: 終點X軸座標
4.end_y,: 終點Y軸座標
5.duration : 滑動這個操作一共持續的時間(也可以稱慣性),單位:ms(毫秒)
    (重點)什麼是慣性,就是在上拉下滑的過程中,滑動動作結束後螢幕會還會滑一段距離,這個現象就是慣性。
    duration時間越短,duration=None,這樣慣性滑動的距離會非常的多。
    duration時間越長,滑動這個動作越緩慢,慣性滑動的距離會變少。

業務場景:

  1. 進入設定。
  2. 從座標(148,659)滑動到座標(148,248)。

說明:

在一個手機介面上,左上角的座標是(0,0)點。

橫向是x軸座標,縱向是y軸座標。

在設定APP中,左右滑動無效,只能上下滑動,

所以只有y座標在變化。

y座標從小到大,是向下滑動,以手勢作為參考,而不以螢幕作參考.

y座標從大到小,是向上滑動手勢,以手勢作為參考,而不以螢幕作參考。

注意:

可以通過driver.get_window_size()命令來獲取手機螢幕大小。

座標的選擇不能在螢幕的座標之外,

也不能選擇在邊界值上,要在螢幕座標之內的範圍選擇。

練習:

"""
1.學習目標
    掌握swipe滑動方法使用
2.操作步驟
    swipe滑動方法,從一個座標滑動到另一個座標
    driver.swipe(start_x,start_y,end_x,end_y,duration=None)
3.需求
    在設定APP首頁實現swipe方法滑動
    使用swipe方法在設定首頁,實現向上滑動
        (x座標不變,y座標從大到小)
4.總結
    swipe()滑動說明
        操作物件  :  座標
        操作過程有慣性有慣性
            消除慣性,新增duration值,
            當值越大,慣性越小,無限接近座標差
"""

# 1.匯入appium
import time
from appium import webdriver

# 2.建立Desired capabilities物件,新增啟動引數
desired_caps = {
    "platformName": "Android",  # 系統名稱
    "platformVersion": "7.1.2",  # 系統版本
    "deviceName": "127.0.0.1:21503",  # 裝置名稱
    "appPackage": "com.android.settings",  # APP包名
    "appActivity": ".Settings"  # APP啟動名
}

# 3.啟動APP
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

# 獲取螢幕大小
size = driver.get_window_size()
print("裝置螢幕大小:", size)
# 裝置螢幕大小: {'width': 810, 'height': 1440}

# 4.操作APP
# 使用swipe方法在設定首頁,實現向上滑動
# x座標不變,y座標從大到小
# start_x = 0  # 不能選擇螢幕的大小的邊界值,否則會報錯
# start_y = 1440  # 不能選擇螢幕的大小的邊界值,否則會報錯
# end_x = 0
# end_y = 400

start_x = 300
start_y = 1000
end_x = 300
end_y = 500
driver.swipe(start_x, start_y, end_x, end_y, duration=5000)


# 6.關閉APP
time.sleep(3)
driver.quit()

2、scroll滑動

從一個元素滑動到另一個元素,直到頁面自動停止。

scroll()方法說明:

scroll(origin_el, destination_el, duration)

引數
1.origin_el :滑動開始的元素
2.destination_el :滑動結束的元素
3.duration : 滑動效果的持續時間  單位ms(毫秒)

業務場景:

  1. 進入設定。
  2. 模擬手指從儲存選單位置到WLAN選單位置的上滑操作。

程式碼實現:

# 定位到儲存選單欄
el1 = driver.find_element_by_xpath("//*[contains(@text,'儲存')]")

# 定位到WLAN選單欄
el2 = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")

# 執⾏滑動操作
driver.scroll(el1,el2)

練習:

"""
1.學習目標
    掌握scroll滑動方法(熟悉即可)
2.操作步驟
    scroll滑動   從一個元素滑動到另一個元素
    driver.scroll(origin_el,destination_el,duration=None)
        origin_el         起始元素
        destination_el    終止元素
        duration          滑動效果的持續時間  單位ms(毫秒)
3.需求
    實現scroll方法
    在設定首頁從”儲存“滑動到“藍芽“

4. 總結
    scroll方法
        操作物件 :  元素
        操作過程有慣性,需要新增duration引數,
        	引數值越大,慣性越小。
"""
# 1.匯入appium
import time
from appium import webdriver

# 2.建立Desired capabilities物件,新增啟動引數
desired_caps = {
    "platformName": "Android",  # 系統名稱
    "platformVersion": "7.1.2",  # 系統版本
    "deviceName": "127.0.0.1:21503",  # 裝置名稱
    "appPackage": "com.android.settings",  # APP包名
    "appActivity": ".Settings"  # APP啟動名
}

# 3.啟動APP
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

# 4.操作APP
# 定位”儲存“和”藍芽“
store = driver.find_element_by_android_uiautomator('new UiSelector().text("儲存")')
blue_tooth = driver.find_element_by_android_uiautomator('new UiSelector().text("藍芽")')

# 從”儲存“滑動到”藍芽“
driver.scroll(store, blue_tooth, duration=5000)

# 實際操作手機是手指在螢幕向上滑動,
# 點選儲存的位置,向上滑動到藍芽的位置,來檢視頁面中下方的內容。

# 6.關閉APP
time.sleep(3)
driver.quit()

3、drag拖拽事件

從一個元素滑動到另一個元素,第二個元素替代第一個元素原本螢幕上的位置。

drag_and_drop()方法說明:

drag_and_drop(origin_el, destination_el)

引數:
1.origin_el:滑動開始的元素
2.destination_el:滑動結束的元素

業務場景:

  1. 進入設定。
  2. 模擬手指將儲存選單 滑動到WLAN選單欄位置。

程式碼實現:

# 定位到儲存選單欄
el1 = driver.find_element_by_xpath("//*[contains(@text,'儲存')]")

# 定位到WLAN選單欄
el2 = driver.find_element_by_xpath("//*[contains(@text,'WLAN')]")

# 執⾏滑動操作
driver.drag_and_drop(el1,el2)

練習:

"""
1.學習目標
    掌握drag_and_drop滑動方法(熟悉)
2.操作步驟
    drag_and_drop方法  從一個元素拖拽到另一個元素上
    driver.drag_and_drop(origin_el,destination_el)
        origin_el         起始元素
        destination_el    終止元素
3.需求
    實現drag_and_drop方法
    在設定首頁從”儲存“滑動到“藍芽“

4. 總結
    drag_and_drop方法
        操作物件 :  元素
        操作過程沒有慣性。
"""
# 1.匯入appium
import time
from appium import webdriver

# 2.建立Desired capabilities物件,新增啟動引數
desired_caps = {
    "platformName": "Android",  # 系統名稱
    "platformVersion": "7.1.2",  # 系統版本
    "deviceName": "127.0.0.1:21503",  # 裝置名稱
    "appPackage": "com.android.settings",  # APP包名
    "appActivity": ".Settings"  # APP啟動名
}

# 3.啟動APP
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

# 4.操作APP
# 定位”儲存“和”藍芽“
store = driver.find_element_by_android_uiautomator('new UiSelector().text("儲存")')
blue_tooth = driver.find_element_by_android_uiautomator('new UiSelector().text("藍芽")')

# 從”儲存“滑動到”藍芽“
driver.drag_and_drop(store, blue_tooth)


# 6.關閉APP
time.sleep(3)
driver.quit()

4、滑動方法小結

滑動方法名稱 實現方式 是否有慣性
swipe 傳入座標滑動 有慣性(當持續時間足夠長時,實現的效果和drag一致)
scroll 傳入元素滑動 有慣性
drag 傳入元素滑動 無慣性

5、擴充:多次滑動

需求:實現多次滑動手機螢幕的效果。

程式碼如下:(多看裡邊的注意事項)

"""
1.學習目標
    掌握多次滑動操作(上面三種滑動方式,那種都可以)
2.操作步驟
    以scroll方式滑動為例。
3.需求
    在設定APP首頁實現多次滑動(向上滑動)
    從儲存滑動到藍芽
    再從安全滑動到儲存

"""

# 1.匯入appium
import time
from appium import webdriver

# 2.建立Desired capabilities物件,新增啟動引數
desired_caps = {
    "platformName": "Android",  # 系統名稱
    "platformVersion": "7.1.2",  # 系統版本
    "deviceName": "127.0.0.1:21503",  # 裝置名稱
    "appPackage": "com.android.settings",  # APP包名
    "appActivity": ".Settings"  # APP啟動名
}

# 3.啟動APP
driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

# 獲取螢幕大小
size = driver.get_window_size()
print("裝置螢幕大小:", size)
# 裝置螢幕大小: {'width': 810, 'height': 1440}

# 4.操作APP

# 4.1 定位儲存和藍芽
store = driver.find_element_by_android_uiautomator('new UiSelector().text("儲存")')
blue_tooth = driver.find_element_by_android_uiautomator('new UiSelector().text("藍芽")')

# 4.2  從儲存滑動到藍芽
driver.scroll(store, blue_tooth, duration=5000)

# 4.3 定位安全
# 重點注意1:
# 因為安全這個元素在設定app的介面中沒有顯示出來,
# 如果你直接進行定位,就會報錯,NoSuchElementException,
# 你需要等到滑動介面顯示出安全這個元素,才能進行定位。
# 不用完全顯示,只要某個元素在螢幕中出現了一點點部分,也可以用find_element找到該元素.
# 這裡一定要注意。
safe = driver.find_element_by_android_uiautomator('new UiSelector().text("安全")')

# 4.4 從安全滑動到儲存
driver.scroll(safe, store, duration=5000)

# 重點注意2
# 如果在演示的時候,發下第二次滑動的效果有問題(滑動距離很短)
# 原因是:
# find_element如果找到了某個元素,會將具體位置快取在系統中;
# 只要不重新獲取,即使該元素已經跑出螢幕外,但也會認為該元素在之前快取的位置.
# (這是一個系統定位機制的問題)
# 所以第二次實際滑動的距離是:
# 從安全的位置滑動到,第一次滑動時儲存所在的位置。
# 這裡一定要注意。

# 所以通過上邊的說明,如果我們需要進行連續的滑動操作時,
# 既然會儲存元素的位置,我們直接兩次從儲存滑動到藍芽操作,
# 不就解決了,多次等距離滑動的操作。
# 如下,執行兩次儲存滑動到藍芽操作
# driver.scroll(store, blue_tooth, duration=5000)
# driver.scroll(store, blue_tooth, duration=5000)
# 如果需要多次,可以寫一個for迴圈來執行多次。

# 我使用Android 7.1.1版本的系統,沒有發現有元素位置快取的現象,
# 所以直接正常寫就好了,如果出現了上述注意2的現象,
# 這裡我們知道是怎麼回事就好了。

# 6.關閉APP
time.sleep(3)
driver.quit()

說明:

程式碼中注意事項2補充:

如果要解決這個問題,只需要對第二次的兩個元素重新獲取(也就是重新定位),再執行操作就解決了。

如上面的程式碼中,執行第二次滑動的時候,安全獲取了,只需要在重新獲取一下儲存元素,第二次滑動就能正常操作了。

image

6、綜合練習

需求:

1,封裝上下左右滑動操作到一個工具類中。

2, 實現在滑動的過程中找到"時間和日期"元素,並點選進入該頁面。(這個例子類似於Selenium中學習的聚焦元素)

封裝滑動工具類:

# 1.匯入appium
import time
from appium import webdriver


# 定義driver
def app_driver():
    # 2.建立Desired capabilities物件,新增啟動引數
    desired_caps = {
        "platformName": "Android",  # 系統名稱
        "platformVersion": "7.1.2",  # 系統版本
        "deviceName": "127.0.0.1:21503",  # 裝置名稱
        "appPackage": "com.android.settings",  # APP包名
        "appActivity": ".Settings"  # APP啟動名
    }

    # 3.啟動APP
    driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)
    return driver


# 把滑動操作封裝成一個工具類
class AppSwipe:

    # 初始化方法
    # 需要一個全域性的driver(相當於一個啟動的app),
    def __init__(self, driver):
        self.driver = driver
        # size是一個字典型別的資料,一個寬度,一個高度
        self.size = self.driver.get_window_size()  # 獲取手機螢幕大小


    """
    封裝滑動方法:使用driver.swipe()方法
    因為scroll滑動和drag拖拽是使用元素定位,左右滑動的時候可能實現不了。
    
    因為沒個裝置的螢幕大小不一樣,我們需要先獲取螢幕的大小,在適用座標定位。
    """

    def swipeUp(self, t=5000, n=1):
        '''
        手勢:向上滑動
        :param duration:持續時間
        :param n:滑動次數
        :return:
        '''

        # 根據手機螢幕的寬高,來確定起始座標位置

        # 上下滑動水平x軸不變,螢幕的寬度*0.5 表示螢幕的中間
        start_x = self.size['width'] * 0.5  # x座標

        # 手勢向上滑動,y軸的座標從大到小
        start_y = self.size['height'] * 0.75  # 起點y座標
        end_y = self.size['height'] * 0.25  # 終點y座標
        for i in range(n):
            self.driver.swipe(start_x, start_y, start_x, end_y, t)

    def swipeDown(self, duration=5000, n=1):
        '''
        手勢:向下滑動
        :param duration:持續時間
        :param n:滑動次數
        :return:
        '''

        # 根據手機螢幕的寬高,來確定起始座標位置
        # 上下滑動水平x軸不變,螢幕的寬度*0.5 表示螢幕的中間
        start_x = self.size['width'] * 0.5  # x座標

        # 手勢向下滑動,y軸的座標從小到大
        start_y = self.size['height'] * 0.25  # 起始y座標
        end_y = self.size['height'] * 0.75  # 終點y座標
        for i in range(n):
            self.driver.swipe(start_x, start_y, start_x, end_y, duration)

    def swipLeft(self, duration=5000, n=1):
        '''
        手勢:向左滑動
        :param duration:持續時間
        :param n:滑動次數
        :return:
        '''
        # 根據手機螢幕的寬高,來確定起始座標位置
        # 手勢向左滑動,x軸的座標從大到小
        start_x = self.size['width'] * 0.75
        end_x = self.size['width'] * 0.25
        # 左右滑動垂直y軸不變,螢幕的高度*0.5 表示螢幕的中間
        start_y = self.size['height'] * 0.5

        for i in range(n):
            self.driver.swipe(start_x, start_y, end_x, start_y, duration)

    def swipRight(self, duration=5000, n=1):
        '''
        手勢:向右滑動
        :param duration:持續時間
        :param n:滑動次數
        :return:
        '''
        # 根據手機螢幕的寬高,來確定起始座標位置
        # 手勢向右滑動,x軸的座標從小到大
        start_x = self.size['width'] * 0.25
        end_x = self.size['width'] * 0.75
        # 左右滑動垂直y軸不變,螢幕的高度*0.5 表示螢幕的中間
        start_y = self.size['height'] * 0.5
        for i in range(n):
            self.driver.swipe(start_x, start_y, end_x, start_y, duration)


if __name__ == '__main__':
    driver = app_driver()
    swipe = AppSwipe(driver)
    swipe.swipeDown()  # 手勢:向下滑動
    swipe.swipeUp(n=2)  # 手勢:向上滑動
    time.sleep(2)

實現"時間和日期"元素的定位和點選:

# 1、匯入剛剛封裝好的滑動工具類app_swipe
from app_swipe import AppSwipe, app_driver
import time

# 2、獲得driver驅動和工具類的實體類
driver = app_driver()
swipe = AppSwipe(driver)

# 3.操作APP--聚焦元素到"日期和時間"
# 如果設定app的介面中沒有顯示"日期和時間"元素,我們是無法定位的,
# 這個時候我們就執行向上滑動操作,
# 直到手機介面中顯示了"日期和時間"元素,並且成功定位了該元素。
# 我們就執行點選操作,然後退出迴圈。即可執行更多的操作了。
while True:
    try:
        driver.find_element_by_android_uiautomator('new UiSelector().text("日期和時間")').click()
        break
    except:
        # 向上滑動
        AppSwipe(driver).swipe_up()  # 向上滑動

# 4.關閉APP
time.sleep(3)
driver.quit()

相關文章