Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set time to MaterialDateTimePicker with Espresso

Im trying to create simple UI test using Espresso to set a date to newly created item.

Project is using https://github.com/wdullaer/MaterialDateTimePicker, but it shows dialog fragment with complex UI and nothing to hold on to.

I would like to create custom ViewAction to set the date or time similar to PickerActions from Espresso.

Any suggestions how to do it?

like image 744
Lubos Horacek Avatar asked Jan 07 '16 15:01

Lubos Horacek


3 Answers

In the end I've created ViewAction that is able to set the time too, but its messy, as you have to know classname of view in the dialog, to have something to match with Matcher.

  /**
     * Returns a {@link ViewAction} that sets a date on a {@link DatePicker}.
     */
    public static ViewAction setDate(final int year, final int monthOfYear, final int dayOfMonth) {

        return new ViewAction() {

            @Override
            public void perform(UiController uiController, View view) {
                final DayPickerView dayPickerView = (DayPickerView) view;

                try {
                    Field f = null; //NoSuchFieldException
                    f = DayPickerView.class.getDeclaredField("mController");
                    f.setAccessible(true);
                    DatePickerController controller = (DatePickerController) f.get(dayPickerView); //IllegalAccessException
                    controller.onDayOfMonthSelected(year, monthOfYear, dayOfMonth);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public String getDescription() {
                return "set date";
            }

            @SuppressWarnings("unchecked")
            @Override
            public Matcher<View> getConstraints() {
                return allOf(isAssignableFrom(DayPickerView.class), isDisplayed());
            }
        };

    }

    /**
     * Returns a {@link ViewAction} that sets a time on a {@link TimePicker}.
     */
    public static ViewAction setTime(final int hours, final int minutes) {

        return new ViewAction() {

            @Override
            public void perform(UiController uiController, View view) {
                final RadialPickerLayout timePicker = (RadialPickerLayout) view;

                timePicker.setTime(new Timepoint(hours, minutes, 0));
            }

            @Override
            public String getDescription() {
                return "set time";
            }

            @SuppressWarnings("unchecked")
            @Override
            public Matcher<View> getConstraints() {
                return allOf(isAssignableFrom(RadialPickerLayout.class), isDisplayed());
            }
        };

    }

And usage:

onView(isAssignableFrom(DayPickerView.class)).perform(MaterialPickerActions.setDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)));

onView(isAssignableFrom(RadialPickerLayout.class)).perform(MaterialPickerActions.setTime(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE)));
like image 151
Lubos Horacek Avatar answered Nov 07 '22 23:11

Lubos Horacek


I used the built-in TimePickerDialog.

Looks like this

fun setAlarmTime(){

    val calendar = Calendar.getInstance()

    onView(isAssignableFrom(TimePicker::class.java)).perform(
        PickerActions.setTime(
            calendar.get(Calendar.HOUR_OF_DAY),
            calendar.get(Calendar.MINUTE) + 2
        )
    )
    onView(withText("OK")).perform(click())
}

Firstly, you should open the TimePickerDialog, then use this code. The time will be the current time + 2 minute. After the setup, it clicks on the OK button.

like image 23
Marci Avatar answered Nov 08 '22 00:11

Marci


I'm pretty sure that is impossible to test it with Espresso. You may need to take this action another UI testing tool called uiatomator.

uiatomator, another great tools made by Google allows you to test your Android system functions like notifications and screen lock. You can use it along with Espresso test framework.

Please read: Espresso & UIAutomator - the perfect tandem

and this official uiautomator documentation, which you would find here.

Also as I've already found uiautomator has a special class for testing this UI element called DatePickerHelper.java.

Check also this article: Crushing Fragmentation using the Factory Design Pattern with UiAutomator Notice that in this article author performs uiatomator tests on DatePicker.

Hope it help

like image 37
piotrek1543 Avatar answered Nov 07 '22 23:11

piotrek1543