Calendar DatePicker: Keeps scrolling up and down

Hello Friends,

I am new B to appium so need guidance of this case,using Java Programming language
Java Client - 6.1,Appium Server - 1.8
Trying to scroll on a calendar to select a particular year
After reading forums tried below but not working

WebElement element = driver.findElement(MobileBy.AndroidUIAutomator(
“new UiScrollable(new UiSelector().resourceId(“android:id/date_picker_year_picker”)).getChildByText(”

  • “new UiSelector().className(“android.widget.TextView”), “1981”)”));

The scrolling happens it scrolls up then down then up and gives error but expected is not selected.

e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:9,“value”:“Could not parse UiSelector argument: problem using reflection to call this method”}
org.openqa.selenium.UnsupportedCommandException: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.
(WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
Build info: version: ‘3.14.0’, revision: ‘aacccce0’, time: ‘2018-08-02T20:13:22.693Z’

the problem is that 1981 is not visible while automation tries to find it. as result you have such result.

try compare your value and scroll yourself e.g.:

// just flingForward
driver.findElement(MobileBy.AndroidUIAutomator(
   "new UiScrollable(new UiSelector().resourceIdMatches(\".*id/date_picker_year_picker\")).flingForward()"));
// or flingBackward
driver.findElement(MobileBy.AndroidUIAutomator(
   "new UiScrollable(new UiSelector().resourceIdMatches(\".*id/date_picker_year_picker\")).flingBackward()"));

now check again current value and decide scroll again or we can now tap needed element.

Thank You Aleksei for inputs.However it gives the below in logs, the fling happens on device though

e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Finding new UiScrollable(new UiSelector().resourceIdMatches(".*id/date_picker_year_picker")).flingBackward() using ANDROID_UIAUTOMATOR with the contextId: multiple: false
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Parsing scrollable: new UiScrollable(new UiSelector().resourceIdMatches(".*id/date_picker_year_picker")).flingBackward()
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: “.*id/date_picker_year_picker”
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] UiScrollable invoking method: public boolean com.android.uiautomator.core.UiScrollable.flingBackward() throws com.android.uiautomator.core.UiObjectNotFoundException args:
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:9,“value”:“Could not parse UiSelector argument: methods must return UiScrollable or UiObject instances”}
e[36minfoe[39m: [debug] Condition unmet after 328ms. Timing out.
e[36minfoe[39m: [debug] Responding to client with error: {“status”:9,“value”:{“message”:“The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.”,“origValue”:“Could not parse UiSelector argument: methods must return UiScrollable or UiObject instances”},“sessionId”:“e21ada17-250f-472b-86ef-5fd76cb5a15c”}
e[36minfoe[39m: e[37m<-- POST /wd/hub/session/e21ada17-250f-472b-86ef-5fd76cb5a15c/element e[39me[31m500e[39me[90m 327.690 ms - 327e[39m e[90me[39m
org.openqa.selenium.UnsupportedCommandException: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource. (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
Build info: version: ‘3.14.0’, revision: ‘aacccce0’, time: ‘2018-08-02T20:13:22.693Z’
System info: host: ‘VAIBHAVS-LAPTOP’, ip: ‘XYZ’, os.name: ‘Windows 7’, os.arch: ‘amd64’, os.version: ‘6.1’, java.version: ‘1.8.0_161’
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities {Port: 4723, appActivity: iratrips.droid.SplashActivity, appPackage: com.iratrips.consumer, browserName: Android, databaseEnabled: false, desired: {Port: 4723, appActivity: iratrips.droid.SplashActivity, appPackage: com.iratrips.consumer, deviceName: Motorolla, platformName: Android, version: 6.0.1}, deviceName: ZY2235F2FB, javascriptEnabled: true, locationContextEnabled: false, networkConnectionEnabled: true, platform: LINUX, platformName: Android, platformVersion: 6.0.1, takesScreenshot: true, version: 6.0.1, warnings: {}, webStorageEnabled: false}
Session ID: e21ada17-250f-472b-86ef-5fd76cb5a15c
*** Element info: {Using=-android uiautomator, value=new UiScrollable(new UiSelector().resourceIdMatches(".*id/date_picker_year_picker")).flingBackward()}
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

I have few more queries but once this resolves I shall raise.

Thanks
Vaibhav

My solution for calendar selection: Open the date picker, tap on year, then I get the index of elements from the list, I check if the expected text is present, if not I swipe from the last item in the list till the first one. and so on till the element is found and tapped.
Define elements per your case

  public void selectDate() {
	register.birthDate.click();
	general.datePickerYear.click();
	u.swipeInListTillExpectedTextAndTap(general.yearList, "1991", 20);
	general.datePickerNextButton.click();
	general.datePickerDay.click();
	general.datePickerOK.click();
}

public void swipeInListTillExpectedTextAndTap(List<MobileElement> list, String expectedText, int time) {
	int i = 1;
	while (!driver.getPageSource().contains(expectedText)) {
		swipeInListFromLastToFirst(list);
		i++;
		if (i == time)
			break;
	}
	tap(driver.findElementByAndroidUIAutomator("new UiSelector().textContains(\"" + expectedText + "\")"));
}

public void swipeInListFromLastToFirst(List<MobileElement> listID) {
	int items = listID.size();
	org.openqa.selenium.Point centerOfFirstElement = listID.get(0).getCenter();
	org.openqa.selenium.Point centerOfLastElement = listID.get(items - 1).getCenter();
	new TouchAction<>(driver).longPress(point(centerOfLastElement.x, centerOfLastElement.y))
			.moveTo(point(centerOfFirstElement.x, centerOfFirstElement.y)).release().perform();
}

Let me know if helps.

@Zuzeac. My mistake. Replace ‘date_picker_year_picker’ with locatorID of listView. Upper element on your screenshot.

Hi @Aleksei,
Didn’t know that we can user flingForward and backward. Good to know, thanks. Where can i find documentation for all UiSelector’s method? would like to research.
Nevertheless, I’m getting same error as @vsharma: Could not parse UiSelector argument: methods must return UiScrollable or UiObject instances.
The driver will scroll a bit then throw error.
I tried with different resource id’s, I don’t get it why.

@Zuzeac docs - https://developer.android.com/reference/android/support/test/uiautomator/UiScrollable

Thank You @Zuzeac, @Aleksei for inputs will try and revert the findings.

e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Got data from client: {“cmd”:“action”,“action”:“element:touchMove”,“params”:{“x”:720,“y”:1322}}
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Got command action: touchMove
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Display bounds: [0,0][720,1184]
e[36minfoe[39m: [debug] Responding to client with error: {“status”:29,“value”:{“message”:“The coordinates provided to an interactions operation are invalid.”,“origValue”:“Coordinate [x=720.0, y=1322.0] is outside of element rect: [0,0][720,1184]”},“sessionId”:“bc720888-172e-4bef-9cbd-93ec502a666d”}
e[36minfoe[39m: e[37m<-- POST /wd/hub/session/bc720888-172e-4bef-9cbd-93ec502a666d/touch/perform e[39me[31m500e[39me[90m 1090.710 ms - 242e[39m e[90me[39m
e[36minfoe[39m: [debug] [BOOTSTRAP] [debug] Returning result: {“status”:29,“value”:“Coordinate [x=720.0, y=1322.0] is outside of element rect: [0,0][720,1184]”}
org.openqa.selenium.interactions.InvalidCoordinatesException: The coordinates provided to an interactions operation are invalid. (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
Build info: version: ‘3.14.0’, revision: ‘aacccce0’, time: ‘2018-08-02T20:13:22.693Z’
System info: host: ‘VAIBHAVS-LAPTOP’, ip: ‘192.168.56.1’, os.name: ‘Windows 7’, os.arch: ‘amd64’, os.version: ‘6.1’, java.version: ‘1.8.0_161’
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities {Port: 4723, appActivity: iratrips.droid.SplashActivity, appPackage: com.iratrips.consumer, browserName: Android, databaseEnabled: false, desired: {Port: 4723, appActivity: iratrips.droid.SplashActivity, appPackage: com.iratrips.consumer, deviceName: Motorolla, platformName: Android, version: 6.0.1}, deviceName: ZY2235F2FB, javascriptEnabled: true, locationContextEnabled: false, networkConnectionEnabled: true, platform: LINUX, platformName: Android, platformVersion: 6.0.1, takesScreenshot: true, version: 6.0.1, warnings: {}, webStorageEnabled: false}
Session ID: bc720888-172e-4bef-9cbd-93ec502a666d

Hi @Zuzeac I am lost… please advise for the below
1)The logs shows out of bound for display, I noticed that when I printed the list size it is 1 is that causing this? The text for the list falls under different class…
List e1=driver.findElements(By.xpath("//*[@class=‘android.widget.ListView’]"));
Below is printed in log
System.out.println(centerOfFirstElement); > (360, 661)
System.out.println(centerOfLastElement); > (360, 661)
When Year is lauched in clicks on centre

Hi @Aleksei you mentioned in comment above replace ‘with locatorID of listView’ I had used the locator id of the list…is anything else you were refering too?

12

@vsharma The list is
android:id/text1
List e1=driver.findElements(By.id("android:id/text1"));

My Bad…
You caught it right @Zuzeac…Thanks “Guru” was trying this for last 1 week as practice.

Thanks @Aleksei for ur support as usual.

@vsharma did you find the solution for this? I am also facing same issue keeps scrolling up and down

ListView inside scrollView, is this the problem?

Thanks in advance

@Zuzeac here what is tap(). Is it working for you?