Unable to set value in date picker wheel in ios

Hi,

I am testing an ios native app, where I need to set date in date picker wheel.

I have tried send_keys and set_value, but it is not working.

I have explored a lot on this, I have found one solution:

List pickerEls = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(pickers));

// use the sendKeys method to set the picker wheel values directly
pickerEls.get(0).sendKeys(“March”);
pickerEls.get(1).sendKeys(“6”);

but this code is in java and I am using python appium. There is no method like “get()” in python. How to make it work?

Below is the screenshot:
image

Below is the screenshot of appium inspector:

you should use setValue instead:

pickerEls.get(0).setValue(“March”);

and for python you should use e.g.:

e = self.driver.find_elements_by_ios_predicate('wdType == "XCUIElementTypePickerWheel"')
e[1].set_value('March')

I have tried like this:

element1=context.driver.find_elements_by_ios_predicate(‘wdType=“XCUIElementTypePickerWheel”’)

time.sleep(5)

element1[0].set_value(“27”)
element1[1].set_value(“January”)
element1[2].set_value(“1994”)

but this is also not working. Error message is empty.

what problem was here? what size of “element1” was? it should be 3. add logs. log into console size of “element1”.

element1 length is 3.

But it is not scrolling

well then no luck. welcome to iOS problems. the only code that works for me 100% (but really slow - that is why i almost do not use it):
JAVA

                direction = "previous"; // "previous" or "next";
                offset = "0.15";
                HashMap<String, Object> params = new HashMap<>();
                params.put("order", direction);
                params.put("offset", offset);
                params.put("element", (pickerWheeIElement.get(0)).getId());
                driver.executeScript("mobile: selectPickerWheelValue", params);

also -> https://appiumpro.com/editions/59

Thank you so much.Above solution is working, now I am able to scroll the date picker wheel values.

But is it possible to scroll to a particular date?

with “mobile: selectPickerWheelValue” you need in loop just scroll and then read what new values is and decide…

Thank you so much. I will try that.

Hi. Can you tell me the solution for Android too. I’m dealing with the same problem. It would be so helpful if you could help me out. How to scroll down the hours minutes and meridian? They all have same ids. I tried above solution like sendkeys it didn’t work.

We have same wheels with our app.
Solution we use tap up/down -> read and check changed value. Quite fast working.

Yes it’s working. But I can only change hours. Couldn’t change minutes or meridian. Eventhough I change index it’s only accessing hours which is 1st index element

Write your code with locators

String hour = driver.findElements(By.id(“android:id/numberpicker_input”)).get(0).getText();
int hourOne = Integer.parseInt(hour);
String hourGiven = “5”;
int hourTwo = Integer.parseInt(hourGiven);
while (true) {
if (hourOne == hourTwo) {
break;
} else if (hourOne < hourTwo) {
driver.findElementByAndroidUIAutomator(
“new UiScrollable(new UiSelector().resourceIdMatches(“android:id/numberpicker_input”)).flingForward()”);

		} else if (hourOne > hourTwo) {
			driver.findElementByAndroidUIAutomator(
					"new UiScrollable(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\")).flingBackward()");
		}
		hourOne++;

	}

	String minutes = driver.findElements(By.id("android:id/numberpicker_input")).get(1).getText();
	int minuteOne = Integer.parseInt(minutes);
	String minuteGiven = "51";
	int minuteTwo = Integer.parseInt(minuteGiven);
	while (true) {
		if (minuteOne == minuteTwo) {
			break;
		} else if (minuteOne < minuteTwo) {
			driver.findElementByAndroidUIAutomator(
					"new UiScrollable(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\")).flingForward()");

		} else if (minuteOne > minuteTwo) {
			driver.findElementByAndroidUIAutomator(
					"new UiScrollable(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\")).flingBackward()");
		}
		minuteOne++;

	}
	String meridian = driver.findElement(By.xpath("(//android.widget.EditText)[2]")).getText();
	// String meridian =
	// driver.findElements(By.id("android:id/numberpicker_input")).get(2).getText();
	String meridianGiven = "PM";
	while (true) {
		if (meridian == meridianGiven) {
			break;
		} else {
			driver.findElementByAndroidUIAutomator(
					"new UiScrollable(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\")).flingForward()");
		}

I thought I could try to click until I get the number I want. It has same ID’s don’t know how to make it work for minutes and meridian. Thank you sir.

try:


// hours
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().classname(\"android.widget.NumberPicker\").scrollable(true).instance(0)).flingForward()"));
// minutes
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().classname(\"android.widget.NumberPicker\").scrollable(true).instance(1)).flingForward()"));

