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:
- Tab by using an element
- Tab by using x,y coordinates
- Press by using an element and duration (in seconds)
- Press by using x,y coordinates, and duration (in seconds)
- Horizontal swipe by using the start and end percentage of the screen and an anchor for the height.
- Vertical swipe by using the start and end percentage of the screen and an anchor for the width.
- Swipe one element to another element
- Multitouch by using an element
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.
- verticalSwiteByPercentages gets start point percentage with respect to the screen, endpoint percentage with respect to the screen, and anchor percentage with respect to the screen.
- swipeByElements gets the first and second elements to perform swipe operation.
- tabByElement gets an element to tap on it.
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

Onur Baskirt is a Software Engineering Leader with international experience in world-class companies. Now, he is a Software Engineering Lead at Emirates Airlines in Dubai.
Thanks Onur, you kept your word. Cannot wait to practice new code.
Welcome Siddhart. I tried some of them and they worked without any problem. If you face with a problem, please do not hesitate to write a comment with the problem definition and I will try to fix it ASAP. :) Have a good day!
Hi Onur,
Could you please codes for findElement and waitVisibility. Its showing to create in project.
//Wait Visibility of an element
protected void waitVisibility (By by) {
wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}
protected AndroidElement findElement (By by) {
return (AndroidElement) driver.findElement(by);
}
Hi Onur,
Thanks for the article.But it is asking me to create method for point .then i downgraded to java client 6.0.0 version.But still problem remains same.Can you help me
Welcome. For this project, I used below versions. Please, try them in your pom.xml file.
appium.version: 6.0.0-BETA5
selenium.version: 3.11.0
testng.version: 6.14.3
Why don’t you use the longPress method with LongPressOptions for swiping and pressing?
https://appium.github.io/java-client/io/appium/java_client/TouchAction.html#longPress-io.appium.java_client.touch.LongPressOptions-
Could you also have a dragging method example?
Hi Leon, as you wrote there are many alternatives available. I did not have any drag method example but if you will have would you share with us with a comment? Then I will add code snippet and put your name in the blog post. ;) Have a good day! :)
TouchAction action = new TouchAction(driver);
action.longPress(elem1).waitAction(3000).moveTo(elem2).perform().release();
Reference: https://stackoverflow.com/questions/36084388/appium-long-press-and-than-move-elementdrag-and-drop-is-not-working
Is the TouchAction deprecated now as I am unable to use it..I have a scenario where a text link widget “Privacy policy and Terms & conditions” is a single element in object spy but two different links..so I wanted to try TouchAction to click each link using Point coordinates. Can you suggest or give alternate code using TouchActions or any other alternative where I can click 2 different links in a single web element
https://discuss.appium.io/t/touch-actions-failing-for-android-automation-after-upgrading-from-appium-2-1-to-2-5-version/41981
Hi Onur Baskirt,
I have another question:
Is it necessary to create new TouchAction(driver) in every method?
Can i create a private member variable of TouchAction and use it without creating a new object for every action, or is it required so that previous configuration will not be executed when i call another method?
I think you can do it. Right now, I could not try on my machine cuz I need to do a lot of settings for appium but please would you try this for me as well. It is better to try. If u get an error, please share it as well. Thank you.
Thank you so much. I have another question: which I didn’t find a solution for it:
How can I go to the home screen and back to the app? I don’t want to lunch the app again from the first point I want to back to the same page as I left the app.
I did not try that but I think it can be done by activities.
https://stackoverflow.com/questions/22710538/how-to-switch-from-one-app-to-another-app-at-run-time
https://discuss.appium.io/t/need-help-for-self-driver-navigate-back/13955/3
Thank you so much, Onur.
Welcome Masha. I thank you too.
hi sir.
how to perform the below tap by co-ordinates using appium ios device
//Tap by coordinates
public void tapByCoordinates (int x, int y) {
new TouchAction(driver)
.tap(point(x,y))
.waitAction(waitOptions(Duration.ofMillis(250))).perform();
}
thank you.
We have two choices with PointOption:
//Using PointOption.point(x, y), which is a static instance of PointOption with those coordinate values
TouchAction touchAction = new TouchAction(driver);
touchAction.tap(PointOption.point(1280, 1013)).perform()
//Using PointOption().withCoordinates(x, y), which returns a reference to the PointOption instance after setting those coordinate values
TouchAction touchAction = new TouchAction(driver);
touchAction.tap(new PointOption().withCoordinates(1280, 1013)).perform()
Reference: https://stackoverflow.com/questions/49048841/appium-tapint-x-int-y-function-seems-to-be-deprecated-any-replacements
Would you try and if it works, please let us know. Then, I will also update the article as well. Thank you.
Another reference: https://stackoverflow.com/questions/44282417/how-to-scroll-with-appium-1-7-1-using-touchaction
thank you sir i found the solution in the stackoverflow
after leave the in this site.
thank you very much for your response.
Welcome, Vamsikrishna. It is working without any problem?
Hi Onur,
Can you please explain what is anchorPercentage?
Hi Siddhart,
With this, you will adjust the starting point of the scroll.
Yes sir, it is working fine.
thank you.
Thank you so much Vamsikrishna.
Thank you again, your tutorials are like the treasure for me. I head to a problem:
when I use “sendtext”, application crashes! the text length is not beyond text field limit. but it happens more when the field is empty( for the edit that section doesn’t sometimes!)
Appium version: 1.9.1
could you please let me know if you have any solution?
npm uninstall -g appium
npm install appium@1.9.1-beta2
This will give you the latest beta that has the fix. (Upgrade the appium version. Maybe you should try v1.10.0
reference: https://github.com/appium/appium/issues/11323
Hi Onur,
We have always issue with handling date time picker in appium even there is no proper solution in appium forum. I would request to check and provide solution how we can deal with .
Ex. While entering date of birth and we are into year field we have scroll up till past year.
Scroll down to certain number which is not visible that point of time.
Waiting for your reply. Here we dont have option to upload screenshot or else I could have posted the same.
It look so tricky. Is it possible to enter the year text? Only scroll element available? Are you doing
do a scroll
then check the year is visible and present
if yes tab it
if not do one more scroll
then check the year is visible and present
if yes tab it
if not do one more scroll
….
You should write a loop and try to do this flow. Now, I can only suggest this Siddharth.
how can we calculate the anchorpercentage, end percentage and startpercentage
public static void swipeHorizontal(AppiumDriver driver, double startPercentage, double finalPercentage, double anchorPercentage, int duration) throws Exception {
Dimension size = driver.manage().window().getSize();
int anchor = (int) (size.height * anchorPercentage);
int startPoint = (int) (size.width * startPercentage);
int endPoint = (int) (size.width * finalPercentage);
new TouchAction(driver).press(startPoint, anchor).waitAction(Duration.ofMillis(duration)).moveTo(endPoint, anchor).release().perform();
}
public static void swipeVertical(AppiumDriver driver, double startPercentage, double finalPercentage, double anchorPercentage, int duration) throws Exception {
Dimension size = driver.manage().window().getSize();
int anchor = (int) (size.width * anchorPercentage);
int startPoint = (int) (size.height * startPercentage);
int endPoint = (int) (size.height * finalPercentage);
new TouchAction(driver).press(anchor, startPoint).waitAction(Duration.ofMillis(duration)).moveTo(anchor, endPoint).release().perform();
}
Call them by:
For scroll up: swipeVertical((AppiumDriver)driver,0.9,0.1,0.5,3000);
For scroll down: swipeVertical((AppiumDriver)driver,0.1,0.9,0.5,3000);
For right to left: swipeHorizontal((AppiumDriver) driver,0.9,0.01,0.5,3000);
For left to right: swipeHorizontal((AppiumDriver) driver,0.01,0.9,0.5,3000);
ref: https://stackoverflow.com/questions/49233444/swipe-funtion-in-andriod-for-java-client-5-0-3-is-not-working
Just play with these numbers on your application.
Hi Onur i used same code as per your suggested when i execute test swipe is not showing in screen but the test is passed. Help me on this thank you.
appium-1.9.0
java-client – 6.1.0
selenium – 3.14.0
my code
DesiredCapabilities capabilities=new DesiredCapabilities();
capabilities.setCapability(“platformName”, “Android”);
capabilities.setCapability(“platformVersion”, “7.0”);
capabilities.setCapability(“appPackage”, “com.hmh.api”);
capabilities.setCapability(“appActivity”, “com.hmh.api.ApiDemos”);
capabilities.setCapability(“deviceName”, “3300e5417489a4ed”);
AndroidDriver driver=new AndroidDriver(new URL(“http://127.0.0.1:4723/wd/hub”), capabilities);
Thread.sleep(5000);
WebElement element = driver.findElement(By.xpath(“//android.widget.TextView[@text=’App’]”));
TouchAction action=new TouchAction(driver);
action.tap(ElementOption.element(element)).perform();
Thread.sleep(3000);
org.openqa.selenium.Dimension size = driver.manage().window().getSize();
int anchor = (int) (size.width * 0.50);
int startPoint = (int) (size.height * 0.50);
int endPoint = (int) (size.height * 0.90);
action.press(PointOption.point(anchor, startPoint))
.waitAction(WaitOptions.waitOptions(Duration.ofMillis(200)))
.moveTo(PointOption.point(anchor, endPoint)).release().perform();
Thread.sleep(5000);
driver.quit();
Hi Sridhar, I am relocating and I will not have time. :( In my new home, I will not have internet for 1 week as well. I am super busy nowadays about home issues.
Official documents: http://appium.io/docs/en/writing-running-appium/touch-actions/
https://discuss.appium.io/t/appium-driver-swipe/19127
Please debug your project based on the above information.
Thank you for replay Onur, continue with your work. When are you free just look on it. thank you.
Sure Sridhar. I need maybe 3-4 weeks to fully settle down. Then I will focus on everything again.
Hi Onur,
Do you know is possible to perform double tap action and that action not being two consequtive tap actions. It would be like double tap on instagram app, when you like some photos.
Hi Vladimir,
TouchActions action = new TouchActions(driver);
action.doubleTap(element);
action.perform();
Ref: http://appium.io/docs/en/commands/interactions/touch/double-tap/
I hope it works.
I already saw this code snippet in appium docs. This is the error I’m getting: java.lang.ClassCastException: io.appium.java_client.android.AndroidDriver cannot be cast to org.openqa.selenium.interactions.HasTouchScreen
https://stackoverflow.com/questions/48458726/classcastexception-with-new-appium-java-touchactions
new TouchAction(android)
.press(point(startX,startY))
.waitAction(waitOptions(ofMillis(2000)))
.moveTo(point(endX, endY))
.release().perform();
This does not work, just highlighting one element
hello,
I am facing the problem with swipe for the end of the particular elements in an e-commerce app.
one time swipe is working but not at the element I need to click.
USe swipe and wait visibility together and when u see the element try to click it.
one more thing, can I click on text tox using coordinate and then can I send the send key on that text box…Plz Give solution
I dont know sir.
Hi Onur,
I wanted to do vertical scroll till the the mentioned/specific data is located. I am using latest appium 1.10 . Please let me know any solution, i m struggling with this alot.
Hi Akshay, for a long time I did not work on Appium. I am highly focused on microservices testing. Maybe it is about Appium version. Please check this site, https://discuss.appium.io/t/i-want-to-know-a-genric-method-for-scrolling-in-appium-java/23823
Hi Onur,
Issue 1:
I’m not able to Click/Tap on particular button when I’m automating in mobile web browser using selenium Java. I have tried in all ways like below:
Actions:
(1) Tap action
public void TapMobile() {
if (elementEnabled()) {
WebElement Element1 = Driver.findElement(By.xpath(“Element”));
TouchActions tapAction = new TouchActions(Driver).singleTap(Element1);
tapAction.perform();
}
(2) PointClick
if (elementEnabled()) {
Point point = Element.getLocation();
int xcord = point.getX();
System.out.println(“Position of the webelement from left side is ” + xcord + ” pixels”);
int ycord = point.getY();
System.out.println(“Position of the webelement from top side is ” + ycord + ” pixels”);
Actions action = new Actions(Driver)
action.moveToElement(Element, xcord, ycord).click().build().perform();
}
(3) AjaxClick
if (elementEnabled()) {
// Wait wait = new FluentWait(Driver)
// .withTimeout(30,SECONDS)
// .pollingEvery(5,SECONDS)
// .ignoring(NoSuchElementException.class);
WebElement Element1 = (new WebDriverWait(Driver, 30))
.until(ExpectedConditions.presenceOfElementLocated(By.xpath(“Element”)));
Element1.click();
}
}
At the end, I’m getting this exception: org.openqa.selenium.JavascriptException: javascript error: Argument to isShown must be of type Element
Issue 2:
I’m not able to verify/get a value from a text box when I’m automating in mobile web browser using Selenium Java. Please see my code below:
(1) Get textbox value
public void TextBoxValue() {
if (Element.isEnabled()) {
String txt= Element.getAttribute(“value”);
System.out.println(“Text box value is ” + txt);
}
}
(2) Verify a textbox value
public void VerifyTextMatch() {
if (Data != null) //Data which wants to verify
{
String Actual = Element.getText(); // Here , I’m trying to get the text
if (Condition.equalsIgnoreCase(“true”)) {
if (Actual.contains(Data)) {
Report.updateTestLog(Action, “Text Matched as expected, Actual: ” + Actual + ” Expected: ” + Data,
Status.PASS);
} else {
Report.updateTestLog(Action, “Text not Matched, Actual: ” + Actual + ” Expected: ” + Data,
Status.FAIL);
}
} else if (Condition.equalsIgnoreCase(“false”)) {
if (!Actual.contains(Data)) {
Report.updateTestLog(Action,
“Text not Matched as expected, Actual: ” + Actual + ” Expected: ” + Data, Status.PASS);
} else {
Report.updateTestLog(Action, “Text should not Match, Actual: ” + Actual + ” Expected: ” + Data,
Status.FAIL);
}
}
}
}
Please help me to fix these issues & suggest your thoughts.
Thanks!
Hi, for a long time I did not do any mobile testing but if I have time I will check these problems. In this article I shared some actions for native apps but for mobile web, did you do these setup? http://appium.io/docs/en/writing-running-appium/web/mobile-web/
Hi Onur, Thanks for your response. Setup has been done perfectly, but we are facing some issues as mentioned above. It would be great help if you give any suggestions.
One more question is, Do you have any idea about “touchstart” javascript mobile action, how to use in selenium web driver java?
Thanks!!!
Hi Subhu,
I did not implement it before. Are you running it for Android or iOS? Better to search on the internet by using JSExecutor.
Hi Onur,
How do i select value from auto complete drop down?
I entered the value “Unit” and from the suggestion i want to select 2nd option which is “United States” but don’t know what syntax should be used
Got an understanding that pressKeyCode method is is deprecated hence,i am not able to find an alternate method to select value from dropdown as don’t know the syntax for presskey method.
driver.pressKeyCode(AndroidKeyCode.KEYCODE_PAGE_DOWN);
driver.pressKeyCode(AndroidKeyCode.ENTER);;
Please assist
Hi, Maybe better to put some pause then move the auto-completed element and tab to it?
How to zoom in and zoom out in android map ,which method to use for both functionality?
Hi Pooja,
I suggest you try:
– First: You can try MultiTouch function: https://appium.io/docs/en/commands/interactions/touch/multi-touch-perform/
– Second: Please, check this article: https://appiumpro.com/editions/67-generating-touch-gestures-to-zoom-in-and-out-on-google-maps
– Third: There are some nice discussions on the below page:
https://discuss.appium.io/t/how-to-zoomin-and-zoom-out-using-appium/2906/7
https://stackoverflow.com/questions/57328715/zoomin-zoomout-methods-on-java-in-appium
Hi Onur,
How we can perform the same action (Zoom in/Zoom out) on an IOS device Apple map, which method we should use. please share some references to the code. Thanks
Hi Onur,
After i scroll to end of the page , the focus to the element which i have to click is lost. Instead of clicking on element it click on some random location. The Inspector is also not able to locate it after the scroll.
I have not encountered it before, but I would put a debug point after the scroll and output which elements are there. If the scroll is fast, maybe it’s trying to click before it appears on the screen, or the code clicks the element before it appears.
I want to tap on an element on ios device.. I am using below code which works sometime but not trust worthy as it dont perform the action every time
Map args = new HashMap();
args.put(“element”, (myelement.getId()));
args.put(“x”, 2);
args.put(“y”, 2);
appiumDriver.get().executeScript(“mobile: tap”, args);
Hello sir Can you help how to tap a location by coordinate as touchaction is deprecated
Bard’s reply:
There are a few ways to tap a location by coordinate in Appium 2.0. One way is to use the tap command. The tap command takes three arguments: the number of fingers to use, the x-coordinate, and the y-coordinate. For example, the following command would tap the screen with one finger at the coordinates (271, 642):
Code snippet
driver.tap(1, 271, 642);
Use code with caution. Learn more
Another way to tap a location by coordinate is to use the elementClick command. The elementClick command takes two arguments: the element to click on and the duration of the click. For example, the following command would click on the element with the id foo for 500 milliseconds:
Code snippet
driver.elementClick(driver.findElementById(“foo”), 500);
Use code with caution. Learn more
Finally, you can also use the actions API to tap a location by coordinate. The actions API allows you to chain together a series of actions, such as press and release. For example, the following code would tap the screen at the coordinates (271, 642) for 500 milliseconds:
Code snippet
driver.actions().press(271, 642).release().perform();
Use code with caution. Learn more
Which method you use to tap a location by coordinate depends on your specific needs. The tap command is the simplest option, but it is not as flexible as the elementClick command or the actions API. The elementClick command is more flexible than the tap command, but it requires you to know the ID of the element you want to click on. The actions API is the most flexible option, but it is also the most complex.
Hi Sir,
Can you let me know how to move through an horizontal slider elementusing the same Appium Java