scrollTo (String text) method of Android Driver not working

Yes.
i m trying to open contacts App on my android device and want to scroll upto one of the contact name.

earlier when i used the Android Driver Api Method- scrollTo(String text), it was getting scrolled continuously first downwards then upwards and then through exception after 2 min.
org.openqa.selenium.NoSuchElementException.

so tried your approach but still i m not able to get this done

Following is end to end code you can try, Just change the name that you are looking:

public class scrollToForElement 
{
        public AndroidDriver driver1;

         @BeforeClass
         public void setUp()
         {
            //Set up desired capabilities and pass the Android app-activity and app-package to Appium

             DesiredCapabilities capabilities = new DesiredCapabilities();
        
                capabilities.setCapability("deviceName", "Testing");
                capabilities.setCapability("appPackage", "com.android.contacts");             
                capabilities.setCapability("appActivity", "com.android.contacts.activities.PeopleActivity");

              //Create RemoteWebDriver instance and connect to the Appium server.
                try
                {
                    driver1 = new AndroidDriver (new URL("http://127.0.0.1:4723/wd/hub"), capabilities);    
                    driver1.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
         }
         
         @Test
         public void testCal()  throws Exception 
         {
                 String str="Franklin";
//                driver1.scrollTo(str);
                
                 driver1.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(\""+str+"\").instance(0))");
                
                driver1.quit();
        }
}
5 Likes

ohh WoW !!!
This works as i wanted it to.
Thanks a lot :smile:
And thanks to everyone for their inputs, this is really learning for me :slight_smile:

heyall,
I’m still facing this issue, instead scroll its clicking on dropdown element.

i tried the followings

  1.     dr.findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(\""+symbol+"\").instance(0))");
    
  2. driver.scrolltoexact(“Text”);

