{"id":10640,"date":"2024-01-14T09:19:50","date_gmt":"2024-01-14T09:19:50","guid":{"rendered":"https:\/\/testgrid.io\/blog\/?p=10640"},"modified":"2024-08-29T14:54:36","modified_gmt":"2024-08-29T14:54:36","slug":"appium-scroll","status":"publish","type":"post","link":"https:\/\/testgrid.io\/blog\/appium-scroll\/","title":{"rendered":"A comprehensive Guide to using Scroll in Appium"},"content":{"rendered":"\n<p>With the modernization of the business landscape, mobile applications have become an integral part of our lives. From handling our day-to-day tasks, getting groceries, and communicating with others, to handling our finances, mobile applications are used everywhere. This increases the need for the technology teams to ensure that the mobile applications work seamlessly. Testing teams use Appium, which is an open-source test automation framework to automate mobile app testing across different platforms like iOS, Android, and Windows. One very common task in Appium test automation is to scroll the mobile application to interact with a specific web element. For instance, an element might be present in the lower part of the screen, hence scrolling would become an essential part to interact with that element.<\/p>\n\n\n\n<p>In this article, we will see why scrolling is required to access elements and the different ways using which we can perform the scrolling action using Appium.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Scrolling is Necessary in Mobile Apps?<\/h2>\n\n\n\n<p>Unlike the traditional web apps accessible via desktop browsers, mobile applications have different screen sizes and dimensions. All the data and information displayed on these apps is adjusted to be accessed using a vertical scroll. Let us look at some points to see why scrolling is important in mobile app testing:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>To access hidden elements<\/strong> &#8211; The elements that can not be seen in the current view can be accessed only after scrolling. For example, a button to submit a form might be at the end of a registration form. Scrolling down is required to access the button. Similarly, certain form elements might not be in the current view, to access them for filling, scrolling is required.<\/li>\n\n\n\n<li><strong>To validate the loading of dynamic content<\/strong> &#8211; Scrolling might be required to load dynamic tables or lists that use pagination that triggers the loading of more content. Additionally, accessing infinite scrolling feeds, or lazy loaded media also requires scrolling to update or refresh the page&#8217;s content.<\/li>\n\n\n\n<li><strong>Mimic real-time gestures <\/strong>&#8211; Scrolling is integral to using mobile devices and it becomes important to validate the behavior within the application under test.<\/li>\n<\/ul>\n\n\n\n<p><strong><a href=\"https:\/\/testgrid.io\/blog\/appium-inspector-tutorial\/\" data-type=\"URL\" data-id=\"https:\/\/testgrid.io\/blog\/appium-inspector-tutorial\/\">Explore Appium Inspector<\/a>: A GUI tool for inspecting &amp; automating mobile apps.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Scrolling Using Appium<\/h2>\n\n\n\n<p>Appium allows you to perform the scroll action in different ways-<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Touch Action<\/strong> &#8211; Appium provides <a href=\"https:\/\/appium.readthedocs.io\/en\/latest\/en\/writing-running-appium\/touch-actions\/\" rel=\"nofollow noopener\" target=\"_blank\">TouchAction<\/a> API that allows you to perform a series of actions like tap, touch, press, long press, scroll, and pinch. You can perform complex multi-touch actions one after the other using this API.\u00a0<\/li>\n\n\n\n<li><strong>UiScrollable<\/strong> &#8211; This is a UI Automator API provided by Appium to automate scrolling gestures. You can use it to scroll to an element under the parent object without the need to specify the direction of the scroll.<\/li>\n\n\n\n<li><strong>JavaScript Executor<\/strong> &#8211; Appium can execute JS scripts to imitate scroll gestures and interact with the desired element.<\/li>\n<\/ul>\n\n\n\n<p>Let us now discuss these ways to perform scrolling in mobile applications, but before that let us look at the use case that we would be automating.<\/p>\n\n\n\n<p>We will be using the Settings App, which is an inbuilt system app for Android devices. After launching the app we will-<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Scroll down to the Display tab.<\/li>\n\n\n\n<li>Tap on the Display menu.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Master <a href=\"https:\/\/testgrid.io\/blog\/locators-in-appium\/\" data-type=\"URL\" data-id=\"https:\/\/testgrid.io\/blog\/locators-in-appium\/\">appium locators<\/a> for efficient mobile testing.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Appium Touch Action<\/h3>\n\n\n\n<p>Touch action helps to emulate various touch-based interactions like tap, swipe, long press, etc, that are performed by mobile device users. Using touch action, you can evaluate the functionality as well as the responsiveness of mobile applications across different configurations. The code below demonstrates scrolling through a mobile application using the touch action class.<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code>package appium;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport org.openqa.selenium.remote.DesiredCapabilities;\nimport org.testng.annotations.Test;\nimport io.appium.java_client.TouchAction;\nimport io.appium.java_client.android.AndroidDriver;\nimport io.appium.java_client.touch.offset.PointOption;\npublic class Scroll {\n\t@Test\n\tpublic void scrollToElement() throws MalformedURLException, InterruptedException {\n\t\t\n\t\tDesiredCapabilities dc = new DesiredCapabilities();\n\t\t\/\/Setting desired capabilities for the android device with details like device name, version, etc\n\t\tdc.setCapability(\"platformName\", \"android\");\n\t\tdc.setCapability(\"platformVersion\",\"14\");\n\t\tdc.setCapability(\"deviceName\", \"Pixel6_TestGrid\");\n\t\tdc.setCapability(\"automationName\", \"UiAutomator2\");\n\t\t\/\/setting capability for application we want to test\n\t\tdc.setCapability(\"appPackage\", \"com.android.settings\");\n\t\tdc.setCapability(\"appActivity\", \"com.android.settings.Settings\");\n\t\t\/\/Instantiating Android Driver and using Appium server host and port\n\t    AndroidDriver driver = new AndroidDriver(new URL(\"http:\/\/127.0.0.1:4723\/wd\/hub\"), dc);\n\t   \/\/Sleep to wait for the app to load\n\t    Thread.sleep(10000);\n\t    \/\/Creating an object of the touch action class\n\t    TouchAction action = new TouchAction(driver);\n\t    \/\/Using PointOption class to specify the co-ordinates for touch action\n\t    PointOption pointStart = PointOption.point(0,700);\t   \n\t    PointOption pointEnd = PointOption.point(0,100);\n\t    \/\/Performing touch action, press at the start point and moving it till end point\n\t    action.press(pointStart).moveTo(pointEnd).release().perform();\n               \/\/Click on the Display Tab\n\t    driver.findElement(AppiumBy.androidUIAutomator(\"new UiSelector().text(\\\"Display\\\")\")).click();\n\n\n\t    \/\/Closing the driver instance\n\t    driver.quit();\n\t   \n\t   \n\t}\n}<\/code><\/pre>\n\n\n\n<p>Upon executing the above code, you will see that after the application launches, scrolling happens and the Display tab is tapped. You may wish to add desired loggers or print statements for your ease. Successful execution logs will be printed post the run finishes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"681\" height=\"317\" src=\"https:\/\/testgrid.io\/blog\/wp-content\/uploads\/2024\/01\/image1-2.png\" alt=\"Touch Actions in appium\" class=\"wp-image-10641\" loading=\"lazy\" title=\"\"><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">UiScrollable<\/h3>\n\n\n\n<p>UI Automator provides UiScrollable, which can be used to automate scrolling gestures in Appium. It enables us to scroll views like grids, lists, expandable collections, etc. It provides an easy way to search child elements under a scrollable parent through scrolling. It is known to handle nested scrolls efficiently without the need to specify directions and positions. It imports UiSCrollable and UiSelector to first identify the scrollable view and then locate the child element. The below code can be used to scroll through the Settings app and click on Display using UiScrollable.<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code>package appium;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport org.openqa.selenium.remote.DesiredCapabilities;\nimport org.testng.annotations.Test;\nimport io.appium.java_client.AppiumBy;\nimport io.appium.java_client.android.AndroidDriver;\npublic class Scrollable {\n\t@Test\n\tpublic void scrollToElement() throws MalformedURLException, InterruptedException {\n\t\t\n\t\tDesiredCapabilities dc = new DesiredCapabilities();\n\t\t\/\/Setting desired capabilities for the android device with details like device name, version, etc\n\t\tdc.setCapability(\"platformName\", \"android\");\n\t\tdc.setCapability(\"platformVersion\",\"14\");\n\t\tdc.setCapability(\"deviceName\", \"Pixel6_TestGrid\");\n\t\tdc.setCapability(\"automationName\", \"UiAutomator2\");\n\t\t\/\/setting capability for application we want to test\n\t\tdc.setCapability(\"appPackage\", \"com.android.settings\");\n\t\tdc.setCapability(\"appActivity\", \"com.android.settings.Settings\");\n\t\t\/\/Instantiating Android Driver and using Appium server host and port\n\t    AndroidDriver driver = (AndroidDriver)new AndroidDriver(new URL(\"http:\/\/127.0.0.1:4723\/wd\/hub\"), dc);\n\t\t\/\/Sleep to wait for the app to load\n\t    Thread.sleep(10000);\n\t    \/\/ Use the 'driver.findElement' method to find a single element within the current context\n\t    \/\/ The element will be located using an Android UI Automator command\n\t    \/\/ This command scrolls until it finds an element with the text \"Display\" and clicks on it\n\t    driver.findElemen(AppiumBy.androidUIAutomator(\"new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\\\"Display\\\"))\")).click();  \n\t   \n\t    \/\/Closing the driver instance\n\t    driver.quit();\n\t   \n\t   \n\t}\n}\n<\/code><\/pre>\n\n\n\n<p>The above works exactly as we saw in the first execution, with a difference in the function we used in the execution. The results too would be of a similar type.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"751\" height=\"317\" src=\"https:\/\/testgrid.io\/blog\/wp-content\/uploads\/2024\/01\/appium-scroll-image-2.png\" alt=\"scrolling in Appium using JavaScript Executor\" class=\"wp-image-10642\" loading=\"lazy\" title=\"\"><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">JavaScript Executor<\/h3>\n\n\n\n<p>Another way to handle scrolling in Appium is to leverage Javascript. It handles the web view and hybrid apps in a much more efficient way. One can easily pinpoint elements using the selector. Additionally, you can pass custom offsets in place of direction. We will see how the <strong><em>\u201cmobile: scroll\u201d <\/em><\/strong>method can be employed to scroll through the Settings app in our use case.<\/p>\n\n\n\n<pre class=\"wp-block-code has-white-color has-black-background-color has-text-color has-background\"><code>package appium;\nimport java.net.MalformedURLException;\nimport java.net.URL;\nimport java.util.HashMap;\nimport org.openqa.selenium.JavascriptExecutor;\nimport org.openqa.selenium.remote.DesiredCapabilities;\nimport org.testng.annotations.Test;\nimport io.appium.java_client.AppiumBy;\nimport io.appium.java_client.android.AndroidDriver;\npublic class ScrollScript {\n\t@Test\n\tpublic void scrollToElement() throws MalformedURLException, InterruptedException {\n\t\t\n\t\tDesiredCapabilities dc = new DesiredCapabilities();\n\t\t\/\/Setting desired capabilities for the android device with details like device name, version, etc\n\t\tdc.setCapability(\"platformName\", \"android\");\n\t\tdc.setCapability(\"platformVersion\",\"14\");\n\t\tdc.setCapability(\"deviceName\", \"Pixel6_TestGrid\");\n\t\tdc.setCapability(\"automationName\", \"UiAutomator2\");\n\t\t\/\/setting capability for application we want to test\n\t\tdc.setCapability(\"appPackage\", \"com.android.settings\");\n\t\tdc.setCapability(\"appActivity\", \"com.android.settings.Settings\");\n\t\t\/\/Instantiating Android Driver and using Appium server host and port\n\t    AndroidDriver driver = (AndroidDriver)new AndroidDriver(new URL(\"http:\/\/127.0.0.1:4723\/wd\/hub\"), dc);\n\t\t\/\/Sleep to wait for the app to load\n\t    Thread.sleep(10000);\n\t    \/\/Instantiate a JavascriptExecutor to execute JavaScript code within the context of the AndroidDriver\n\t    JavascriptExecutor js = (JavascriptExecutor) driver;\n\t    \/\/Define a string representing the element selector for the element with the text \"Display\"\n\t    String eleSelector =\"new UiSelector().text(\\\"Display\\\")\";\n\t    \/\/Create a HashMap to store parameters for scrolling\n\t    HashMap&lt;String, Object&gt; scrollObj = new HashMap&lt;String, Object&gt;();\n\t    \/\/Specify the strategy for scrolling, which is \"-android uiautomator\" indicating the use of Android UI Automator\n\t    scrollObj.put(\"strategy\", \"-android uiautomator\");\n\t    \/\/Specify the selector for the element to be scrolled to, using the previously defined 'eleSelector'\n\t    scrollObj.put(\"selector\", eleSelector);\n\t    \/\/Specify the direction of scrolling, in this case, \"down\"\n\t    scrollObj.put(\"direction\", \"down\");\n\t    \/\/Execute the JavaScript code to perform the scrolling action, using the 'mobile: scroll' command and passing the scroll parameters\n\t    js.executeScript(\"mobile: scroll\", scrollObj);\n\t    \/\/Use the 'driver.findElement' method to find a single element within the current context\n\t    \/\/The element will be located using an Android UI Automator command\n\t    \/\/This command locates the element with the text \"Display\" and clicks on it\n\t    driver.findElement(AppiumBy.androidUIAutomator(eleSelector)).click();\n\t   \n\t    \/\/Closing the driver instance\n\t    driver.quit();\n\t   \n\t}\n}\n<\/code><\/pre>\n\n\n\n<p>Similar to the above two runs, the one with JS Executor will also perform the same actions and yield the same results.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"671\" height=\"308\" src=\"https:\/\/testgrid.io\/blog\/wp-content\/uploads\/2024\/02\/image3.png\" alt=\"scrolling in Appium using Javascript executor\" class=\"wp-image-10651\" loading=\"lazy\" title=\"\"><\/figure>\n\n\n\n<p>After discussing the different approaches to automate scrolling in Appium, we can say that we can emulate the scroll action through the different parameters, be it the element locator, coordinates, or simply by using the strategy of the scroll in JavaScript executor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices for Scrolling to Elements<\/h2>\n\n\n\n<p>Listed below are a few tips to ensure reliable scrolling when an element you want to interact with is not in view.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The UI should be carefully analyzed to find scrollable parents.<\/li>\n\n\n\n<li>Try to scroll in the least nested scroll around your target element.<\/li>\n\n\n\n<li>Prefer scroll methods over JS scrolling.<\/li>\n\n\n\n<li>Waits after scrolls can help to avoid issues due to content loading.<\/li>\n\n\n\n<li>Fixing the scroll counts in the automation scripts should be avoided, rather the scrolls should be linked to the visibility of elements.<\/li>\n\n\n\n<li>Ensure proper exception handling in case the element is not visible upon scrolling.<\/li>\n\n\n\n<li>When using coordinates, try to scroll fractionally more to avoid flakiness.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Scrolling through an application is an important aspect of user interaction. Hence it becomes extremely critical to have robust scrolling interactions to achieve stable test automation of applications. Based on the build and complexity of the application under test, you can use one of the different techniques discussed to handle scroll. Appium\u2019s scrolling methods when used with the best practices can help access and test complex scroll interactions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the modernization of the business landscape, mobile applications have become an integral part of our lives. From handling our day-to-day tasks, getting groceries, and communicating with others, to handling our finances, mobile applications are used everywhere. This increases the need for the technology teams to ensure that the mobile applications work seamlessly. Testing teams [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":11471,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[2061,579],"tags":[],"class_list":["post-10640","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-appium","category-guide"],"acf":[],"images":{"medium":"https:\/\/testgrid.io\/blog\/wp-content\/uploads\/2024\/01\/A-comprehensive-guide-to-using-Scroll-in-Appium.jpg","large":"https:\/\/testgrid.io\/blog\/wp-content\/uploads\/2024\/01\/A-comprehensive-guide-to-using-Scroll-in-Appium.jpg"},"_links":{"self":[{"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/posts\/10640","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/comments?post=10640"}],"version-history":[{"count":7,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/posts\/10640\/revisions"}],"predecessor-version":[{"id":10736,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/posts\/10640\/revisions\/10736"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/media\/11471"}],"wp:attachment":[{"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/media?parent=10640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/categories?post=10640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/testgrid.io\/blog\/wp-json\/wp\/v2\/tags?post=10640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}