Categories
Appium Tutorials

How to Use Touch Actions in Appium: Swipe Tap Touch



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:

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


Source