package net.oldev.aBrightnessQS;


import android.support.test.espresso.ViewInteraction;
import android.support.test.filters.SmallTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
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.matcher.ViewMatchers.isAssignableFrom;
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.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;

/**
 * A sanity check test for Main UI
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void mainActivityTest() {
        // Click to get dialog to update brightness levels
        ViewInteraction brightnessPctsLayout = onView(
                allOf(withId(R.id.brightnessPctsSection), isDisplayed()));
        brightnessPctsLayout.perform(click());

        // randomize levels to be entered so that the new one is unlikely to be the same as the existing one.
        final int startLevel = (int)(System.currentTimeMillis() % 50) + 1;
        String newLevelsStr = startLevel + "," + (startLevel+10) + "," + (startLevel+30);

        replaceTextInDialog(R.id.brightnessPctsInput, R.string.ok_btn_label, newLevelsStr);

        // Assert the new levels are now displayed.
        onView(withId(R.id.brightnessPctsOutput))
                .check(matches(withText(newLevelsStr)));

        /// delay(1000); // for visual inspection
    }

    /**
     * Enter (& replace) text in a dialog, e.g., those generated by AlertDialog.builder
     *
     * @param dialogEditTextId the id of the EditText view within the dialog
     * @param dialogPositiveButtonLabelId the id of the *label of the positive button (Ideally id would be used, but it could not be set)
     * @param newText the new text to be entered.
     */
    private void replaceTextInDialog(int dialogEditTextId, int dialogPositiveButtonLabelId, String newText) {
        ViewInteraction editText = onView(
                allOf(withId(dialogEditTextId),
                        // withParent(...) check obtained from espresso recorder
                        withParent(allOf(withId(android.R.id.custom),
                                withParent(withClassName(is("android.widget.FrameLayout"))))),
                        isDisplayed()));
        editText.perform(click(),
                replaceText(newText),
                closeSoftKeyboard());

        ViewInteraction positiveButton = onView(
                allOf(withText(dialogPositiveButtonLabelId),
                        isAssignableFrom(android.widget.Button.class),
                        isDisplayed()));

        positiveButton.perform(scrollTo(), click());
    }

    private static void delay(long delayMillis) {
        // Added a sleep statement to match the app's execution delay.
        // The recommended way to handle such scenarios is to use Espresso idling resources:
        // https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/index.html
        try {
            Thread.sleep(delayMillis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

@@ -231,16 +231,49 @@
 Unit4;%0A%0A
+import org.junit.FixMethodOrder;%0A
 import o
@@ -342,16 +342,56 @@
 RunWith;
+%0Aimport org.junit.runners.MethodSorters;
 %0A%0Aimport
@@ -1417,16 +1417,62 @@
  UI%0A */%0A
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)%0A
 @SmallTe
@@ -1545,118 +1545,445 @@
     
-@Rule%0A    public ActivityTestRule%3CMainActivity%3E mActivityTestRule = new ActivityTestRule%3C%3E(MainActivity.class)
+private static final boolean RELAUNCH_ACTIVITY_TRUE = true;%0A%0A    // Note: The test relies on the fact the activity is relaunched per test method,%0A    // so that we can test settings persistence.%0A    @Rule%0A    public ActivityTestRule%3CMainActivity%3E mActivityTestRule = new ActivityTestRule%3C%3E(MainActivity.class, false, RELAUNCH_ACTIVITY_TRUE);%0A%0A    // Used to hold the new levels from test t1 to t2%0A    private static String msNewLevelsStr
 ;%0A%0A 
@@ -2011,24 +2011,24 @@
 oid 
-mainActivityTest
+t1ModifySettings
 () %7B
@@ -2458,24 +2458,19 @@
         
-String n
+msN
 ewLevels
@@ -2613,17 +2613,19 @@
 _label, 
-n
+msN
 ewLevels
@@ -2773,17 +2773,19 @@
 ithText(
-n
+msN
 ewLevels
@@ -2843,16 +2843,299 @@
 pection%0A
+%0A    %7D%0A%0A    @Test%0A    public void t2SettingsPersisted() %7B%0A        // Re-assert the new levels have been persisted, and are now displayed.%0A        // upon activity relaunch.%0A        onView(withId(R.id.brightnessPctsOutput))%0A                .check(matches(withText(msNewLevelsStr)));%0A%0A
     %7D%0A%0A 

test levels changes are persisted.