Scrolling on mobile handsets or handheld devices can be of up or down,
Scenario: some times elements can’t be identified as those are not visible on screen, but once we scroll down to make it visible, and then can be easily identified.
Scroll is possible in both native app and also on mobile browsers, we will see one by one.
Would recommend to watch these below 2 demo videos to know more –
Scrolling on native apps:
NOTE: get the size of the device screen or size of the element on which scrolling needs to be done, so that same code can be run across difference devices.
On java-client 6.0 onwards, we have use PointOptions.point() to assign coordinates and WaitOptions.waitOptions() to assign duration
new TouchAction((PerformsTouchActions) MobileDriver.getDriver()) .press(PointOption.point(0, scrollStart)) .waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1))) .moveTo(PointOption.point(0, scrollEnd)) .release().perform();
On java-client version 5.0 on wards, swipe() method deprecated, workaround is to use io.appium.java_client.TouchAction
new TouchAction(driver).press(0, scrollStart) .waitAction(2000) .moveTo(0, scrollEnd).release().perform();
On Java-client 4.0 version onwards, scrollTo() or scrollToExact() methods are deprecated, workaround is to use swipe() method (implemented from TouchShortcuts interface)
driver.swipe(0,scrollStart,0,scrollEnd,2000);
Implementation
We will use Android Phone app to understand scrolling using appium.
Test scenario – On the Phone app, we will be scrolling on the Contacts page to reach to any contact. e.g Zebra in this case which is extreme bottom on the Contacts screen

