Gestures

In mobile app testing, simulating user interactions like swipes, taps, and pinch-zoom gestures is crucial for validating how the app behaves. Gestures are a natural part of mobile app navigation, and Appium provides ways to automate these actions to test the app's usability and responsiveness.

Gestures let you interact with mobile apps like a real user would. Examples include:

  • Tapping on buttons or icons.
  • Swiping through image galleries, lists, or screens.
  • Scrolling down pages or up to the top.
  • Pinch and Zoom to zoom in or out on images or maps.
  • Long Press for interactions that need a longer touch (e.g., dragging an item).

In the latest versions of Appium, you can also use the W3C Actions API, which provides more flexibility and compatibility with both Android and iOS.

Java
C#
Python
Javascript
Kotlin
Copy
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence swipe = new Sequence(finger, 1);
swipe.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), startX, startY));
swipe.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()));
swipe.addAction(finger.createPointerMove(Duration.ofMillis(1000), PointerInput.Origin.viewport(), endX, endY));
swipe.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));

driver.perform(Arrays.asList(swipe));

This approach is more versatile and works on both platforms without requiring separate Android or iOS-specific code.

Appium also lets you perform gestures using the execute command, which gives you more control compared to normal gesture methods. With executeScript("mobile: ..."), you can directly call built-in mobile actions like swipe, scroll, pinch, or long press. These commands work at a lower level and are useful when regular methods don't work properly or when you need more precise control over gestures. For example, you can use mobile: swipeGesture or mobile: pinchOpenGesture to perform advanced interactions. This approach is especially helpful in Appium 2.x, where many modern gesture actions are exposed through execute commands.

Following are some of the gesture commands.

Appium Gestures (Android)


Click Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement clickGestureElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: clickGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) clickGestureElement).getId()),
	entry("x", 100),
	entry("y", 100)
));

Long Click Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement longClickGestureElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: longClickGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) longClickGestureElement).getId()),
	entry("x", 100),
	entry("y", 100),
	entry("duration", 1000)
));

Double Click Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement doubleClickGestureElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: doubleClickGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) doubleClickGestureElement).getId()),
	entry("x", 100),
	entry("y", 100)
));

Drag Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement dragElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: dragGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) dragElem).getId()),
	entry("startX", 100),
	entry("startY", 100),
	entry("endX", 100),
	entry("endY", 100),
	entry("speed", 3000)
));

Fling Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement flingElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: flingGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) flingElem).getId()),
	entry("direction", "down"),
	entry("left", 0),
	entry("top", 0),
	entry("width", 500),
	entry("height", 1000),
	entry("speed", 5000)
));

Pinch Open Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement pinchOElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: pinchOpenGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) pinchOElem).getId()),
	entry("direction", "down"),
	entry("percent", 0.75),
	entry("left", 100),
	entry("top", 100),
	entry("width", 500),
	entry("height", 1000),
	entry("speed", 3000)
));

Pinch Close Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement pinchCElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: pinchCloseGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) pinchCElem).getId()),
	entry("direction", "down"),
	entry("percent", 0.75),
	entry("left", 100),
	entry("top", 100),
	entry("width", 500),
	entry("height", 1000),
	entry("speed", 3000)
));

Swipe Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement swipeElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: swipeGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) swipeElem).getId()),
	entry("direction", "up"),
	entry("percent", 0.75),
	entry("left", 100),
	entry("top", 100),
	entry("width", 200),
	entry("height", 200)
));

Scroll Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement scrollElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: scrollGesture", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) scrollElem).getId()),
	entry("direction", "up"),
	entry("percent", 0.30),
	entry("left", 100),
	entry("top", 100),
	entry("width", 200),
	entry("height", 200),
	entry("speed", 3000)
));

Appium Gestures (iOS)

Swipe Gesture

Java
C#
Python
Javascript
Kotlin
Copy
driver.executeScript("mobile: swipe", Map.ofEntries(
	entry("direction", "up"),
	entry("percent", 0.30),
	entry("velocity", 2500)
));

Scroll Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement scrollElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: scroll", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) scrollElement).getId()),
	entry("direction", "down")
));

Pinch Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement pinchElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: pinch", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) pinchElement).getId()),
	entry("scale", 2),
	entry("velocity", 1.0)
));

Tap Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement tapElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: tap", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) tapElement).getId()),
	entry("x", 1),
	entry("y", 1)
));

Double Tap Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement dblTapElement = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: doubleTap", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) dblTapElement).getId()),
	entry("x", 1),
	entry("y", 1)
));

Touch and Hold Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement longTapElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: touchAndHold", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) longTapElem).getId()),
	entry("duration", 2.0),
	entry("x", 1),
	entry("y", 1)
));

Two finger Tap Gesture

Java
C#
Python
Javascript
Kotlin
Copy
WebElement twoFingerTapElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: twoFingerTap", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) twoFingerTapElem).getId())
));

Drag From to for Duration

Java
C#
Python
Javascript
Kotlin
Copy
WebElement dragFromToDurationElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: dragFromToDuration", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) dragFromToDurationElem).getId()),
	entry("duration", 2.0),
	entry("fromX", 100),
	entry("fromY", 100),
	entry("toX", 200),
	entry("toY", 300)
));

Drag From to for Duration with velocity

Java
C#
Python
Javascript
Kotlin
Copy
WebElement dragFromWithVelocityElem = driver.findElement(AppiumBy.id("elementId"));
WebElement dragToWithVelocityElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: dragFromToWithVelocity", Map.ofEntries(
	entry("fromElementId", ((RemoteWebElement) dragFromWithVelocityElem).getId()),
	entry("toElementId", ((RemoteWebElement) dragToWithVelocityElem).getId()),
	entry("pressDuration", 0.5),
	entry("holdDuration", 0.1),
	entry("velocity", 400),
	entry("fromX", 100),
	entry("fromY", 100),
	entry("toX", 200),
	entry("toY", 300)
));

Rotate Element

Java
C#
Python
Javascript
Kotlin
Copy
WebElement rotateElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: rotateElement", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) rotateElem).getId()),
	entry("rotation", -Math.PI / 2),
	entry("velocity", Math.PI / 4)
));

TAP with number of taps

Java
C#
Python
Javascript
Kotlin
Copy
WebElement noTapsElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: tapWithNumberOfTaps", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) noTapsElem).getId()),
	entry("numberOfTaps", 2),
	entry("numberOfTouches", 1)
));

Scroll to element

Java
C#
Python
Javascript
Kotlin
Copy
WebElement scrollToElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: scrollToElement", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) scrollToElem).getId())
));

Select Picker Wheel Value

Java
C#
Python
Javascript
Kotlin
Copy
WebElement selectPickerWheelValueElem = driver.findElement(AppiumBy.id("elementId"));
driver.executeScript("mobile: selectPickerWheelValue", Map.ofEntries(
	entry("elementId", ((RemoteWebElement) selectPickerWheelValueElem).getId()),
	entry("order", "next"),
	entry("offset", 0.15)
));

Alert

Java
C#
Python
Javascript
Kotlin
Copy
driver.executeScript("mobile: alert", Map.ofEntries(
	entry("action", "accept"),
	entry("buttonLabel", "Cool Button")
));