scrollTo (String text) method of Android Driver not working

@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’.