Table of Contents
1.Introduce the object: TouchAction: touch
A. Click (tap) operation:
B. Slide the screen multiple times:
C. Long press
2.MultiAction —– Multi-touch zoom in and out operation
2.1 Zoom in and out based on analytical gesture operations
2.2 Another method for zooming in/out: zoom/pinch
3. Sliding screen operation:
A. driver.swipe(x1, y1, x2, y2,duration)
B.driver.scroll
C. driver.drag_and_drop
**To summarize the above three methods:
1. Introduce object: TouchAction: touch
from appium.webdriver.common.touch_action import TouchAction
TouchAction(driver)
– TouchAction objects include (tab), press (short press), move_to (slide to a certain coordinate) and other methods
– Through the TouchAction object, add tap, move_to and other operations, and then perform () execution, you can realize functions such as unlocking the screen
The events available in the specification are:
Press, release, moveTo, tap, wait,
Long press (longPress), cancel (cancel), execute (perform)
A. Click (tap) operation:
driver.tap (coordinate x, coordinate y, continuous click time/s) – coordinate positioning is recommended to be used sparingly and only as a last resort
In addition to positioning clicks on elements, coordinate clicks can also be implemented through positioning expressions.
The first type: TouchAction(driver).tap(x=155, y=706, count=1).perform() The second type: TouchAction(driver).tap(ele, count=1).perform()
B. Swipe the screen multiple times:
It is recommended to use less coordinate positioning. The following are just examples
from appium.webdriver.common.touch_action import TouchAction # You need to release after a short press. You also need to release after a long press. action=TouchAction(driver) action.press(x=220,y=700).move_to(x=840, y=700).move_to(x=220, y=1530).move_to(x=840, y=1530).release(). perform()
Example: Unlock the nine-square grid in WeChat service
import time from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium import webdriver from appium.webdriver.common.mobileby import MobileBy from appium.webdriver.common.touch_action import TouchAction desired_caps = { 'platformName': 'Android', 'platformVersion': '8.1', 'deviceName': 'ye_shen_Android', 'appPackage': 'com.tencent.mm', 'appActivity': 'com.tencent.mm.ui.LauncherUI', 'noReset': True, 'autoAcceptAlerts': True, 'newCommandTimeout': 240 } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.implicitly_wait(10) # Click WeChat Mine loc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().resourceId("com.tencent.mm:id/j5t")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(loc)) TouchAction(driver).tap(x=540, y=1255).wait(200).perform() # Click Service locc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Service")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(locc)) ele = driver.find_element(MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Service")') TouchAction(driver).tap(ele).wait(200).perform() # Check Please enter the gesture password loccs = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Please enter the gesture password")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(loccs)) # Get the starting coordinates - the upper left vertex of the nine-square grid loc = driver.find_element(MobileBy.ID, "com.tencent.mm:id/hrs").location print(loc) # Get the size of the nine-square grid element height width width and height loc_size = driver.find_element(MobileBy.ID, "com.tencent.mm:id/hrs").size print(loc_size) # Get the mean value after segmentation, which is the step size of the nine-square grid to be used below step = loc_size["width"] / 6 step_x = loc_size["width"] / 6 step_y = loc_size["height"] / 6 # Calculate the coordinates of each point point1 = (loc["x"] + step, loc["y"] + step * 5) point2 = (point1[0], point1[1] - step * 2) point3 = (point2[0], point2[1] - step * 2) point4 = (point3[0] + step * 2, point3[1] + step * 2) point5 = (point4[0] + step * 2, point4[1] + step * 2) point6 = (point5[0], point5[1] - step * 2) point7 = (point6[0], point6[1] - step * 2) # Perform sliding operation TouchAction(driver).press(x=point1[0], y=point1[1]).wait(500). \ move_to(x=point2[0], y=point2[1]). \ move_to(x=point3[0], y=point3[1]). \ move_to(x=point4[0], y=point4[1]). \ move_to(x=point5[0], y=point5[1]). \ move_to(x=point6[0], y=point6[1]). \ move_to(x=point7[0], y=point7[1]). \ release().perform() time.sleep(10) driver.quit()
As shown in the picture:
C. Long press
For example: an example of long press: It is recommended to use coordinate positioning less often. The following is just an example
import time from appium import webdriver from appium.webdriver.common.touch_action import TouchAction from appium.webdriver.webdriver import By des = { "platformName": "Android", "platformVersion": "9", "deviceName": "windwos virtual machine", "appPackage": "com.android.settings", "appActivity": "com.android.settings.Settings", "udid": "192.168.0.101:5555", "noReset": "True" } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', des) driver.implicitly_wait(10) touch = TouchAction(driver) #touch.press(x=720, y=1910).perform() touch.long_press(x=720, y=1910).perform()
2.MultiAction —– Multi-touch
Zoom operation
Click here to learn from the article
Background: When using map apps and zooming in and out of images, we often need to zoom in on the interface to more conveniently view the location or zoom in on the image.
2.1 Zoom in and out based on analysis gesture operation
-
(1) Appium provides the MultiAction class for zooming in and out operations. Simulate real finger operations, as shown in the figure:
-
(2) MultiAction is a multi-touch class that can simulate user multi-touch operations. It mainly includes two methods: add() and perform(). MultiAction can be combined with the previously learned ActionTouch to simulate the user’s multiple finger sliding operation effects.
from appium.webdriver.common.multi_action import MultiAction from appium.webdriver.common.touch_action import TouchAction
add method: touch_actions
is one or more TouchAction objects, describing the action to be performed by a finger
def add(self, *touch_actions: 'TouchAction') -> None: """Add TouchAction objects to the MultiAction, to be performed later. Args: touch_actions: one or more TouchAction objects describing a chain of actions to be performed by one finger Usage: | a1 = TouchAction(driver) | a1.press(el1).move_to(el2).release() | a2 = TouchAction(driver) | a2.press(el2).move_to(el1).release() | MultiAction(driver).add(a1, a2) Returns: `MultiAction`: Self instance """ for touch_action in touch_actions: if self._touch_actions is None: self._touch_actions = [] self._touch_actions.append(copy.copy(touch_action))
perform method
def perform(self: T) -> T: """Perform the actions stored in the object. Usage: | a1 = TouchAction(driver) | a1.press(el1).move_to(el2).release() | a2 = TouchAction(driver) | a2.press(el2).move_to(el1).release() | MultiAction(driver).add(a1, a2).perform() Returns: `MultiAction`: Self instance """ self._driver.execute(Command.MULTI_ACTION, self.json_wire_gestures) # clean up and be ready for the next batch self._touch_actions = [] return self
usage:
from appium.webdriver.common.multi_action import MultiAction from appium.webdriver.common.touch_action import TouchAction a1 = TouchAction(driver) a1.press(el1).move_to(el2).release() a2 = TouchAction(driver) a2.press(el2).move_to(el1).release() MultiAction(driver).add(a1, a2).perform()
Code practice: Zoom in and out of the map in WeChat
import time from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium import webdriver from appium.webdriver.common.mobileby import MobileBy from appium.webdriver.common.touch_action import TouchAction from appium.webdriver.common.multi_action import MultiAction desired_caps = { 'platformName': 'Android', 'platformVersion': '8.1', 'deviceName': 'ye_shen_Android', 'appPackage': 'com.tencent.mm', 'appActivity': 'com.tencent.mm.ui.LauncherUI', 'noReset': True, 'autoAcceptAlerts': True, 'newCommandTimeout': 240, # 'automationName': 'uiautomator2' } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.implicitly_wait(10) # Click on WeChat chat box loc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Address Book")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(loc)) # el = driver.find_element(MobileBy.ANDROID_UIAUTOMATOR,'new UiSelector().resourceId("com.tencent.mm:id/bth")') TouchAction(driver).tap(x=152, y=315).wait(200).perform() # Click on the map inside locc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().textContains("Xixiang")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(locc)) ele = driver.find_element(MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().textContains("Xixiang")') TouchAction(driver).tap(ele).wait(200).perform() def getSize(driver): x = driver.get_window_size()['width'] y = driver.get_window_size()['height'] return x, y # Zoom in def narrow(): x, y = getSize(driver) action1 = TouchAction(driver) action2 = TouchAction(driver) zoom_action = MultiAction(driver) action1.press(x=x*0.2, y=y*0.2).wait(1000).move_to(x=x*0.4, y=y*0.4).wait(1000).release() action2.press(x=x*0.8, y=y*0.8).wait(1000).move_to(x=x*0.6, y=y*0.6).wait(1000).release() zoom_action.add(action1, action2) zoom_action.perform() # Zoom out def enlarge(): x, y = getSize(driver) action1=TouchAction(driver) action2=TouchAction(driver) zoom_action=MultiAction(driver) action1.press(x=x*0.4,y=y*0.4).wait(1000).move_to(x=x*0.2,y=y*0.2).wait(1000).release() action2.press(x=x*0.6,y=y*0.6).wait(1000).move_to(x=x*0.8,y=y*0.8).wait(1000).release() zoom_action.add(action1,action2) zoom_action.perform() if __name__ == '__main__': for i in range(5): narrow() for i in range(5): enlarge()
2.2 Another method for zooming in/out: zoom/pinch
Parameters: percent: perform a magnification operation on a certain control, the default magnification ratio is 200%, steps: indicates how many steps the magnification/zooming action is completed, the default is 50
– zoom(self, element=None, percent=200, steps=50)
– pinch(self, element=None, percent=200, steps=50)
# Zoom in driver.zoom(element) # Zoom out driver.pinch(element)
3. Sliding screen operation:
Click here to learn from the article
A. driver.swipe(x1, y1, x2, y2,duration)
swipe(startX,startY,endX,endY)
StartX – EndX: Distance X slides
Start Y – End Y: distance Y slides
Slide from coordinates (x1, x2) to coordinates (x2, y2), duration: duration/milliseconds, sliding time (the sliding coordinates cannot exceed the width and height of the screen)
size = driver.get_window_size() print(driver.get_window_size()) What is returned is: {'width': 1080, 'height': 1776} Use the swipe(self, start_x, start_y, end_x, end_y, duration=0) method: start_x = size['width'] * 0.9 # Width start_y = size['height'] * 0.5 # Height end_x = size['width'] * 0.1 end_y = size['height'] * 0.5
The method of moving a screen up, down, left, and right is as follows:
import time from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium import webdriver from appium.webdriver.common.mobileby import MobileBy desired_caps = { 'platformName': 'Android', 'platformVersion': '8.1', 'deviceName': 'ye_shen_Android', 'appPackage': 'com.tencent.mm', 'appActivity': 'com.tencent.mm.ui.LauncherUI', 'noReset': True, 'autoAcceptAlerts': True, 'newCommandTimeout': 240 } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) loc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().resourceId("com.tencent.mm:id/cn_")') WebDriverWait(driver, 10).until(EC.visibility_of_element_located(loc)) #Get screen size width and height def getSize(driver): x = driver.get_window_size()['width'] y = driver.get_window_size()['height'] return (x, y) #Screen slide up def swipeUp(driver,t=1000): l = getSize(driver) x1 = int(l[0] * 0.5) #x coordinate y1 = int(l[1] * 0.75) #Start y coordinate y2 = int(l[1] * 0.25) #End point y coordinate driver.swipe(x1, y1, x1, y2,t) #Screen slide down def swipeDown(driver,t=1000): l = getSize(driver) x1 = int(l[0] * 0.5) #x coordinate y1 = int(l[1] * 0.25) #Start y coordinate y2 = int(l[1] * 0.75) #End point y coordinate driver.swipe(x1, y1, x1, y2,t) #Screen slide left def swipLeft(driver,t): l=getSize(driver) x1=int(l[0]*0.75) y1=int(l[1]*0.5) x2=int(l[0]*0.05) driver.swipe(x1,y1,x2,y1,t) #Screen slide right def swipRight(driver,t=1000): l=getSize(driver) x1=int(l[0]*0.05) y1=int(l[1]*0.5) x2=int(l[0]*0.75) driver.swipe(x1,y1,x2,y1,t) #Call the slide down method swipeDown(driver)
B.driver.scroll
- Scroll from one element to another, only by sliding between two elements.
- The first picture is a pull-down to open the mini program, and the second picture is a bottle of water instead of the subscription account message location.
Method details:
Parameters: origin_el – the starting element to scroll
; destination_el – the end element to scroll to; duration – duration, in milliseconds, the default is 600 ms
def scroll(self: T, origin_el: WebElement, destination_el: WebElement, duration: Optional[int] = None) -> T: if self.w3c and duration is None: duration=600 action = TouchAction(self) if duration is None: action.press(origin_el).move_to(destination_el).release().perform() else: action.press(origin_el).wait(duration).move_to(destination_el).release().perform() return self
Code practice:
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium import webdriver from appium.webdriver.common.mobileby import MobileBy desired_caps = { 'platformName': 'Android', 'platformVersion': '8.1', 'deviceName': 'ye_shen_Android', 'appPackage': 'com.tencent.mm', 'appActivity': 'com.tencent.mm.ui.LauncherUI', 'noReset': True, 'autoAcceptAlerts': True, 'newCommandTimeout': 240, # 'automationName': 'uiautomator2' } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.implicitly_wait(10) #click WeChat loc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Address Book")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(loc)) # Subscription account message stop_element = driver.find_element(MobileBy.XPATH, '//*[@resource-id="com.tencent.mm:id/gkp"]/android.widget.LinearLayout[2]') # Bottled water start_element = driver.find_element(MobileBy.XPATH, '//*[@resource-id="com.tencent.mm:id/gkp"]/android.widget.LinearLayout[7]') # Execute sliding operation. Choose one of the following two to execute. # Pull down WeChat to mini program driver.scroll(stop_element,start_element,3000) # Bottled water instead of subscription account message driver.scroll(start_element,stop_element,3000)
Scroll down to mini program
Note: There is inertia in the operation process, and the duration parameter needs to be added. The larger the parameter value, the smaller the inertia.
C. driver.drag_and_drop
Dragging from one element to another causes the second element to take its original position on the screen.
Method: Parameters: origin_el – the starting element of the page to be slid; destination_el – the end element of the page to be slid.
def drag_and_drop(self: T, origin_el: WebElement, destination_el: WebElement) -> T: action = TouchAction(self) action.long_press(origin_el).move_to(destination_el).release().perform() return self
Code practice:
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium import webdriver from appium.webdriver.common.mobileby import MobileBy desired_caps = { 'platformName': 'Android', 'platformVersion': '8.1', 'deviceName': 'ye_shen_Android', 'appPackage': 'com.tencent.mm', 'appActivity': 'com.tencent.mm.ui.LauncherUI', 'noReset': True, 'autoAcceptAlerts': True, 'newCommandTimeout': 240, # 'automationName': 'uiautomator2' } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) driver.implicitly_wait(10) #click WeChat loc = (MobileBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Address Book")') WebDriverWait(driver, 30).until(EC.visibility_of_element_located(loc)) # Subscription account message stop_element = driver.find_element(MobileBy.XPATH, '//*[@resource-id="com.tencent.mm:id/gkp"]/android.widget.LinearLayout[2]') # Bottled water start_element = driver.find_element(MobileBy.XPATH, '//*[@resource-id="com.tencent.mm:id/gkp"]/android.widget.LinearLayout[7]') # Execute sliding operation. Choose one of the following two to execute. # Pull down WeChat to mini program driver.drag_and_drop(stop_element,start_element) # Bottled water instead of subscription account message driver.drag_and_drop(start_element,stop_element)
driver.drag_and_drop method description: The duration cannot be set and there is no inertia.
**Summary of the above three methods:
Sliding and dragging are nothing more than considering whether it has “inertia” and whether the passed parameters are “elements” or “coordinates”.
1) scroll: has “inertia”, pass in the “element”, and you can control the inertia by setting the duration parameter.
2) drag_and_drop: No “inertia”, pass in “element”
3) swipe: There is “inertia”. Pass in “coordinates” and you can control the inertia by setting the duration parameter.
original