DriverFactory.java
Invoke the mobile application and instantiate the driver
public class AppFactory { public static AppiumDriver<MobileElement> driver; public static DesiredCapabilities cap; public static void Android_LaunchApp() throws MalformedURLException { cap = new DesiredCapabilities(); cap.setCapability("platformName", "Android"); cap.setCapability("deviceName", "emulator-5554"); cap.setCapability("automationName", "UiAutomator2"); //cap.setCapability("appPackage", "com.android.calculator2"); //cap.setCapability("appActivity", ".Calculator"); cap.setCapability("appPackage", "com.google.android.dialer"); cap.setCapability("appActivity", ".DialtactsActivity"); driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), cap); AppDriver.setDriver(driver); } public static void iOS_LaunchApp() throws MalformedURLException { cap = new DesiredCapabilities(); cap.setCapability("platformName", "iOS"); cap.setCapability("deviceName", "iPhone 11 Pro Max"); cap.setCapability("automationName", "XCUITest"); cap.setCapability("platformVersion", "13.3"); cap.setCapability("usePrebuiltWDA", true); //cap.setCapability("bundleId", "com.SamadiPour.SimpleCalculator"); cap.setCapability("bundleId", "com.example.apple-samplecode.UICatalog"); driver = new IOSDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), cap); AppDriver.setDriver(driver); } public static void closeApp(){ driver.quit(); } }
MobileDriver.java
Get and set the driver instance
public class AppDriver { private static ThreadLocal<WebDriver> driver = new ThreadLocal<>(); public static WebDriver getDriver(){ return driver.get(); } static void setDriver(WebDriver Driver){ driver.set(Driver); } }
Util.Java
scrollDown() method will scroll down on screen,
public class Util { public static void scrollDown(){ Dimension dimension = AppDriver.getDriver().manage().window().getSize(); int scrollStart = (int) (dimension.getHeight() * 0.5); int scrollEnd = (int) (dimension.getHeight() * 0.2); new TouchAction((PerformsTouchActions) AppDriver.getDriver()) .press(PointOption.point(0, scrollStart)) .waitAction(WaitOptions.waitOptions(Duration.ofSeconds(1))) .moveTo(PointOption.point(0, scrollEnd)) .release().perform(); } public static void scrollNClick(By listItems, String Text){ boolean flag = false; while(true){ for(WebElement el: AppDriver.getDriver().findElements(listItems)){ if(el.getAttribute("text").equals(Text)){ el.click(); flag=true; break; } } if(flag) break; else scrollDown(); } } public static void scrollNClick(WebElement el){ int retry = 0; while(retry <= 5){ try{ el.click(); break; }catch (org.openqa.selenium.NoSuchElementException e){ scrollDown(); retry++; } } } public static void scrollIntoView(String Text){ ((AndroidDriver<MobileElement>) AppDriver.getDriver()).findElementByAndroidUIAutomator( "new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text(\"" + Text + "\").instance(0))").click(); } }
TestListener.java
public class TestListener implements ITestListener { @Override public void onTestStart(ITestResult result) { String Platform = result.getMethod().getXmlTest().getLocalParameters().get("platform"); if(Platform.contains("android")) { try { AppFactory.Android_LaunchApp(); } catch (MalformedURLException e) { e.printStackTrace(); } }else if(Platform.contains("ios")){ try { AppFactory.iOS_LaunchApp(); } catch (MalformedURLException e) { e.printStackTrace(); } } } @Override public void onTestSuccess(ITestResult result) { tearDown(); } @Override public void onTestFailure(ITestResult result) { tearDown(); } @Override public void onTestSkipped(ITestResult result) { tearDown(); } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult result) { } @Override public void onTestFailedWithTimeout(ITestResult result) { } @Override public void onStart(ITestContext context) { } @Override public void onFinish(ITestContext context) { } public void tearDown(){ AppDriver.getDriver().quit(); } }
BasePage.java
public class BasePage { public BasePage(){ PageFactory.initElements(new AppiumFieldDecorator(AppDriver.getDriver()), this); } @FindBy(id = "com.google.android.dialer:id/contacts_tab") public WebElement ContactTab; @FindBy(xpath = "//android.widget.TextView[@text='Create new contact']") public WebElement AddContact; @FindBy(xpath = "//android.widget.EditText[@text='First name']") public WebElement FirstName; @FindBy(id = "com.android.contacts:id/editor_menu_save_button") public WebElement SaveBtn; By by_createNewContact = By.xpath("//android.widget.TextView[@text='Create new contact']"); By by_FirstName = By.xpath("//android.widget.EditText[@text='First name']"); public void save_Contact() throws InterruptedException { Thread.sleep(500); ContactTab.click(); new WebDriverWait(AppDriver.getDriver(), 20).until(ExpectedConditions.presenceOfElementLocated(by_createNewContact)); AddContact.click(); new WebDriverWait(AppDriver.getDriver(), 20).until(ExpectedConditions.presenceOfElementLocated(by_FirstName)); FirstName.sendKeys("Welcome111"); SaveBtn.click(); } }
ContactsPage.java
public class ContactsPage { public ContactsPage(){ PageFactory.initElements(new AppiumFieldDecorator(AppDriver.getDriver()), this); } @FindBy(xpath = "//android.widget.TextView[@text='Zebra']") public WebElement Submit; public By by_names = By.id("com.google.android.dialer:id/contact_name"); }
PerformScroll.java –
scroll down on Contacts page to reach to Zebra
public class PerformScroll { @Test public void Test_SaveContact() throws InterruptedException { BasePage basePage = new BasePage(); ContactsPage cp = new ContactsPage(); basePage.ContactTab.click(); Thread.sleep(500); //Util.scrollNClick(cp.by_names, "Zebra"); //Util.scrollNClick(cp.Submit); Util.scrollIntoView("Zebra"); Thread.sleep(2000); } }
Run the below testng.xml to perform scrolling
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Suite1" verbose="1" > <listeners> <listener class-name="base.TestListener"/> </listeners> <test name="Android"> <parameter name="platform" value="android"/> <classes> <!--class name="android.tc.Verify_SaveContact" /--> <class name="android.tc.PerformScroll" /> </classes> </test> <test name="iOS"> <parameter name="platform" value="ios"/> <classes> <!--class name="ios.tc.Verify_ActionSheet" /--> </classes> </test> </suite>
On mobile browser:
Scroll methods mentioned in the Util.java will work for mobile browsers as well, but to launch the mobile browser we need to set different capabilities, so let’s see the implementation
Even you can even use as usual selenium scroll using JavaScriptExecutor for mobile browsers.
For Chrome browser, we need to download chromeDriver from here
public class Scrolling { static DesiredCapabilities cap; static AndroidDriver driver; public static void main(String args[]) throws MalformedURLException, InterruptedException{ cap = new DesiredCapabilities(); cap.setCapability("platformName", "Android"); cap.setCapability("deviceName", "emulator-5554"); cap.setCapability("automationName", "UiAutomator2"); cap.setCapability("browserName", "Chrome"); cap.setCapability("chromedriverExecutable", "/Users/MyUser/sel/chromedriver"); driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), cap); driver.get("http://qavalidation.com"); Thread.sleep(3000); JavascriptExecutor js = (JavascriptExecutor) driver; while(driver.findelements(By.id("back-to-top")).size()==0) { //Scroll page down to 250px js.executeScript("window.scrollBy(0,250)", ""); } }
Complete code repo – https://github.com/sunilpatro1985/AppiumTest_Java_And_iOS
For more ways to scroll on Desktop browsers, follow Scrolling browser using selenium
Im getting error for getDriver() –> The method getDriver() is undefined for the type MobileDriver
please help
Please correct your code,
Close app method is missing