新鮮出爐:appium2.0+ 單點觸控和多點觸控新的解決方案

發表於2022-05-06

在 appium2.0 之前,在移動端裝置上的觸屏操作,單手指觸屏和多手指觸屏分別是由 TouchAction 類,Multiaction 類實現的。

在 appium2.0 之後,這 2 個方法將會被捨棄。

"[Deprecated] 'TouchAction' action is deprecated. Please use W3C actions instead."

 

 

 


1、w3c action 是什麼?

在 w3c 的 actions 當中,將輸入源分為了三類:

  1. 鍵盤類 - Key
  2. 指標類 - Pointer
  3. None

對於 Pointer 指標類輸入源,共有 3 種:Mouse 滑鼠、Touch 觸屏、Pen 筆觸

輸入源,是提供輸入事件的虛擬裝置。

每一個輸入源,都是一個輸入 id,輸入源 type。與真實裝置一樣,每一個輸入源都有狀態的,有輸入事件。

在 python selenium 的原始碼當中,selenium/common/actions/input_devices.py 裡 InputDevices 類定義了輸入源類。

 

 

 

1、空輸入源(null input source)

提供以下行為:

pause:不做任何操作一段時間,或者動作的持續時間

2、鍵盤輸入源(key input source)

提供以下行為:

KeyDown:按下某個鍵

KeyUp:釋放某個鍵

在 python selenium 的原始碼當中,selenium/common/actions/key_input.py 裡 KeyInput 類定義了按鈕輸入源類。

 

 

 

3、指標輸入源(pointer input source),提供以下行為:

PointerDown:按下滑鼠鍵,或者觸屏或者觸屏筆觸屏

PointerUp:鬆開滑鼠鍵,或者手離開螢幕,或者觸屏筆離開螢幕

PointerMove:移動到螢幕某個點

PointerCancel:刪除某個指標操作

在 python selenium 的原始碼當中,selenium/common/actions/pointer_input.py 裡 PointerInput 類定義了指標輸入源類。

 

 

 

4、在輸入源基礎上,定義了鍵盤操作類 KeyActions

在 python selenium 的原始碼當中,selenium/common/actions/key_actions.py 裡 KeyActions 類定義了鍵盤操作類。

 

 

 

5、在輸入源基礎上,定義了滑鼠/觸屏操作 PointerActions 類:

在 python selenium 的原始碼當中,selenium/common/actions/pointer_actions.py 裡 PointerActions 類定義了滑鼠/觸屏操作類。

 

 

 

 

 

 

 

 

彙總一下上面幾個類:

 

 

 

6、ActionBuilder 類

初始化方法:

  1. 輸入源裝置列表,會放 2 個輸入源:滑鼠輸入源、鍵盤輸入源。
  2. 有 2 個私有屬性:鍵盤操作物件(KeyActions 類例項化**)**,滑鼠/觸屏操作物件(PointerActions 類例項化)

 

 

 

屬性:key_action,pointer_action

在 ActionChains 類當中,就是通過這 2 個屬性來呼叫滑鼠和鍵盤的操作的。

 

 

 

新增新的輸入源:add_key_input,add_pointer_input

 

 

 


2、ActionChains 類

selenium 中的滑鼠操作類,滑鼠行為都是使用的 ActionBuilder 類。

初始化:

 

 

 

 

 

 


3、單點觸控 - ActionChains 類

直接使用 ActionChains 類裡的,w3c_actions 去實現。

比如 appium 當中的 swipe 滑屏方法:

移動到某一個座標點 → 按下 → 移動到另一個座標點 → 釋放

 

 

 


4、多點觸控 - ActionChains 類

多點觸控,是個單點觸控操作同時發生,比如 2 個手指,同時在螢幕上進行滑動操作。

仍然是 ActionChains 類,不過需要在裡面,新增新的單點觸控操作。

 
actions = ActionChains(driver)
# 輸入源裝置列表為空
actions.w3c_actions.devices = []

# 新增一個新的輸入源到裝置到中,輸入源型別為Touch
new_input = actions.w3c_actions.add_pointer_input('touch', f'finger{finger}')
# 輸入源的動作:移動到某個點,按下,移動到另外一點,釋放
new_input.create_pointer_move(x=start_x, y=start_y)
new_input.create_pointer_down(MouseButton.LEFT)
new_input.create_pause(duration / 1000)
new_input.create_pointer_move(x=end_x, y=end_y)
new_input.create_pointer_up(MouseButton.LEFT)

# 以此類推,可以新增多個輸入源操作到裝置當中。可以是滑鼠操作,也可以是觸屏,按鍵等操作

 

比如,對百度地圖 app 進行放大操作的程式碼如下:

from time import sleep
from appium import webdriver

from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.mouse_button import MouseButton

#我要在android7.1.2裝置上,開啟百度地圖app
desired_caps = {
"automationName":"UiAutomator2",
"platformName":"Android",
"platformVersion":"7.1.2",
"deviceName":"HuaWei",
"noReset":True,
"appPackage":"com.baidu.BaiduMap",
"appActivity":"com.baidu.baidumaps.WelcomeScreen",
"systemPort": 8225,
"newCommandTimeout": 1200
}

#先連線appium server。傳遞指令。 appium server連線地址
driver = webdriver.Remote('<http://127.0.0.1:4723/wd/hub>', desired_caps)

sleep(20)

#獲取裝置的大小 - size
size_dict = driver.get_window_size()

# ==========放大地圖:從地圖中心分別向對角線滑動放大 - 2個手指同時執行滑動操作  ==================
actions = ActionChains(driver)
#輸入源裝置列表為空
actions.w3c_actions.devices = []

# ========== 第1個手指:從正中心向右上角滑動  ==================
#新增一個新的輸入源到裝置到中,輸入源型別為Touch,id為finger0
new_input = actions.w3c_actions.add_pointer_input('touch','finger0')
#輸入源的動作:移動到某個點,按下,移動到另外一點,釋放
new_input.create_pointer_move(x=size_dict["width"] * 0.5, y=size_dict["height"] * 0.5)
new_input.create_pointer_down()
# new_input.create_pointer_down(MouseButton.LEFT)
new_input.create_pause(0.2) # 200ms
new_input.create_pointer_move(x=size_dict["width"] * 0.9, y=size_dict["height"] * 0.1)
new_input.create_pointer_up(MouseButton.LEFT)

# ========== 第2個手指:從正中心向左下角滑動  ==================
#新增一個新的輸入源到裝置到中,輸入源型別為Touch。id為finger1
new_input = actions.w3c_actions.add_pointer_input('touch','finger1')
#輸入源的動作:移動到某個點,按下,移動到另外一點,釋放
new_input.create_pointer_move(x=size_dict["width"] * 0.5, y=size_dict["height"] * 0.5)
new_input.create_pointer_down()
# new_input.create_pointer_down(MouseButton.LEFT)
new_input.create_pause(0.2) # 200ms
new_input.create_pointer_move(x=size_dict["width"] * 0.1, y=size_dict["height"] * 0.9)
new_input.create_pointer_up(MouseButton.LEFT)

#執行動作
actions.perform()

 

 

相關文章