Hi, I tried this. Still it didn’t work.
Exception thrown like this: Exception in thread “main” org.openqa.selenium.InvalidSelectorException: Could not parse selector expression new UiScrollable(new UiSelector().classname("android.widget.NumberPicker").scrollable(true).instance(0)).flingForward(): UiScrollable has no suitable constructor with arguments [new UiSelector().classname(“android.widget.NumberPicker”).scrollable(true).instance(0)]

ah invalid locator. try without ‘scrollable’

// hours
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().classname(\"android.widget.NumberPicker\").instance(0)).flingForward()"));
// minutes
driver.findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().classname(\"android.widget.NumberPicker\").instance(1)).flingForward()"));

anyway the idea is to find elements by class name where first is hour, second min, third am/pm.

also you may check that works e.g.

driver.findElement(MobileBy.AndroidUIAutomator(new UiSelector().classname(\"android.widget.NumberPicker\").instance(0))) // first hour element
1 Like

Thank you for the reply. But it didn’t work even after removing scrollable. The same exception is throwing as before.

driver.findElement(MobileBy.AndroidUIAutomator(new UiSelector().classname(“android.widget.NumberPicker”).instance(0))
this too didn’t work.

@StephenJohn
I also have the same issue i.e. have same ID and I resolve by changing/adding the child locator to solution provided by @Aleksei
Now the UISelector is

getBaseMobileDriver().findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().className(\"android.widget.NumberPicker\").instance(0).childSelector(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\"))).flingForward()"));

Below is the complete code

//<editor-fold desc="Swipe to Select Month and Year from Number Picker">
    public void swipeToSelectMonthYear(String strMonthYear) {

        YearMonth yearMonth = YearMonth.parse(strMonthYear.trim(), DateTimeFormatter.ofPattern("MM-yyyy"));

        Month varMonth = Month.of(yearMonth.getMonthValue());
        Year varYear = Year.of(yearMonth.getYear());

        if (getBaseMobileDriver() instanceof IOSDriver) {
            selectMonth(yearMonth.getMonthValue());
            mobEleInitiateTransferYearSelection.setValue(String.valueOf(yearMonth.getYear()));
        }else {
            if (!varMonth.equals(getSelectedMonth())) {
                MobileElement mobileElementMonth = mobileElementsMonthYearScroll.get(0).findElement(By.className("android.widget.EditText"));
                while (varMonth.getValue() != Month.of(Integer.parseInt(mobileElementMonth.getText())).getValue()) {
                    getBaseMobileDriver().findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().className(\"android.widget.NumberPicker\").instance(0).childSelector(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\"))).flingForward()"));
                }
            }
            if (!varYear.equals(getSelectedYear())) {
                MobileElement mobileElementYear = mobileElementsMonthYearScroll.get(1).findElement(By.className("android.widget.EditText"));
                while (varYear.getValue() != Year.of(Integer.parseInt(mobileElementYear.getText())).getValue()) {
                    getBaseMobileDriver().findElement(MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().className(\"android.widget.NumberPicker\").instance(1).childSelector(new UiSelector().resourceIdMatches(\"android:id/numberpicker_input\"))).flingForward()"));

                }
            }
        }
        acceptDateOfBirthPopUp();
    }
    //</editor-fold>