appium: touchPerform actions processed separately: could not do swipe.

The problem

Basic test - trying to do swipe (from right to left) in Android app (React Native):

const windowSize = await driver.getWindowSize();

const right2leftSwipeOptions = {
        startX: windowSize.width * 0.9,
        startY: windowSize.height / 2,
        endX: windowSize.width * 0.1,
        endY: windowSize.height / 2
      };

await driver.touchPerform([
        {
          action: "press",
          options: {
            x: right2leftSwipeOptions.startX,
            y: right2leftSwipeOptions.startY
          }
        },
        {
          action: "moveTo",
          options: {
            x: right2leftSwipeOptions.endX,
            y: right2leftSwipeOptions.endY
          }
        },
        { action: "release" }
      ]);

All is according to your docs: sample for WebdriverIO. Only 3 actions: press, moveTo, release.

So, nothing happens - no actual swiping! See gist#1 with Appium log. In log we could see that every action processed separately! But stop, description for touchPerform clearly says that:

‘Touch Perform’ works similarly to the other singular touch interactions, except that this allows you to chain together more than one touch action as one command. This is useful because Appium commands are sent over the network and there’s latency between commands. This latency can make certain touch interactions impossible because some interactions need to be performed in one sequence.

Okay, I spent 2 days to do something useful but not invented nothing more than almost randomly add 1 new action to my touchPerform sequence - wait. Now my code looks like this:

const windowSize = await driver.getWindowSize();

const right2leftSwipeOptions = {
        startX: windowSize.width * 0.9,
        startY: windowSize.height / 2,
        endX: windowSize.width * 0.1,
        endY: windowSize.height / 2,
        delay: 0
      };

await driver.touchPerform([
        {
          action: "press",
          options: {
            x: right2leftSwipeOptions.startX,
            y: right2leftSwipeOptions.startY
          }
        },
        { action: "wait", options: { mseconds: right2leftSwipeOptions.delay } },
        {
          action: "moveTo",
          options: {
            x: right2leftSwipeOptions.endX,
            y: right2leftSwipeOptions.endY
          }
        },
        { action: "release" }
      ]);

And now swipe is working! Check gist#2 with Appium log. Now Appium works with all actions in 1 sequence! As it should be!

So, there are my questions/remarks:

  1. Why first code is not working as 1 sequence?
  2. Why in your documentation not working example?
  3. Why adding “wait” solved problem? Is it important where exactly put “wait” in sequence order?
  4. Why delay is could be any number without any difference in result: 0, 100, 1000, 5000? Actually there is no delay for 5 seconds - swipe would be done always with same time.
  5. Why in gist#1 we could see that Appium “Shutting down because we waited 60 seconds for a command” almost immediately? And in gist#2 all is good: shutting down really comes after 60 seconds?

Environment

  • Appium version: 1.10.0
  • Desktop OS/version used to run Appium: MAC OS X 10.10.5
  • Mobile platform/version under test: Android
  • Real device or emulator/simulator: Real device (Honor 8 Android 7 API 24)
  • Appium CLI or Appium.app|exe: Appium.app

Link to Appium logs

  1. Appium log with Bad reaction to performTouch
  2. Appium log with Good reaction to performTouch

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 25 (5 by maintainers)

Most upvoted comments

I can’t find a working guide on how to scroll on both platforms … all methods I’ve found are not working.

Welcome to my world of pain 😃

a proper doc that explain

There are no such docs and this is main problem 😦

Now I am using for iOS (XCUITest) this code:

await driver.executeScript("mobile: swipe", [{ direction: "left" }]);

and for Android (UiAutomator2) this one:

await driver.touchPerform([
        {
          action: "press",
          options: {
            x: startX,
            y: startY
          }
        },
        { action: "wait", options: { mseconds: 0 } },
        {
          action: "moveTo",
          options: {
            x: endX,
            y: endY
          }
        },
        { action: "release" }
      ]);

And this is rather bad… Because as I could understand - main Appium purpose should be next words: “One code for both platforms”.