Having problems to set date in Android date picker when using Xamarin.UiTest

RemcovanBlarcum.1709RemcovanBlarcum.1709 NLUniversity ✭✭

Below the code I am using to set the datepicker on IOS and Android:

using System;
using Xamarin.UITest;
namespace MZT.UITests
{
///


/// This extension class extends the interface to add extension methods for selecting values from the default Date/Time pickers in iOS and Android.
///

public static class AppPickerExtensions
{
///
/// Gets the standard timeout period.
///

private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30);

#region Android Configuration
//private const string AndroidDatePickerClass = "DatePicker";
private const string AndroidDatePickerClass = "NumberPicker";
private const string AndroidTimePickerClass = "TimePicker";
private const string AndroidDatePickerUpdateDateMethod = "updateDate";
/// <summary>
/// Gets the Android Set Minute method for the TimePicker class. As of API v 23 this is deprecated and should be replaced with "setMinute".
/// </summary>
private const string AndroidTimePickerSetMinuteMethod = "setCurrentMinute";
/// <summary>
/// Gets the Android Set Hour method for the TimePicker class. As of API v 23 this is deprecated and should be replaced with "setHour".
/// </summary>
private const string AndroidTimePickerSetHourMethod = "setCurrentHour";
#endregion

#region iOS Configuration
private const string iOSDatePickerClass = "UIPickerView";
private const string iOSTableViewClass = "UIPickerTableView";

private const int iOSDatumCarroessel = 0;
//private const int iOSDateDayColumn = 3;
//private const int iOSDateYearColumn = 6;

private const int iOSTimeHourColumn = 0;
private const int iOSTimeMinuteColumn = 3;
private const int iOSTimePeriodColumn = 6;
#endregion

/// <summary>
/// Updates the presented date picker with the DateTime provided.
/// Does not request or dismiss the picker; you will need to do so yourself.
/// </summary>
/// <param name="app">App.</param>
/// <param name="platform">Platform being tested.</param>
/// <param name="dateTime">Date to be selected. Time component is ignored.</param>
/// <param name="pickerClass">Android picker class if subclassed.</param>
/// <param name="timeout">Timeout for picker scrolling.</param>
public static void PickerDatumInstellen(this IApp app, Platform platform, DateTime dateTime, string pickerClass = AndroidDatePickerClass, TimeSpan? timeout = null)
{
        if (platform == Platform.Android)
        {
            //app.WaitForElement(x => x.Class(AndroidDatePickerClass), timeout: DefaultTimeout);
            app.WaitForElement(x => x.Class(AndroidDatePickerClass), timeout: DefaultTimeout);
            // Note that the month provided (4 selects it from a 0-based index, whereas the date and year are both the standard values)
            app.Query(x => x.Class(pickerClass).Invoke(AndroidDatePickerUpdateDateMethod, dateTime.ToString("d MMMMMMMMMMMM yyyy")));


        }
        else if (platform == Platform.iOS)
        {
            app.WaitForElement(x => x.Class(iOSDatePickerClass), timeout: DefaultTimeout);
            //ScrollToPickerColumn(app, iOSDateMonthColumn, dateTime.ToString("MMM"), timeout);
            ScrollToPickerColumn(app, iOSDatumCarroessel, dateTime.ToString("d MMMMMMMMMMMM yyyy"), timeout);
            //ScrollToPickerColumn(app, iOSDateDayColumn, dateTime.ToString("d"), timeout);
            //ScrollToPickerColumn(app, iOSDateYearColumn, dateTime.ToString("yyyy"), timeout);
            app.Tap(x => x.Marked("Done"));

        }
}

/// <summary>
/// Updates the presented time picker with the time provided.
/// Does not request or dismiss the picker; you will need to do so yourself.
/// </summary>
/// <param name="app">App.</param>
/// <param name="platform">Platform being tested.</param>
/// <param name="time">Time to be selected. Date component is ignored.</param>
/// <param name="pickerClass">Android picker class if subclassed.</param>
/// <param name="timeout">Timeout for picker scrolling.</param>
public static void UpdateTimePicker(this IApp app, Platform platform, DateTime time, string pickerClass = AndroidTimePickerClass, TimeSpan? timeout = null)
{
    var hours = time.Hour;
    var minute = time.Minute;
    if (platform == Platform.Android)
    {
        app.WaitForElement(x => x.Class(AndroidTimePickerClass), timeout: DefaultTimeout);
        app.Query(c => c.Class(pickerClass).Invoke(AndroidTimePickerSetHourMethod, hours));
        app.Query(c => c.Class(pickerClass).Invoke(AndroidTimePickerSetMinuteMethod, minute));
    }
    else if (platform == Platform.iOS)
    {
        // Assumes 12 Hour Clock
        app.WaitForElement(x => x.Class(iOSDatePickerClass), timeout: DefaultTimeout);
        var period = time.Hour >= 12 ? "PM" : "AM";
        ScrollToPickerColumn(app, iOSTimeHourColumn, time.ToString("h"), timeout);
        ScrollToPickerColumn(app, iOSTimeMinuteColumn, time.ToString("m"), timeout);
        ScrollToPickerColumn(app, iOSTimePeriodColumn, period, timeout);
    }
}

/// <summary>
/// Scrolls to the designated picker column (for iOS only).
/// </summary>
/// <param name="app">App instance.</param>
/// <param name="columnIndex">Column index to scroll to.</param>
/// <param name="marked">Marked content to scroll to.</param>
/// <param name="timeout">Timeout for scrolling.</param>
private static void ScrollToPickerColumn(IApp app, int columnIndex, string marked, TimeSpan? timeout = null)
{
    timeout = timeout ?? DefaultTimeout;
    app.ScrollDownTo(z => z.Marked(marked), x => x.Class(iOSTableViewClass).Index(columnIndex), timeout: timeout, strategy: ScrollStrategy.Auto);
    app.Tap(x => x.Text(marked));
}

}
}

On IOS this code succesfully set the date to the required state. But on Android, Uitest is only quering the string, and showing me that the required date is present. But it is not update the date to the required value. What am I doing wrong?

My application output shows the following information:

Waiting for element matching Class("NumberPicker").

Query for Class("NumberPicker").Invoke("updateDate", "1 april 2019") gave 1 results.

What is the reason for not updating the date to the required value?

Sign In or Register to comment.