package com.orgzly.android.espresso; import android.support.test.rule.ActivityTestRule; import android.widget.DatePicker; import android.widget.TimePicker; import com.orgzly.R; import com.orgzly.android.OrgzlyTest; import com.orgzly.android.ui.MainActivity; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.Espresso.pressBack; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.replaceText; import static android.support.test.espresso.action.ViewActions.scrollTo; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.contrib.PickerActions.setDate; import static android.support.test.espresso.contrib.PickerActions.setTime; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withClassName; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static com.orgzly.android.espresso.EspressoUtils.closeSoftKeyboardWithDelay; import static com.orgzly.android.espresso.EspressoUtils.onActionItemClick; import static com.orgzly.android.espresso.EspressoUtils.onListItem; import static com.orgzly.android.espresso.EspressoUtils.onSpinnerString; import static com.orgzly.android.espresso.EspressoUtils.settingsSetTodoKeywords; import static com.orgzly.android.espresso.EspressoUtils.spinnerItemCount; import static com.orgzly.android.espresso.EspressoUtils.toLandscape; import static com.orgzly.android.espresso.EspressoUtils.toPortrait; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; @SuppressWarnings("unchecked") public class NoteFragmentTest extends OrgzlyTest { @Rule public ActivityTestRule activityRule = new ActivityTestRule<>(MainActivity.class, true, false); @Before public void setUp() throws Exception { super.setUp(); shelfTestUtils.setupBook("book-name", "Sample book used for tests\n" + "* Note #1.\n" + "* Note #2.\n" + "SCHEDULED: <2014-05-22 Thu> DEADLINE: <2014-05-22 Thu>\n" + "** TODO Note #3.\n" + "** Note #4.\n" + "SCHEDULED: <2015-01-11 Sun .+1d/2d>\n" + "*** DONE Note #5.\n" + "CLOSED: [2014-01-01 Wed 20:07]\n" + "**** Note #6.\n" + "** Note #7.\n" + "* ANTIVIVISECTIONISTS Note #8.\n" + "**** Note #9.\n" + "** Note #10.\n" + ""); activityRule.launchActivity(null); onView(allOf(withText("book-name"), isDisplayed())).perform(click()); } @Test public void testSettingScheduleTime() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(withText(R.string.schedule_button_hint))); onView(withId(R.id.fragment_note_scheduled_button)).perform(click()); onView(withText(R.string.set)).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(allOf(withText(startsWith(userDate())), isDisplayed()))); } @Test public void testAbortingOfSettingScheduledTime() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(withText(R.string.schedule_button_hint))); onView(withId(R.id.fragment_note_scheduled_button)).perform(click()); pressBack(); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(withText(R.string.schedule_button_hint))); } @Test public void testRemovingScheduledTime() { onListItem(2).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(not(withText(R.string.schedule_button_hint)))); onView(withId(R.id.fragment_note_scheduled_button)).perform(click()); onView(withText("Clear")).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(withText(R.string.schedule_button_hint))); } @Test public void testSettingDeadlineTime() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(withText(R.string.deadline_button_hint))); onView(withId(R.id.fragment_note_deadline_button)).perform(click()); onView(withText(R.string.set)).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(allOf(withText(startsWith(userDate())), isDisplayed()))); } @Test public void testAbortingOfSettingDeadlineTime() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(withText(R.string.deadline_button_hint))); onView(withId(R.id.fragment_note_deadline_button)).perform(click()); pressBack(); onView(withId(R.id.fragment_note_deadline_button)).check(matches(withText(R.string.deadline_button_hint))); } @Test public void testRemovingDeadlineTime() { onListItem(2).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(not(withText(R.string.deadline_button_hint)))); onView(withId(R.id.fragment_note_deadline_button)).perform(click()); onView(withText("Clear")).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(withText(R.string.deadline_button_hint))); } @Test public void testStateToDoneShouldAddClosedTime() { onListItem(2).perform(click()); onView(withId(R.id.fragment_note_closed_button)).check(matches(not(isDisplayed()))); onView(withId(R.id.fragment_note_state)).perform(click()); onView(withText("DONE")).perform(click()); onView(withId(R.id.fragment_note_closed_button)).check(matches(allOf(withText(startsWith(userDate())), isDisplayed()))); } @Test public void testChangingStateSettingsFromNoteFragment() { onListItem(1).perform(click()); settingsSetTodoKeywords(""); onView(withId(R.id.fragment_note_state)).check(matches(spinnerItemCount(2))); // NOTE and others settingsSetTodoKeywords("TODO"); onView(withId(R.id.fragment_note_state)).check(matches(spinnerItemCount(3))); // NOTE and others } @Test public void testTitleCanNotBeEmptyForNewNote() { onView(withId(R.id.fab)).perform(click()); onView(withId(R.id.done)).perform(click()); onView(withText(R.string.can_not_be_empty)).check(matches(isDisplayed())); } @Test public void testTitleCanNotBeEmptyForExistingNote() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_title)).perform(replaceText("")); onView(withId(R.id.done)).perform(click()); onView(withText(R.string.can_not_be_empty)).check(matches(isDisplayed())); } @Test public void testSavingNoteWithRepeater() { onListItem(4).perform(click()); onView(withId(R.id.done)).perform(click()); } @Test public void testClosedTimeInNoteFragmentIsSameAsInList() { onListItem(5).perform(click()); onView(withId(R.id.fragment_note_closed_button)).check(matches(allOf(withText(userDateTime("[2014-01-01 Wed 20:07]")), isDisplayed()))); } @Test public void testSettingStateRemainsSetAfterRotation() { toPortrait(activityRule); onListItem(1).perform(click()); onView(withId(R.id.fragment_note_state)).perform(click()); // Open spinner onSpinnerString("TODO").perform(click()); onView(withText("TODO")).check(matches(isDisplayed())); toLandscape(activityRule); onView(withText("TODO")).check(matches(isDisplayed())); } @Test public void testSettingPriorityRemainsSetAfterRotation() { toPortrait(activityRule); onListItem(1).perform(click()); onView(withId(R.id.fragment_note_priority)).perform(click()); // Open spinner onSpinnerString("B").perform(click()); onView(withText("B")).check(matches(isDisplayed())); toLandscape(activityRule); onView(withText("B")).check(matches(isDisplayed())); } @Test public void testSettingScheduledTimeRemainsSetAfterRotation() { toPortrait(activityRule); onListItem(1).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(withText(R.string.schedule_button_hint))); onView(withId(R.id.fragment_note_scheduled_button)).perform(click()); onView(withText(R.string.set)).perform(click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(allOf(withText(startsWith(userDate())), isDisplayed()))); toLandscape(activityRule); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(allOf(withText(startsWith(userDate())), isDisplayed()))); } @Test public void testSetScheduledTimeAfterRotation() { onListItem(1).perform(click()); toPortrait(activityRule); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(withText(R.string.schedule_button_hint))); onView(withId(R.id.fragment_note_scheduled_button)).perform(click()); toLandscape(activityRule); onView(withText(R.string.set)).perform(closeSoftKeyboardWithDelay(), click()); onView(withId(R.id.fragment_note_scheduled_button)).check(matches(allOf(withText(startsWith(userDate())), isDisplayed()))); } @Test public void testRemovingDoneStateRemovesClosedTime() { onListItem(5).perform(click()); onView(withId(R.id.fragment_note_closed_button)).check(matches(allOf(withText(userDateTime("[2014-01-01 Wed 20:07]")), isDisplayed()))); onView(withId(R.id.fragment_note_state)).perform(click()); // Open spinner onSpinnerString("NOTE").perform(click()); onView(withId(R.id.fragment_note_closed_button)).check(matches(not(isDisplayed()))); } @Test public void testSettingPmTimeDisplays24HourTime() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(allOf(withText(R.string.deadline_button_hint), isDisplayed()))); onView(withId(R.id.fragment_note_deadline_button)).perform(click()); /* Set date. */ onView(withId(R.id.dialog_timestamp_date_picker)).perform(click()); onView(withClassName(equalTo(DatePicker.class.getName()))).perform(setDate(2014, 4, 1)); onView(withText(R.string.ok)).perform(click()); /* Set time. */ onView(withId(R.id.dialog_timestamp_time_picker)).perform(scrollTo(), click()); onView(withClassName(equalTo(TimePicker.class.getName()))).perform(setTime(15, 15)); onView(withText(R.string.ok)).perform(click()); onView(withText(R.string.set)).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(allOf(withText(userDateTime("<2014-04-01 Tue 15:15>")), isDisplayed()))); } @Test public void testDateTimePickerKeepsValuesAfterRotation() { onListItem(1).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(allOf(withText(R.string.deadline_button_hint), isDisplayed()))); toPortrait(activityRule); onView(withText(R.string.deadline_button_hint)).perform(click()); /* Set date. */ onView(withId(R.id.dialog_timestamp_date_picker)).perform(click()); onView(withClassName(equalTo(DatePicker.class.getName()))).perform(setDate(2014, 4, 1)); onView(withText(R.string.ok)).perform(click()); /* Set time. */ onView(withId(R.id.dialog_timestamp_time_picker)).perform(scrollTo(), click()); onView(withClassName(equalTo(TimePicker.class.getName()))).perform(setTime(9, 15)); onView(withText(R.string.ok)).perform(click()); /* Rotate screen. */ toLandscape(activityRule); /* Set time. */ onView(withText(R.string.set)).perform(click()); onView(withId(R.id.fragment_note_deadline_button)).check(matches(allOf(withText(userDateTime("<2014-04-01 Tue 09:15>")), isDisplayed()))); } @Test public void testChangingPrioritySettingsFromNoteFragment() { /* Open note which has no priority set. */ onListItem(1).perform(click()); /* Change lowest priority to A. */ onActionItemClick(R.id.activity_action_settings, R.string.settings); onListItem(EspressoUtils.SETTINGS_LOWEST_PRIORITY).perform(click()); onData(hasToString(containsString("A"))).perform(click()); pressBack(); onView(withId(R.id.fragment_note_priority)).check(matches(spinnerItemCount(2))); /* Change lowest priority to C. */ onActionItemClick(R.id.activity_action_settings, R.string.settings); onListItem(EspressoUtils.SETTINGS_LOWEST_PRIORITY).perform(click()); onData(hasToString(containsString("C"))).perform(click()); pressBack(); onView(withId(R.id.fragment_note_priority)).check(matches(spinnerItemCount(4))); } @Test public void testPropertiesAfterRotatingDevice() { onListItem(1).perform(click()); onView(withId(R.id.add_property)).perform(click()); onView(withId(R.id.name)).perform(replaceText("prop-name-1")); onView(withId(R.id.value)).perform(replaceText("prop-value-1"), closeSoftKeyboardWithDelay()); onView(withId(R.id.add_property)).perform(click()); onView(allOf(withId(R.id.name), not(withText("prop-name-1")))).perform(replaceText("prop-name-2")); onView(allOf(withId(R.id.value), not(withText("prop-value-1")))).perform(replaceText("prop-value-2"), closeSoftKeyboardWithDelay()); toLandscape(activityRule); toPortrait(activityRule); onView(allOf(withId(R.id.name), withText("prop-name-1"))).check(matches(isDisplayed())); onView(allOf(withId(R.id.value), withText("prop-value-1"))).check(matches(isDisplayed())); onView(allOf(withId(R.id.name), withText("prop-name-2"))).check(matches(isDisplayed())); onView(allOf(withId(R.id.value), withText("prop-value-2"))).check(matches(isDisplayed())); } }