131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi/* 231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Copyright (C) 2016 The Android Open Source Project 331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License"); 531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * you may not use this file except in compliance with the License. 631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * You may obtain a copy of the License at 731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * http://www.apache.org/licenses/LICENSE-2.0 931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 1031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software 1131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS, 1231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * See the License for the specific language governing permissions and 1431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * limitations under the License 1531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi */ 1631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 1731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagipackage android.widget.espresso; 1831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 1931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.Espresso.onView; 2031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.assertion.ViewAssertions.matches; 2131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.matcher.RootMatchers.withDecorView; 2231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; 2331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 2431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.matcher.ViewMatchers.withId; 2531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport static android.support.test.espresso.matcher.ViewMatchers.withText; 2631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 2731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport org.hamcrest.Matcher; 2831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 2931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.NoMatchingRootException; 3031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.NoMatchingViewException; 3131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.UiController; 3231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.ViewAction; 3331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.ViewInteraction; 3431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.action.GeneralLocation; 3531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.action.Press; 3631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.support.test.espresso.action.Tap; 3731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagiimport android.view.View; 3831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 3931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagipublic final class SuggestionsPopupwindowUtils { 4031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi private static final int id = com.android.internal.R.id.suggestionWindowContainer; 4131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 4231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi private SuggestionsPopupwindowUtils() {}; 4331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 4431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public static ViewInteraction onSuggestionsPopup() { 4531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi return onView(withId(id)).inRoot(withDecorView(hasDescendant(withId(id)))); 4631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 4731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 4831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi private static ViewInteraction onSuggestionsPopupItem(Matcher<View> matcher) { 4931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi return onView(matcher).inRoot(withDecorView(hasDescendant(withId(id)))); 5031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 5131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 5231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi /** 5331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Asserts that the suggestions popup is displayed on screen. 5431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 5531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * @throws AssertionError if the assertion fails 5631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi */ 5731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public static void assertSuggestionsPopupIsDisplayed() { 5831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi onSuggestionsPopup().check(matches(isDisplayed())); 5931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 6031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 6131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi /** 6231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Asserts that the suggestions popup is not displayed on screen. 6331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 6431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * @throws AssertionError if the assertion fails 6531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi */ 6631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public static void assertSuggestionsPopupIsNotDisplayed() { 6731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi try { 6831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi onSuggestionsPopup().check(matches(isDisplayed())); 6931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) { 7031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi return; 7131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 7231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi throw new AssertionError("Suggestions popup is displayed"); 7331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 7431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 7531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi /** 7631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Asserts that the suggestions popup contains the specified item. 7731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 7831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * @param itemLabel label of the item. 7931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * @throws AssertionError if the assertion fails 8031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi */ 8131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public static void assertSuggestionsPopupContainsItem(String itemLabel) { 8231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi onSuggestionsPopupItem(withText(itemLabel)).check(matches(isDisplayed())); 8331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 8431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 8531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi /** 8631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Click on the specified item in the suggestions popup. 8731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * 8831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * @param itemLabel label of the item. 8931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi */ 9031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public static void clickSuggestionsPopupItem(String itemLabel) { 9131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi onSuggestionsPopupItem(withText(itemLabel)).perform(new SuggestionItemClickAction()); 9231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 9331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 9431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi /** 9531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * Click action to avoid checking ViewClickAction#getConstraints(). 9631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi * TODO: Use Espresso.onData instead of this. 9731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi */ 9831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi private static final class SuggestionItemClickAction implements ViewAction { 9931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi private final ViewClickAction mViewClickAction; 10031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 10131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public SuggestionItemClickAction() { 10231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi mViewClickAction = 10331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi new ViewClickAction(Tap.SINGLE, GeneralLocation.VISIBLE_CENTER, Press.FINGER); 10431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 10531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 10631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi @Override 10731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public Matcher<View> getConstraints() { 10831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi return isDisplayed(); 10931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 11031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 11131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi @Override 11231eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public String getDescription() { 11331eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi return mViewClickAction.getDescription(); 11431eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 11531eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi 11631eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi @Override 11731eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi public void perform(UiController uiController, View view) { 11831eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi mViewClickAction.perform(uiController, view); 11931eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 12031eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi } 12131eb74fb2bc33aea6a8054c861a6e7aac7c41f4bKeisuke Kuroyanagi} 122