How to Use Touch Actions in Appium? Hi all, in this article, I will answer this question and share with you the details of how to do some appium mobile actions such as swipe, tap, press, multi-touch. I wrote a MobileActions class which comprises of these actions. You can instantiate it into your BaseScreen or BasePage class and use it in your Screen/Page classes. I will start with the MobileActions class. By using these class, you can do the below actions:
Table of Contents
How to Use Touch Actions in Appium Code Examples
MobileActions Class – Here is the code of all actions:
package utilities; import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; import static io.appium.java_client.touch.offset.ElementOption.element; import static io.appium.java_client.touch.offset.PointOption.point; import static java.time.Duration.ofMillis; import static java.time.Duration.ofSeconds; import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidElement; import org.openqa.selenium.Dimension; public class MobileActions { private AndroidDriver<MobileElement> driver; public MobileActions (AndroidDriver driver) { this.driver = driver; } //Tap to an element for 250 milliseconds public void tapByElement (AndroidElement androidElement) { new TouchAction(driver) .tap(tapOptions().withElement(element(androidElement))) .waitAction(waitOptions(ofMillis(250))).perform(); } //Tap by coordinates public void tapByCoordinates (int x, int y) { new TouchAction(driver) .tap(point(x,y)) .waitAction(waitOptions(ofMillis(250))).perform(); } //Press by element public void pressByElement (AndroidElement element, long seconds) { new TouchAction(driver) .press(element(element)) .waitAction(waitOptions(ofSeconds(seconds))) .release() .perform(); } //Press by coordinates public void pressByCoordinates (int x, int y, long seconds) { new TouchAction(driver) .press(point(x,y)) .waitAction(waitOptions(ofSeconds(seconds))) .release() .perform(); } //Horizontal Swipe by percentages public void horizontalSwipeByPercentage (double startPercentage, double endPercentage, double anchorPercentage) { Dimension size = driver.manage().window().getSize(); int anchor = (int) (size.height * anchorPercentage); int startPoint = (int) (size.width * startPercentage); int endPoint = (int) (size.width * endPercentage); new TouchAction(driver) .press(point(startPoint, anchor)) .waitAction(waitOptions(ofMillis(1000))) .moveTo(point(endPoint, anchor)) .release().perform(); } //Vertical Swipe by percentages public void verticalSwipeByPercentages(double startPercentage, double endPercentage, double anchorPercentage) { Dimension size = driver.manage().window().getSize(); int anchor = (int) (size.width * anchorPercentage); int startPoint = (int) (size.height * startPercentage); int endPoint = (int) (size.height * endPercentage); new TouchAction(driver) .press(point(anchor, startPoint)) .waitAction(waitOptions(ofMillis(1000))) .moveTo(point(anchor, endPoint)) .release().perform(); } //Swipe by elements public void swipeByElements (AndroidElement startElement, AndroidElement endElement) { int startX = startElement.getLocation().getX() + (startElement.getSize().getWidth() / 2); int startY = startElement.getLocation().getY() + (startElement.getSize().getHeight() / 2); int endX = endElement.getLocation().getX() + (endElement.getSize().getWidth() / 2); int endY = endElement.getLocation().getY() + (endElement.getSize().getHeight() / 2); new TouchAction(driver) .press(point(startX,startY)) .waitAction(waitOptions(ofMillis(1000))) .moveTo(point(endX, endY)) .release().perform(); } //Multitouch action by using an android element public void multiTouchByElement (AndroidElement androidElement) { TouchAction press = new TouchAction(driver) .press(element(androidElement)) .waitAction(waitOptions(ofSeconds(1))) .release(); new MultiTouchAction(driver) .add(press) .perform(); } }
You can use this class by instantiating it in BasePage or BaseScreen class as shown below:
public class BaseScreen { protected AndroidDriver<MobileElement> driver; protected WebDriverWait wait; protected MobileActions mobileActions; public BaseScreen(AndroidDriver<MobileElement> driver) { this.driver = driver; wait = new WebDriverWait(driver, 15); mobileActions = new MobileActions(driver); } ...... ...... ...... //You BaseScreen class code continues.
And from now on you can use mobileActions object in your screen classes too. You can see its usage in below code snippet.
package screens; import io.appium.java_client.MobileElement; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidElement; import lombok.SneakyThrows; import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions; public class CandidateMainScreen extends BaseScreen { public CandidateMainScreen(AndroidDriver<MobileElement> driver) { super(driver); } /** * Mobile Elements */ By allowWhenUsingBy = By.id("com.android.permissioncontroller:id/permission_allow_foreground_only_button"); By jobsBy = By.id("com.isinolsun.app:id/rootRelativeView"); /** * Actions */ public void allowNotification() { if (wait.until(ExpectedConditions.visibilityOfElementLocated(allowWhenUsingBy)).isDisplayed()) { wait.until(ExpectedConditions.visibilityOfElementLocated(allowWhenUsingBy)).click(); } } @SneakyThrows public void clickToJob() { wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(jobsBy)).get(1).click(); Thread.sleep(4000); //Just Wait for a while } public void swipeDownAndClickToJob() { waitAndFindElements(jobsBy); mobileActions.verticalSwipeByPercentages(0.6, 0.3, 0.5); mobileActions.swipeByElements((AndroidElement) waitAndFindElements(jobsBy).get(1), (AndroidElement) waitAndFindElements(jobsBy).get(0)); mobileActions.swipeByElements((AndroidElement) waitAndFindElements(jobsBy).get(0), (AndroidElement) waitAndFindElements(jobsBy).get(1)); mobileActions.tapByElement((AndroidElement) waitAndFindElements(jobsBy).get(1)); } }
As you see in the above screen class, we can use mobileAction object to perform swipe and tab actions.
You can use all appium mobile actions which are declared in MobileActions class in this way. Also, you can add new appium mobile actions to enhance this class. This code is modified for an Android project but you can change the driver type as AppiumDriver or as IOSDriver to use it in your project needs.
GitHub Project
https://github.com/swtestacademy/appium-parallel-tests/tree/appium-mobile-actions
Youtube Demo Video
I hope you enjoy reading the appium mobile actions article and it helped you in your mobile automation projects. Please share your feedback on the comment section with us.
You can also find our Appium articles here: Appium articles.
Thank you.
Onur Baskirt