  3. HashMap<String, String> scrollObject = new HashMap<String, String>();
    RemoteWebElement element = (RemoteWebElement)dr.findElementByAndroidUIAutomator(“new UiSelector().className(“android.widget.ListView”)”);
    JavascriptExecutor js = (JavascriptExecutor) dr;
    String webElementId = ((RemoteWebElement) element).getId();
    scrollObject.put(“text”, symbol);
    scrollObject.put(“element”, webElementId);
    js.executeScript(“mobile: scrollTo”, scrollObject);

none of the above are working fine for me…

Please provide the appium server log so we can better understand the failure

please find the script and logs
java script:
dr.scrollToExact(symbol);
dr.switchTo().activeElement().findElement(By.id(“com.msf.opx:id/txtPosSymbolDesc”));
List list1 = dr.findElements(By.id(“com.msf.opx:id/txtPosSymbolDesc”));
for (WebElement cr : list1) {
if (cr.getText().contains(symbol)) {
cr.click();
}
}

please find the script and logs
java script:
dr.scrollToExact(symbol);
dr.switchTo().activeElement().findElement(By.id(“com.msf.opx:id/txtPosSymbolDesc”));
List list1 = dr.findElements(By.id(“com.msf.opx:id/txtPosSymbolDesc”));
for (WebElement cr : list1) {
if (cr.getText().contains(symbol)) {
cr.click();
}
}

appium logs:

info: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:7,“value”:“No element found”}
info: [debug] Pushing command to appium work queue: [“find”,{“strategy”:“id”,“selector”:“com.msf.opx:id/btnpositions”,“context”:“”,“multiple”:false}]
info: [debug] [BOOTSTRAP] [debug] Got data from client: {“cmd”:“action”,“action”:“find”,“params”:{“strategy”:“id”,“selector”:“com.msf.opx:id/btnpositions”,“context”:“”,“multiple”:false}}
info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
info: [debug] [BOOTSTRAP] [debug] Got command action: find
info: [debug] [BOOTSTRAP] [debug] Finding com.msf.opx:id/btnpositions using ID with the contextId: multiple: false
info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[INSTANCE=0, RESOURCE_ID=com.msf.opx:id/btnpositions]
info: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:0,“value”:{“ELEMENT”:“4”}}
info: [debug] Responding to client with success: {“status”:0,“value”:{“ELEMENT”:“4”},“sessionId”:“9073d745-390b-49ce-a414-fc4d57cf78d1”}
info: ← POST /wd/hub/session/9073d745-390b-49ce-a414-fc4d57cf78d1/element 200 3555.858 ms - 87 {“status”:0,“value”:{“ELEMENT”:“4”},“sessionId”:“9073d745-390b-49ce-a414-fc4d57cf78d1”}
info: → POST /wd/hub/session/9073d745-390b-49ce-a414-fc4d57cf78d1/element/4/click {“id”:“4”}
info: [debug] Pushing command to appium work queue: [“element:click”,{“elementId”:“4”}]
info: [debug] [BOOTSTRAP] [debug] Got data from client: {“cmd”:“action”,“action”:“element:click”,“params”:{“elementId”:“4”}}
info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
info: [debug] [BOOTSTRAP] [debug] Got command action: click
info: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:0,“value”:true}
info: [debug] Responding to client with success: {“status”:0,“value”:true,“sessionId”:“9073d745-390b-49ce-a414-fc4d57cf78d1”}
info: ← POST /wd/hub/session/9073d745-390b-49ce-a414-fc4d57cf78d1/element/4/click 200 2132.285 ms - 76 {“status”:0,“value”:true,“sessionId”:“9073d745-390b-49ce-a414-fc4d57cf78d1”}
info: → POST /wd/hub/session/9073d745-390b-49ce-a414-fc4d57cf78d1/element {“using”:“-android uiautomator”,“value”:"new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().description("GE JAN16 > info: [debug] [BOOTSTRAP] [debug] Parsing scrollable: new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().text(“GE JAN16 20 CALL”).instance(0))
info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: boolean arg: true
info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: int arg: 0
info: [debug] [BOOTSTRAP] [debug] UiScrollable invoking method: public boolean com.android.uiautomator.core.UiScrollable.scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException args: new UiSelector().text(“GE JAN16 20 CALL”).instance(0),
info: [debug] [BOOTSTRAP] [debug] UiScrollable coerce type: class com.android.uiautomator.core.UiObject arg: new UiSelector().text(“GE JAN16 20 CALL”).instance(0)
info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: “GE JAN16 20 CALL”
info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: int arg: 0
info: [debug] [BOOTSTRAP] [debug] Method name: scrollIntoView
info: [debug] [BOOTSTRAP] [debug] Setting uiObject for scrollIntoView
info: [debug] [BOOTSTRAP] [debug] Invoking method: public boolean com.android.uiautomator.core.UiScrollable.scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException with: com.android.uiautomator.core.UiObject@1c1d2bca
info: [debug] [BOOTSTRAP] [debug] Invoke complete.
info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=GE JAN16 20 CALL, INSTANCE=0]
info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[TEXT=GE JAN16 20 CALL, INSTANCE=0]
info: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:7,“value”:“No element found”}
info: [debug] Condition unmet after 63589ms. Timing out.
info: [debug] Responding to client with error: {“status”:7,“value”:{“message”:“An element could not be located on the page using the given search parameters.”,“origValue”:“No element found”},“sessionId”:“9073d745-390b-49ce-a414-fc4d57cf78d1”}
info: ← POST /wd/hub/session/9073d745-390b-49ce-a414-fc4d57cf78d1/element 500 63523.488 ms - 195
info: → DELETE /wd/hub/session/9073d745-390b-49ce-a414-fc4d57cf78d1 {}

This Worked For Me :smile:
Thanks

Thank you! Worked perfectly for me!
Could you explain step by step this line

I hope you know this, Android automation is possible by UIAutomatior. The following is the statement in Android Automator

new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains("“+str+”").instance(0))

The same is passed in driver.findByUIAutomator.

@UD

What is the iOS alternative for scrollTo() method ?

@UD

Following method works as replacement for scrollTo(text) on Android.

((AndroidDriver) driver).findElementByAndroidUIAutomator(
“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(”"
+ content + “”).instance(0))");

But sometime it doesn’t work and I get error as below:-

