Overview
In the third part of the “Gestures in Appium” series, we will explore how to perform the “Long Press” gesture in Appium. This gesture is typically used to make the item under press draggable or to open modification options like Deletion, Edit, or Select. So, let’s dive in!
Press and Hold using W3C Actions API
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.options.android import UiAutomator2Options
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.actions import interaction
import desired_caps # Explained in Part 1
appium_options = UiAutomator2Options().load_capabilities(desired_caps.contacts)
driver = webdriver.Remote(appium_server, options=appium_options)
# Find all contacts in the list
contacts = driver.find_elements(by=AppiumBy.ID, value="com.android.contacts:id/cliv_name_textview")
# Create an instance from ActionChains class
actions = ActionChains(driver)
# Create a "touch" type of pointer input. By default it is "mouse"
touch_input = PointerInput(interaction.POINTER_TOUCH, 'touch')
# Override pointer action as 'touch'
actions.w3c_actions = ActionBuilder(self, mouse=touch_input)
# Press and Hold using W3C actions on first contact
actions.w3c_actions.pointer_action.click_and_hold(contacts[0])
actions.perform()
In this example, we implemented a gesture using W3C Actions API to press and hold the first contact on the list like the one you can see above. First, we locate all contacts in the list and create an instance of ActionChains to perform actions on them. Next is this:
touch_input = PointerInput(interaction.POINTER_TOUCH, 'touch')
The ActionBuilder
class is the key component of W3C Actions, responsible for creating instances of PointerInput, which we talked about in previous parts. The ActionChains
class uses this class to create w3c_actions. We have different types of input, such as mouse
, touch
, wheel
, pen
, etc. By default, it is set to “mouse”. However, in some cases, it is better to change it to “touch”, even though the mouse is considered the main input in the appium context (Both ‘mouse’ and ’touch’ are types of pointer actions.). For example, when performing actions like “Zoom”, it is mandatory to change the input to “touch”.
In this example, although Press and Hold is a type of mouse action, for compatibility reasons, we are changing the input to “touch”. Now let’s go to the next step:
actions.w3c_actions = ActionBuilder(self, mouse=touch_input)
ActionBuilder has an argument called “mouse” which sets the input type. We are replacing the default input with the one created in the previous step (touch input).
actions.w3c_actions.pointer_action.click_and_hold(contacts[0])
actions.perform()
Finally, we use the click and hold
method of the PointerActions
class (which is used “ActionBuilder”).
I did my best to explain what was happening here. :)
Press and Hold using W3C Mobile Gestures Commands
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.options.android import UiAutomator2Options
import desired_caps # Explained in Part 1
appium_options = UiAutomator2Options().load_capabilities(desired_caps.contacts)
driver = webdriver.Remote(appium_server, options=appium_options)
contacts = driver.find_elements(by=AppiumBy.ID, value="com.android.contacts:id/cliv_name_textview")
# Get element coordinates (position in the page)
element_coord = contacts[0].location
# Long press using W3C Mobile Gestures Commands
driver.execute_script('mobile: longClickGesture', {'x': element_coord['x'], 'y': element_coord['y'], 'duration': 1000})
W3C Mobile Gestures has a command mobile: longClickGestures
that accepts either element object, coordinates, or selector/locator strategy pair. We simply pass the element’s position and set the duration parameter to 1000 milliseconds. So it holds the finger on that position for 1 second.
Press and Hold using TouchAction class
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.options.android import UiAutomator2Options
import desired_caps # Explained in Part 1
appium_options = UiAutomator2Options().load_capabilities(desired_caps.contacts)
driver = webdriver.Remote(appium_server, options=appium_options)
contacts = driver.find_elements(by=AppiumBy.ID, value="com.android.contacts:id/cliv_name_textview")
actions = TouchAction(driver)
# actions.long_press(el=contacts[0]).perform()
# or:
actions.press(el=contacts[0]).wait(ms=1000).release().perform()
There are two ways to create a long press gesture in the TouchAction class:
Using long_press
method:
actions.long_press(el=contacts[0]).perform()
Or create a sequence of actions to perform it:
actions.press(el=contacts[0]).wait(ms=1000).release().perform()
It is worth mentioning again that you can pass either element
object (like we did) or x
,y
arguments to the press
or long_press
methods.
Thank you for taking the time to read. If you enjoyed the post, please leave your reactions, comments, and questions. Your feedback is greatly appreciated!
In the next article, we will cover the Scroll gesture.
Previous: Part 2 - Tap | Double Tap | Multi-finger Tap
Next: Part 4 - Scroll (Vertical/Horizontal/Search and Scroll Element IntoView)
Follow me on LinkedIn: https://www.linkedin.com/in/mohammad-monfared/
Happy testing ✌️