/*
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.espresso;
import android.app.*;
import android.content.*;
import android.support.test.*;
import android.support.test.espresso.*;
import android.support.test.espresso.intent.rule.*;
import android.support.test.runner.*;
import android.test.suitebuilder.annotation.*;
import org.hamcrest.*;
import org.isoron.uhabits.R;
import org.isoron.uhabits.activities.habits.list.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*;
import org.junit.*;
import org.junit.runner.*;
import java.util.*;
import static android.support.test.espresso.Espresso.*;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.*;
import static android.support.test.espresso.assertion.ViewAssertions.*;
import static android.support.test.espresso.intent.Intents.*;
import static android.support.test.espresso.intent.matcher.IntentMatchers.*;
import static android.support.test.espresso.matcher.ViewMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.isoron.uhabits.espresso.HabitViewActions.*;
import static org.isoron.uhabits.espresso.MainActivityActions.*;
import static org.isoron.uhabits.espresso.ShowHabitActivityActions.*;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainTest
{
private SystemHelper sys;
@Rule
public IntentsTestRule<ListHabitsActivity> activityRule =
new IntentsTestRule<>(ListHabitsActivity.class);
@Before
public void setup()
{
Context context =
InstrumentationRegistry.getInstrumentation().getContext();
sys = new SystemHelper(context);
sys.disableAllAnimations();
sys.acquireWakeLock();
sys.unlockScreen();
Instrumentation.ActivityResult okResult =
new Instrumentation.ActivityResult(Activity.RESULT_OK,
new Intent());
intending(hasAction(equalTo(Intent.ACTION_SEND))).respondWith(okResult);
intending(hasAction(equalTo(Intent.ACTION_SENDTO))).respondWith(
okResult);
intending(hasAction(equalTo(Intent.ACTION_VIEW))).respondWith(okResult);
skipTutorial();
}
public void skipTutorial()
{
try
{
for (int i = 0; i < 10; i++)
onView(allOf(withClassName(endsWith("AppCompatImageButton")),
isDisplayed())).perform(click());
}
catch (NoMatchingViewException e)
{
// ignored
}
}
@After
public void tearDown()
{
sys.releaseWakeLock();
}
/**
* User opens menu, clicks about, sees about screen.
*/
@Test
public void testAbout()
{
clickMenuItem(R.string.about);
onView(isRoot()).perform(swipeUp());
}
/**
* User creates a habit, toggles a bunch of checkmarks, clicks the habit to
* open the statistics screen, scrolls down to some views, then scrolls the
* views backwards and forwards in time.
*/
@Test
public void testAddHabitAndViewStats() throws InterruptedException
{
String name = addHabit(true);
onData(Matchers.allOf(is(instanceOf(Habit.class)),
HabitMatchers.withName(name)))
.onChildView(withId(R.id.checkmarkPanel))
.perform(toggleAllCheckmarks());
Thread.sleep(1200);
onData(Matchers.allOf(is(instanceOf(Habit.class)),
HabitMatchers.withName(name)))
.onChildView(withId(R.id.label))
.perform(click());
onView(withId(R.id.scoreView)).perform(scrollTo(), swipeRight());
onView(withId(R.id.frequencyChart)).perform(scrollTo(), swipeRight());
}
/**
* User opens the app, clicks the add button, types some bogus information,
* tries to save, dialog displays an error.
*/
@Test
public void testAddInvalidHabit()
{
onView(withId(R.id.actionAdd)).perform(click());
typeHabitData("", "", "15", "7");
onView(withId(R.id.buttonSave)).perform(click());
onView(withId(R.id.tvName)).check(matches(isDisplayed()));
}
/**
* User opens the app, creates some habits, selects them, archives them,
* select 'show archived' on the menu, selects the previously archived
* habits and then deletes them.
*/
@Test
public void testArchiveHabits()
{
List<String> names = new LinkedList<>();
for (int i = 0; i < 3; i++)
names.add(addHabit());
selectHabits(names);
clickMenuItem(R.string.archive);
assertHabitsDontExist(names);
clickMenuItem(R.string.show_archived);
assertHabitsExist(names);
selectHabits(names);
clickMenuItem(R.string.unarchive);
clickMenuItem(R.string.show_archived);
assertHabitsExist(names);
deleteHabits(names);
}
/**
* User creates a habit, selects the habit, clicks edit button, changes some
* information about the habit, click save button, sees changes on the main
* window, selects habit again, changes color, then deletes the habit.
*/
@Test
public void testEditHabit()
{
String name = addHabit();
onData(Matchers.allOf(is(instanceOf(Habit.class)),
HabitMatchers.withName(name)))
.onChildView(withId(R.id.label))
.perform(longClick());
clickMenuItem(R.string.edit);
String modifiedName = "Modified " + new Random().nextInt(10000);
typeHabitData(modifiedName, "", "1", "1");
onView(withId(R.id.buttonSave)).perform(click());
assertHabitExists(modifiedName);
selectHabit(modifiedName);
clickMenuItem(R.string.color_picker_default_title);
pressBack();
deleteHabit(modifiedName);
}
/**
* User creates a habit, opens statistics page, clicks button to edit
* history, adds some checkmarks, closes dialog, sees the modified history
* calendar.
*/
@Test
public void testEditHistory()
{
String name = addHabit();
onData(Matchers.allOf(is(instanceOf(Habit.class)),
HabitMatchers.withName(name)))
.onChildView(withId(R.id.label))
.perform(click());
openHistoryEditor();
onView(withClassName(endsWith("HabitHistoryView"))).perform(
clickAtRandomLocations(20));
pressBack();
onView(withId(R.id.historyChart)).perform(scrollTo(), swipeRight(),
swipeLeft());
}
/**
* User creates a habit, opens settings, clicks export as CSV, is asked what
* activity should handle the file.
*/
@Test
public void testExportCSV()
{
addHabit();
clickMenuItem(R.string.settings);
clickSettingsItem("Export as CSV");
intended(hasAction(Intent.ACTION_SEND));
}
/**
* User creates a habit, exports full backup, deletes the habit, restores
* backup, sees that the previously created habit has appeared back.
*/
@Test
public void testExportImportDB()
{
String name = addHabit();
clickMenuItem(R.string.settings);
String date =
DateFormats.getBackupDateFormat().format(DateUtils.getLocalTime());
date = date.substring(0, date.length() - 2);
clickSettingsItem("Export full backup");
intended(hasAction(Intent.ACTION_SEND));
deleteHabit(name);
clickMenuItem(R.string.settings);
clickSettingsItem("Import data");
onData(
allOf(is(instanceOf(String.class)), startsWith("Backups"))).perform(
click());
onData(
allOf(is(instanceOf(String.class)), containsString(date))).perform(
click());
selectHabit(name);
}
/**
* User opens the settings and generates a bug report.
*/
@Test
public void testGenerateBugReport()
{
clickMenuItem(R.string.settings);
clickSettingsItem("Generate bug report");
intended(hasAction(Intent.ACTION_SEND));
}
/**
* User opens menu, clicks Help, sees website.
*/
@Test
public void testHelp()
{
clickMenuItem(R.string.help);
intended(hasAction(Intent.ACTION_VIEW));
}
/**
* User opens menu, clicks settings, sees settings screen.
*/
@Test
public void testSettings()
{
clickMenuItem(R.string.settings);
}
}