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
17package android.widget.espresso;
18
19import static android.support.test.espresso.Espresso.onView;
20import static android.support.test.espresso.assertion.ViewAssertions.matches;
21import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
22import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
23import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
24import static android.support.test.espresso.matcher.ViewMatchers.withId;
25import static android.support.test.espresso.matcher.ViewMatchers.withText;
26
27import org.hamcrest.Matcher;
28
29import android.support.test.espresso.NoMatchingRootException;
30import android.support.test.espresso.NoMatchingViewException;
31import android.support.test.espresso.UiController;
32import android.support.test.espresso.ViewAction;
33import android.support.test.espresso.ViewInteraction;
34import android.support.test.espresso.action.GeneralLocation;
35import android.support.test.espresso.action.Press;
36import android.support.test.espresso.action.Tap;
37import android.view.View;
38
39public final class SuggestionsPopupwindowUtils {
40    private static final int id = com.android.internal.R.id.suggestionWindowContainer;
41
42    private SuggestionsPopupwindowUtils() {};
43
44    public static ViewInteraction onSuggestionsPopup() {
45        return onView(withId(id)).inRoot(withDecorView(hasDescendant(withId(id))));
46    }
47
48    private static ViewInteraction onSuggestionsPopupItem(Matcher<View> matcher) {
49        return onView(matcher).inRoot(withDecorView(hasDescendant(withId(id))));
50    }
51
52    /**
53     * Asserts that the suggestions popup is displayed on screen.
54     *
55     * @throws AssertionError if the assertion fails
56     */
57    public static void assertSuggestionsPopupIsDisplayed() {
58        onSuggestionsPopup().check(matches(isDisplayed()));
59    }
60
61    /**
62     * Asserts that the suggestions popup is not displayed on screen.
63     *
64     * @throws AssertionError if the assertion fails
65     */
66    public static void assertSuggestionsPopupIsNotDisplayed() {
67        try {
68            onSuggestionsPopup().check(matches(isDisplayed()));
69        } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) {
70            return;
71        }
72        throw new AssertionError("Suggestions popup is displayed");
73    }
74
75    /**
76     * Asserts that the suggestions popup contains the specified item.
77     *
78     * @param itemLabel label of the item.
79     * @throws AssertionError if the assertion fails
80     */
81    public static void assertSuggestionsPopupContainsItem(String itemLabel) {
82        onSuggestionsPopupItem(withText(itemLabel)).check(matches(isDisplayed()));
83    }
84
85    /**
86     * Click on the specified item in the suggestions popup.
87     *
88     * @param itemLabel label of the item.
89     */
90    public static void clickSuggestionsPopupItem(String itemLabel) {
91        onSuggestionsPopupItem(withText(itemLabel)).perform(new SuggestionItemClickAction());
92    }
93
94    /**
95     * Click action to avoid checking ViewClickAction#getConstraints().
96     * TODO: Use Espresso.onData instead of this.
97     */
98    private static final class SuggestionItemClickAction implements ViewAction {
99        private final ViewClickAction mViewClickAction;
100
101        public SuggestionItemClickAction() {
102            mViewClickAction =
103                    new ViewClickAction(Tap.SINGLE, GeneralLocation.VISIBLE_CENTER, Press.FINGER);
104        }
105
106        @Override
107        public Matcher<View> getConstraints() {
108            return isDisplayed();
109        }
110
111        @Override
112        public String getDescription() {
113            return mViewClickAction.getDescription();
114        }
115
116        @Override
117        public void perform(UiController uiController, View view) {
118            mViewClickAction.perform(uiController, view);
119        }
120    }
121}
122