1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package android.widget.espresso;
18 
19 import static androidx.test.espresso.Espresso.onView;
20 import static androidx.test.espresso.assertion.ViewAssertions.matches;
21 import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
22 import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
23 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
24 import static androidx.test.espresso.matcher.ViewMatchers.withId;
25 import static androidx.test.espresso.matcher.ViewMatchers.withText;
26 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
27 
28 import android.view.View;
29 
30 import androidx.test.espresso.NoMatchingRootException;
31 import androidx.test.espresso.NoMatchingViewException;
32 import androidx.test.espresso.UiController;
33 import androidx.test.espresso.ViewAction;
34 import androidx.test.espresso.ViewInteraction;
35 import androidx.test.espresso.action.GeneralLocation;
36 import androidx.test.espresso.action.Press;
37 import androidx.test.espresso.action.Tap;
38 
39 import org.hamcrest.Matcher;
40 
41 public final class SuggestionsPopupwindowUtils {
42     private static final int id = com.android.internal.R.id.suggestionWindowContainer;
43 
SuggestionsPopupwindowUtils()44     private SuggestionsPopupwindowUtils() {};
45 
onSuggestionsPopup()46     public static ViewInteraction onSuggestionsPopup() {
47         getInstrumentation().waitForIdleSync();
48         return onView(withId(id)).inRoot(withDecorView(hasDescendant(withId(id))));
49     }
50 
onSuggestionsPopupItem(Matcher<View> matcher)51     private static ViewInteraction onSuggestionsPopupItem(Matcher<View> matcher) {
52         getInstrumentation().waitForIdleSync();
53         return onView(matcher).inRoot(withDecorView(hasDescendant(withId(id))));
54     }
55 
56     /**
57      * Asserts that the suggestions popup is displayed on screen.
58      *
59      * @throws AssertionError if the assertion fails
60      */
assertSuggestionsPopupIsDisplayed()61     public static void assertSuggestionsPopupIsDisplayed() {
62         onSuggestionsPopup().check(matches(isDisplayed()));
63     }
64 
65     /**
66      * Asserts that the suggestions popup is not displayed on screen.
67      *
68      * @throws AssertionError if the assertion fails
69      */
assertSuggestionsPopupIsNotDisplayed()70     public static void assertSuggestionsPopupIsNotDisplayed() {
71         try {
72             onSuggestionsPopup().check(matches(isDisplayed()));
73         } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) {
74             return;
75         }
76         throw new AssertionError("Suggestions popup is displayed");
77     }
78 
79     /**
80      * Asserts that the suggestions popup contains the specified item.
81      *
82      * @param itemLabel label of the item.
83      * @throws AssertionError if the assertion fails
84      */
assertSuggestionsPopupContainsItem(String itemLabel)85     public static void assertSuggestionsPopupContainsItem(String itemLabel) {
86         onSuggestionsPopupItem(withText(itemLabel)).check(matches(isDisplayed()));
87     }
88 
89     /**
90      * Click on the specified item in the suggestions popup.
91      *
92      * @param itemLabel label of the item.
93      */
clickSuggestionsPopupItem(String itemLabel)94     public static void clickSuggestionsPopupItem(String itemLabel) {
95         onSuggestionsPopupItem(withText(itemLabel)).perform(new SuggestionItemClickAction());
96     }
97 
98     /**
99      * Click action to avoid checking ViewClickAction#getConstraints().
100      * TODO: Use Espresso.onData instead of this.
101      */
102     private static final class SuggestionItemClickAction implements ViewAction {
103         private final ViewClickAction mViewClickAction;
104 
SuggestionItemClickAction()105         public SuggestionItemClickAction() {
106             mViewClickAction =
107                     new ViewClickAction(Tap.SINGLE, GeneralLocation.VISIBLE_CENTER, Press.FINGER);
108         }
109 
110         @Override
getConstraints()111         public Matcher<View> getConstraints() {
112             return isDisplayed();
113         }
114 
115         @Override
getDescription()116         public String getDescription() {
117             return mViewClickAction.getDescription();
118         }
119 
120         @Override
perform(UiController uiController, View view)121         public void perform(UiController uiController, View view) {
122             mViewClickAction.perform(uiController, view);
123         }
124     }
125 }
126