Stefanos Badojohn
Stefanos Badojohn

Reputation: 41

Precise scrolling in Android native app using Appium/WebdriverIO

The problem

I'm trying to perform precise scrolling in an Android native app using Appium & WebdriverIO.

The end goal is to perform snapshot testing (comparing screenshots) in Android views that contain scrollable content (e.g: ScrollViews/WebViews), so there is a need for pixel-perfect results.

What I've tried so far

There seem to be a couple of ways to scroll, such as touchAction or performActions.

Using touchAction:

This looks like the most straightforward way (in fact, this is what Appium Inspector produces when recording a swipe gesture)

await driver.touchAction([
   { action: 'press', x: 200, y: 400 },
   { action: 'moveTo', x: 200, y: 200 },
   'release'
])

This scrolls the content just fine, however there are the following issues:

  1. There are times when the gesture appears to have no effect on ScrollViews (although I have double checked that the swipe is being performed, by enabled the Pointer location in Developer settings).
  2. It only scrolls consistently (in regards to the scrolling distance) in WebViews.

Using Appium's performActions:

await driver.performActions([
   {
      type: 'pointer',
      id: 'finger1',
      parameters: { pointerType: 'touch' },
      actions: [
         { type: 'pointerMove', duration: 0, x: 200, y: 400 },
         { type: 'pointerDown', button: 0 },
         { type: 'pause', duration: 100 },
         { type: 'pointerMove', duration: 1000, origin: 'pointer', x: 200, y: 200 },
         { type: 'pointerUp', button: 0 },
      ],
   },
])

This appears to work in all kinds of content (ScrollViews or WebViews), but the scrolling distance is not consistent at all.

In all cases, the scrolling distance seems to vary greatly depending on the duration of the gesture, yet even a really large duration like 10000ms doesn't result in 100% consistent scrolling distance.

While messing around with performActions, I've also tried including an additional pause in between the pointerMove and pointerUp actions, in an attempt to remove the gesture's velocity as a failing factor:

...
   { type: 'pointerMove', duration: 1000, origin: 'pointer', x: 200, y: 200 },         
   { type: 'pause', duration: 1000 },
   { type: 'pointerUp', button: 0 },
...

but as soon as the pointerUp action takes place, the content scrolls a tiny bit more, resulting again in unpredictable scrolling distance.

The question

Is there a way of scrolling using Appium/WebdriverIO, that will always produce 100% consistent results in regards to the scrolling distance?

Upvotes: 3

Views: 987

Answers (2)

Ahmad Azeri
Ahmad Azeri

Reputation: 11

I'm not sure if this can answer your question, but have you tried scrollGesture?

import { driver } from '@wdio/globals';

export class CommonAction{

    async scrollUp(){
        const screenSize = await driver.getWindowSize();
        await driver.executeScript("mobile: scrollGesture", [
            { direction: "up", left: screenSize.width * 0.5, top: screenSize.height * 0.5, width: screenSize.width * 0.9, height: screenSize.height * 0.9, percent: 0.25}
        ]);
    }

    async scrollDown(){
        const screenSize = await driver.getWindowSize();
        await driver.executeScript("mobile: scrollGesture", [
            { direction: "down", left: screenSize.width * 0.025, top: screenSize.height * 0.025, width: screenSize.width * 0.9, height: screenSize.height * 0.9, percent: 0.25}
        ]);
    }
}
export default new CommonAction();

Full sample on my GitHub repository: https://github.com/ahmadazerichandrabhuana/wdioandroid/blob/main/test/pageobjects/common.action.js

Hope it can help, and I'm sorry for the very late answer.

Upvotes: 1

Ashwa
Ashwa

Reputation: 41

I am using the below line to scroll down and find the text Driver.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector()).scrollIntoView(textContains("********"));");

Upvotes: -1

Related Questions