Capabilities [{app=/test.apk, appPackage=com.testapp.droid.qa, networkConnectionEnabled=true, warnings={}, appWaitPackage=com.testapp.droid.qa, appWaitActivity=com.testapp.droid.qa.v2.SplashActivity, databaseEnabled=false, deviceName=4d0080044ca841eb, platform=LINUX, deviceUDID=4d0080044ca841eb, appActivity=com.testapp.droid.qa.v2.SplashActivity, desired={app=/test.apk, platformName=Android, deviceName=Android Emulator}, platformVersion=5.0.1, webStorageEnabled=false, locationContextEnabled=false, takesScreenshot=true, javascriptEnabled=true, platformName=Android}]
Session ID: 3d197d89-25b6-4d4f-9e2e-130ab3293a67
*** Element info: {Using=-android uiautomator, value=new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“mobqa”).instance(0))}
at sun.reflect.GeneratedConstructorAccessor20.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:51)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:352)
at io.appium.java_client.DefaultGenericMobileDriver.findElement(DefaultGenericMobileDriver.java:67)
at io.appium.java_client.AppiumDriver.findElement(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElement(AndroidDriver.java:1)
at io.appium.java_client.android.AndroidDriver.findElementByAndroidUIAutomator(AndroidDriver.java:468)

FYI I have tried putting wait for 3 seconds (sleep(3000)) before this scroll command execution. Then also I got the above error. Can you tell me how to solve this ?

1 Like

Here is the solution for scrollTo in Android.

What was the reasoning behind removing such a vital function from appium? Sure, everything can be done with ui automator code, but what is the point of using appium if not to provide an easier api than uiautomator? Did some fool at appium think that scroll-to wasn’t really needed and that nobody on the planet had ever had to automate a screen with more elements than would fit on the display?

1 Like

+1 , it was really a helpful function.

((AndroidDriver) wd).findElementByAndroidUIAutomator(“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(”"+str+"").instance(0))");

I am using the above code to scroll.it starts scrolling after few scrolls if it doesnt find the str it started reverse scrolling.

Any suggestion ?

@Vikrantbodkhe, @UD, when I used above approach, nothing happened even not receiving any exception ( i.e my app is not scrolled to the particular text).

((AndroidDriver) driver).findElementByAndroidUIAutomator(“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(”"+selector+"").instance(0))");

please refer below appium logs:

[MJSONWP] Responding to client with driver.setValue() result: true
[HTTP] <-- POST /wd/hub/session/d5942964-8c74-4e0f-9611-39522a11fbbf/element/2/value 200 5502 ms - 76
[HTTP] --> POST /wd/hub/session/d5942964-8c74-4e0f-9611-39522a11fbbf/element {“using”:"-android uiautomator",“value”:“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“Register”).instance(0))”}
[MJSONWP] Calling AppiumDriver.findElement() with args: ["-android uiautomator",“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“Register”)…
[debug] [BaseDriver] Waiting up to 0 ms for condition
[debug] [AndroidBootstrap] Sending command to android: {“cmd”:“action”,“action”:“find”,“params”:{“strategy”:”-android uiautomator",“selector”:“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“Register”).instance(0))”,“context”:"",“multiple”:false}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {“cmd”:“action”,“action”:“find”,“params”:{“strategy”:"-android uiautomator",“selector”:“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“Register”).instance(0))”,“context”:"",“multiple”:false}}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: find
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Finding new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“Register”).instance(0)) using ANDROID_UIAUTOMATOR with the contextId: multiple: false
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Parsing scrollable: new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(“Register”).instance(0))
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] UiSelector coerce type: boolean arg: true
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] UiSelector coerce type: int arg: 0
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] UiScrollable invoking method: public boolean com.android.uiautomator.core.UiScrollable.scrollIntoView(com.android.uiautomator.core.UiObject) throws com.android.uiautomator.core.UiObjectNotFoundException args: new UiSelector().textContains(“Register”).instance(0),
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] UiScrollable coerce type: class com.android.uiautomator.core.UiObject arg: new UiSelector().textContains(“Register”).instance(0)
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] UiSelector coerce type: class java.lang.String arg: “Register”
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] UiSelector coerce type: int arg: 0
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Method name: scrollIntoView
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Setting uiObject for scrollIntoView
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Using: UiSelector[CONTAINS_TEXT=Register, INSTANCE=0]
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {“status”:0,“value”:{“ELEMENT”:“3”}}
[debug] [AndroidBootstrap] Received command result from bootstrap
[MJSONWP] Responding to client with driver.findElement() result: {“ELEMENT”:“3”}
[HTTP] <-- POST /wd/hub/session/d5942964-8c74-4e0f-9611-39522a11fbbf/element 200 85 ms - 87
[BaseDriver] Shutting down because we waited 60 seconds for a command
[debug] [AndroidDriver] Shutting down Android driver
[Appium] Closing session, cause was ‘New Command Timeout of 60 seconds expired. Try customizing the timeout using the ‘newCommandTimeout’ desired capability’
[Appium] Removing session d5942964-8c74-4e0f-9611-39522a11fbbf from our master session list
[debug] [ADB] Getting connected devices…
[debug] [ADB] 1 device(s) connected
[debug] [ADB] Running /Users/f2849/android-sdks/platform-tools/adb with args: ["-P",5037,"-s",“192.168.56.101:5555”,“shell”,“am”,“force-stop”,“com.net.shine”]
[debug] [ADB] Pressing the HOME button
[debug] [ADB] Getting connected devices…
[debug] [ADB] 1 device(s) connected
[debug] [ADB] Running /Users/f2849/android-sdks/platform-tools/adb with args: ["-P",5037,"-s",“192.168.56.101:5555”,“shell”,“input”,“keyevent”,3]
[debug] [Logcat] Stopping logcat capture
[debug] [AndroidBootstrap] Sending command to android: {“cmd”:“shutdown”}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {“cmd”:“shutdown”}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type SHUTDOWN
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Returning result: {“status”:0,“value”:“OK, shutting down”}
[AndroidBootstrap] [BOOTSTRAP LOG] [debug] Closed client connection
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: numtests=1
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: stream=.
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: test=testRunServer
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: current=1
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS_CODE: 0
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS: stream=
[debug] [AndroidBootstrap] [UIAUTO STDOUT] Test results for WatcherResultPrinter=.
[debug] [AndroidBootstrap] [UIAUTO STDOUT] Time: 78.012
[debug] [AndroidBootstrap] [UIAUTO STDOUT] OK (1 test)
[debug] [AndroidBootstrap] [UIAUTO STDOUT] INSTRUMENTATION_STATUS_CODE: -1
[debug] [AndroidBootstrap] Received command result from bootstrap
[debug] [UiAutomator] Shutting down UiAutomator
[debug] [UiAutomator] Moving to state ‘stopping’
[debug] [UiAutomator] UiAutomator shut down normally
[deb

String str= “Value”
((AndroidDriver) driver).findElementByAndroidUIAutomator(“new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(”"+str+"").instance(0))");

Only change the Value string variable

OR ELSE you can use the below code

while(driver.findElements(By.name("Value"))).size()==0)
	
	{
		Dimension dimensions = wd.manage().window().getSize();
		Double screenHeightStart = dimensions.getHeight() * 0.5;
		System.out.println(screenHeightStart);
		int scrollStart = screenHeightStart.intValue();
		System.out.println(scrollStart);
		Double screenHeightEnd = dimensions.getHeight() * 0.2;
		System.out.println(screenHeightEnd);
		int scrollEnd = screenHeightEnd.intValue();
		System.out.println(scrollEnd);
		wd.swipe(0,scrollStart,0,scrollEnd,5000);
	//	wd.swipe(0,1100,0,100,20000);
	}

	if(wd.findElements(By.name("Value"))).size()>0)
	{

wd.findElements(By.name(“Value”)).click();

Will this above method work fine for appium latest version?

Try the below method one which works from version 3.0.0 to the latest 4.1.2
Ex: java-client 4.1.2

Method:
String selector = “searchString”;
driver.findElement(MobileBy.AndroidUIAutomator(“new UiScrollable(new UiSelector()).scrollIntoView(new UiSelector().text(”"+selector+""));"));

The method will scroll in the page until it finds the string with ‘searchString’.