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.

1 Like

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.

1 Like

@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?

Hi vsharma Iam facing same issuse in android and same datepicker in android …how to scroll specific year plzzzzzzzzzz,

Hi I am facing same datepicker issue in android …how to scroll for previous year …I am working on WebdriverIO project …these function not working

@vsharma Could you please post the detailed example line of code for this solution. Please help me out. Thanks. Awaiting your reply.

Finally after 3 days i got solution. :):):slight_smile: Thank You Aleksei

Hi Aleksei,

Can I get some sample code to scroll till 1981, I treid with scrollforward() & flingBackward() method. when I run with flingBackWard() method, its while scrolling its crossing the expected year & it will throw element not found error.

Thanks
Madhukar

it is mentioned above in thread with ‘UiScrollable’

also other ways you can read -> http://appium.io/docs/en/writing-running-appium/tutorial/swipe-tutorial/

Hi Aleksei,

I’m new to appium & learned this appium recently. I’m practicing the API Demo’s App.While practicing in the API Demo’s App, for the following Scenario i’m facing issue.
My Flow:
APIDemo App->Views->Date Widgets->1.Dialog->Change The Date->Here i’m changing the year to 1999.
Below is the my Code.

        driver.findElementByXPath("//*[@text='Views']").click();
        driver.findElementByXPath("//*[@text='Date Widgets']").click();
        driver.findElementByXPath("//*[@text='1. Dialog']").click();
        driver.findElementByXPath("//*[@text='CHANGE THE DATE']").click();
        driver.findElementById("android:id/date_picker_header_year").click();
        
        
        String text="1999";
        String uiSelector = "new UiSelector().textMatches(\"" + text + "\")";
    //    WebElement year1=driver.findElementByXPath("//android.widget.TextView[@text='1999']");

        String command = "new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(" + uiSelector + ").flingBackward();";
        // String command = "new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(" + uiSelector + ").scrollBackward();";
        driver.findElement(MobileBy.AndroidUIAutomator(command));

When I executed above code, I am not able to scroll till1999.It will scroll up twice & scroll down twice & execution will stop.

It would be helpful if you can guide me, if there is any issue in my code.