Forum Xamarin Test Cloud (Read Only)

Controlling a Picker (Android NumberPicker, iOS UIPickerView) from UITest

Posting this extension method snippet in case it helps anyone else:

    /// <summary>
    /// Set by index on Android and by name on iOS
    /// </summary>
    public static bool SetPicker (this IApp app, int index, string name )
    {
        if (string.IsNullOrEmpty (name))
            throw new ArgumentNullException ("name");
        if (app.IsAndroid())
        {
            var results = app.Query (c => c.Class ("numberPicker").Invoke ("setValue", index));
            app.Tap (c => c.Marked ("OK"));
            return results.Any ();
        }
        else
        {
            app.Tap (c => c.Marked (name));
            app.Tap (c => c.Button ("Done"));
            return true;
        }
    }

In order to test a Xamarin Forms app in both iOS and Android flavors it's somewhat challenging to come up with a sequence of clicks and drags to operate the picker and when you have it working you'll then find that Android 5 has a different layout from 4 requiring yet more special-case code.

This code assumes you've already tapped the picker to open it. You pass it both the index and the text of the item you want to pick.

If anyone has a better way to control pickers on Android and iOS I'd be interested to hear it.

Posts

  • Thanks for sharing @IanMercer‌.

  • PrabakaranRamasamyPrabakaranRamasamy USMember ✭✭✭

    @IanMercer this approach is not working for hidden items.

  • Here is a method I haven't finished yet as the time part is not implemented. However, the date part works on Xamarin.iOS and Xamarin.Android apps. I am sure it can be tweaked to work for Xamarin.Forms:

        protected void SetPickerDate(DateTime desired,bool includeDate,bool includeTime)
        {
            if (includeDate) {
                if (platform == Platform.Android) {
                    int yearNum = desired.Year;
                    //Android starts from 0
                    int monthNum = desired.Month - 1;
                    int dateNum = desired.Day;
                    app.WaitForElement (x => x.Class ("DatePicker"), "Timed out waiting for date picker", TimeSpan.FromMinutes (1));
                    app.Query (x => x.Class ("DatePicker").Invoke ("updateDate", yearNum, monthNum, dateNum));
                } else {
                    string yearStr = "" + desired.Year;
                    string monthStr = desired.ToString("MMMM");
                    string dateStr = "" + desired.Day;
                    app.ScrollDownTo (x => x.Text (monthStr), x => x.Class ("UIPickerTableView").Index (0), ScrollStrategy.Auto, TimeSpan.FromMinutes (1));
                    app.Tap (x => x.Text (monthStr));
                    app.ScrollDownTo (x => x.Text (dateStr), x => x.Class ("UIPickerTableView").Index (3), ScrollStrategy.Auto, TimeSpan.FromMinutes (1));
                    app.Tap (x => x.Text (dateStr));
                    app.ScrollUpTo (x => x.Text (yearStr), x => x.Class ("UIPickerTableView").Index (6), ScrollStrategy.Auto, TimeSpan.FromMinutes (1));
                    app.Tap (x => x.Text (yearStr));
                }
            }
        }
    
Sign In or Register to comment.