/*
 * Copyright 2016, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.testing.espresso.RecyclerViewSample;

import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import androidx.test.core.app.ActivityScenario;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.filters.LargeTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * Test class showcasing some {@link RecyclerViewActions} from Espresso.
 */
@RunWith(AndroidJUnit4.class)
@LargeTest
public class RecyclerViewSampleTest {

    private static final int ITEM_BELOW_THE_FOLD = 40;

    /**
     * Use {@link ActivityScenario} to create and launch the activity under test. This is a
     * replacement for {@link androidx.test.rule.ActivityTestRule}.
     */
    @Rule
    public ActivityScenarioRule<MainActivity> activityScenarioRule =
        new ActivityScenarioRule<MainActivity>(MainActivity.class);
    
    @Test
    public void itemWithText_exists() {
        String itemElementText = activityRule.getActivity().getResources()
                .getString(R.string.item_element_text);

        // scrollTo will fail if no item matches.
        onView(ViewMatchers.withId(R.id.recyclerView))
                .perform(RecyclerViewActions.scrollTo(
                        hasDescendant(withText(itemElementText))
                ));
    }

    @Test
    public void scrollToItemBelowFold_checkItsText() {
        // First scroll to the position that needs to be matched and click on it.
        onView(ViewMatchers.withId(R.id.recyclerView))
                .perform(RecyclerViewActions.actionOnItemAtPosition(ITEM_BELOW_THE_FOLD, click()));

        // Match the text in an item below the fold and check that it's displayed.
        String itemElementText = getApplicationContext().getResources().getString(
                R.string.item_element_text) + String.valueOf(ITEM_BELOW_THE_FOLD);
        onView(withText(itemElementText)).check(matches(isDisplayed()));
    }

    @Test
    public void itemInMiddleOfList_hasSpecialText() {
        // First, scroll to the view holder using the isInTheMiddle matcher.
        onView(ViewMatchers.withId(R.id.recyclerView))
                .perform(RecyclerViewActions.scrollToHolder(isInTheMiddle()));

        // Check that the item has the special text.
        String middleElementText =
                getApplicationContext().getResources().getString(R.string.middle);
        onView(withText(middleElementText)).check(matches(isDisplayed()));
    }

    /**
     * Matches the {@link CustomAdapter.ViewHolder}s in the middle of the list.
     */
    private static Matcher<CustomAdapter.ViewHolder> isInTheMiddle() {
        return new TypeSafeMatcher<CustomAdapter.ViewHolder>() {
            @Override
            protected boolean matchesSafely(CustomAdapter.ViewHolder customHolder) {
                return customHolder.getIsInTheMiddle();
            }

            @Override
            public void describeTo(Description description) {
                description.appendText("item in the middle");
            }
        };
    }
}

@@ -945,16 +945,89 @@
 atches;%0A
+import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;%0A
 import s
@@ -1317,16 +1317,64 @@
 tchers;%0A
+import androidx.test.espresso.PerformException;%0A
 import a
@@ -2264,20 +2264,16 @@
 class);%0A
-    
 %0A    @Te
@@ -2266,32 +2266,67 @@
 ass);%0A%0A    @Test
+(expected = PerformException.class)
 %0A    public void
@@ -2343,14 +2343,20 @@
 ext_
-e
+doesNotE
 xist
-s
 () %7B
@@ -2368,140 +2368,138 @@
     
-String itemElementText = activityRule.getActivity().getResources()%0A                .getString(R.string.item_element_text);%0A%0A
+// Attempt to scroll to an item that contains the special text.%0A        onView(ViewMatchers.withId(R.id.recyclerView))%0A   
         
 // s
@@ -2494,16 +2494,21 @@
         
+     
 // scrol
@@ -2521,16 +2521,25 @@
 ll fail 
+the test 
 if no it
@@ -2554,63 +2554,8 @@
 es.%0A
-        onView(ViewMatchers.withId(R.id.recyclerView))%0A
     
@@ -2652,31 +2652,33 @@
 ithText(
-itemElementText
+%22not in the list%22
 ))%0A     

make test negative