[email protected]
Appium-Python-Client==2.11.1
Hi, how do I perform a three finger tap with appium? I want to perform the three finger tap 3 times.
My current code looks like this:
# Set up coordinates for the taps if needed, or find an element to tap on
x1, y1 = 850, 450 # Coordinates for first finger
x2, y2 = 900, 450 # Coordinates for second finger
x3, y3 = 950, 450 # Coordinates for third finger
# Create TouchAction instances for each tap
tap1 = TouchAction(self.driver).tap(x=x1, y=y1)
tap2 = TouchAction(self.driver).tap(x=x2, y=y2)
tap3 = TouchAction(self.driver).tap(x=x3, y=y3)
# Create a MultiAction object
multi_touch = MultiAction(self.driver)
multi_touch.add(tap1, tap2, tap3)
# Perform the multi-touch action (the triple tap)
multi_touch.perform()
multi_touch.perform()
multi_touch.perform()
However, I’m encountering this error:
E Stacktrace:
E io.appium.uiautomator2.common.exceptions.UiAutomator2Exception: Cannot invoke method public boolean androidx.test.uiautomator.InteractionController.performMultiPointerGesture(android.view.MotionEvent$PointerCoords[][]) on object androidx.test.uiautomator.InteractionController@f87e653 with parameters [[[Landroid.view.MotionEvent$PointerCoords;@97eb642]
E at io.appium.uiautomator2.utils.ReflectionUtils.invoke(ReflectionUtils.java:85)
E at io.appium.uiautomator2.core.InteractionController.doPerformMultiPointerGesture(InteractionController.java:127)
E at io.appium.uiautomator2.core.InteractionController.access$400(InteractionController.java:29)
E at io.appium.uiautomator2.core.InteractionController$5.run(InteractionController.java:142)
E at android.app.UiAutomation.executeAndWaitForEvent(UiAutomation.java:920)
E at io.appium.uiautomator2.core.EventRegister.runAndRegisterScrollEvents(EventRegister.java:40)
E at io.appium.uiautomator2.core.EventRegister.runAndRegisterScrollEvents(EventRegister.java:81)
E at io.appium.uiautomator2.core.InteractionController.performMultiPointerGesture(InteractionController.java:139)
E at io.appium.uiautomator2.handler.MultiPointerGesture.safeHandle(MultiPointerGesture.java:44)
E at io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:59)
E at io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:277)
E at io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:271)
E at io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:68)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
E at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
E at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
E at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
E at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
E at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
E at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
E at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
E at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
E at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
E at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:345)
E at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)
E at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)
E at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
E at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
E at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:611)
E at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:552)
E at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:466)
E at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
E at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
E at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
E at java.lang.Thread.run(Thread.java:1012)
E Caused by: java.lang.reflect.InvocationTargetException
E at java.lang.reflect.Method.invoke(Native Method)
E at io.appium.uiautomator2.utils.ReflectionUtils.invoke(ReflectionUtils.java:83)
E ... 42 more
E Caused by: java.lang.IllegalArgumentException: Must provide coordinates for at least 2 pointers
E at androidx.test.uiautomator.InteractionController.performMultiPointerGesture(InteractionController.java:724)```
Any example code snippets? I’ve tried updating my code to use PointerInput, but still have issues witha triple touch tap…
# Set up the pointer input devices (one for each finger)
finger1 = PointerInput(PointerInput.POINTER_TOUCH, "finger1")
finger2 = PointerInput(PointerInput.POINTER_TOUCH, "finger2")
finger3 = PointerInput(PointerInput.POINTER_TOUCH, "finger3")
# Coordinates for each finger tap
x1, y1 = 935, 450
x2, y2 = 1135, 470
x3, y3 = 1335, 480
for _ in range(3): # Repeat the gesture three times
action = ActionBuilder(self.driver)
# Create actions for each finger
action.add_pointer_input(
finger1, finger1.create_pointer_move(x=x1, y=y1, duration=0)
action.add_pointer_input(
finger1, finger1.create_pointer_down(PointerInput.POINTER_TOUCH)
action.add_pointer_input(
finger1, finger1.create_pointer_up(PointerInput.POINTER_TOUCH)
action.add_pointer_input(
finger2, finger2.create_pointer_move(x=x2, y=y2, duration=0)
action.add_pointer_input(
finger2, finger2.create_pointer_down(PointerInput.POINTER_TOUCH)
action.add_pointer_input(
finger2, finger2.create_pointer_up(PointerInput.POINTER_TOUCH)
action.add_pointer_input(
finger3, finger3.create_pointer_move(x=x3, y=y3, duration=0)
action.add_pointer_input(
finger3, finger3.create_pointer_down(PointerInput.POINTER_TOUCH)
action.add_pointer_input(
finger3, finger3.create_pointer_up(PointerInput.POINTER_TOUCH)
# Perform the actions
action.perform()
print("performing triple tap")
sleep(0.1) # Wait for a short duration between gestures
actions = ActionChains(self)
# 'mouse' pointer action
actions.w3c_actions.pointer_action.click_and_hold(origin_el)
if pause is not None and pause > 0:
actions.w3c_actions.pointer_action.pause(pause)
actions.w3c_actions.pointer_action.move_to(destination_el)
actions.w3c_actions.pointer_action.release()
actions.perform()
return cast('WebDriver', self)
def tap(self, positions: List[Tuple[int, int]], duration: Optional[int] = None) -> 'WebDriver':
"""Taps on an particular place with up to five fingers, holding for a
certain time
Args:
positions: an array of tuples representing the x/y coordinates of
the fingers to tap. Length can be up to five.
duration: length of time to tap, in ms
Usage:
driver.tap([(100, 20), (100, 60), (100, 100)], 500)
Thank you!, I was able to get multi-touch working with ‘tap’.
coords = [(935, 450), (1135, 470), (1335, 480)]
for _ in range(3):
self.page_utils.tap_location(coords)
print("Performed triple tap.")