Last updated: May 31, 2020 10:57
With the deprecation of ScrollTo and ScrollToExact functions of Appium, scrolling to a specific element we want to interact with has become a little harder.
One option might be to use Perfecto´s Visual Analysis to scroll to a visual queue. See Scrolling in visual analysis to find a needle for details.
Using native objects, we can use Android´s UIAutomator to leverage the Android UISelector, as well as NsPredicates on iOS (on XCUITest).
We can leverage the UIAutomator methods by executing the findElementByAndroidUIAutomator.
The first thing we need, is to identify a scrollable object on the page, within which we can then scroll to a specific object.
- Let's take the Android settings app as an example- com.android.settings, eg. on the Samsung S8.
- Using the Object spy, we can see that there is a number of android.widget.LinearLayout object that represent the items we want to click.
- In order to scroll, we need to specify the parent within which the object we are looking for is listed. This parent needs to be scrollable.
In this case we can pick the direct parent, the android.support.v7.widget.RecyclerViewer, or a higher level ancestor like this FrameLayout:
A difficulty about using AndroidUIAutomator Findby, is that we are limited to the UISelector's element identification, which is not as flexible as XPath.
For the search we are mainly limited to text, resourcId and index- so finding a uniquely identifiable scrollable container as well as child is important.
In this case here, the FrameLayout has the resourceID android:id/content, which we can easily obtain from the Perfecto ObjectSpy:
- In this example, we want to scroll to and click the "Lock Screen and Security" setting, which is uniquely identified by text:
- The code we can now use to scroll to this object, to then click it is:
By Specifying the Scrollable parent- in our example identified by com.android.settings:id/content
If there is only a single scrollable container, UISelector can just be used with scrollable(true) instead of identifying the parent object:
Refer to Scrolling on iOS for further information.
One way we can swipe on iOS, eg. utilizing the iOSNsPredicates. The same is possible using Class Chain or AccessibilityID.
Here we just need to define an object we want to scroll to using NsPredicates.
Eg. on iOS settings (which can be started using bundleId com.apple.Preferences), we want to scroll down to the Notes section, and click it.
Notes can be identified by its value, which is "Notes" - so we know that the object could be found (among other options) through
driver.findElementByIosNsPredicate("value CONTAINS 'Notes'") or driver.findElementByIosNsPredicate("value == 'Notes'")
In order to scroll to the object we can use ExecuteScript:
We could then follow a click on it using also NsPredicate, or any other Appium FindElementBy:
driver.findElementByIosNsPredicate("value CONTAINS 'Notes'").click();