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 com.android.documentsui.bots; 18 19 import static androidx.test.espresso.Espresso.onView; 20 import static androidx.test.espresso.action.ViewActions.typeText; 21 import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant; 22 import static androidx.test.espresso.matcher.ViewMatchers.isClickable; 23 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; 24 import static androidx.test.espresso.matcher.ViewMatchers.withId; 25 26 import static junit.framework.Assert.assertEquals; 27 import static junit.framework.Assert.assertFalse; 28 import static junit.framework.Assert.assertTrue; 29 30 import static org.hamcrest.CoreMatchers.allOf; 31 import static org.hamcrest.CoreMatchers.anyOf; 32 33 import android.content.Context; 34 import android.support.test.uiautomator.UiDevice; 35 import android.support.test.uiautomator.UiObject; 36 import android.support.test.uiautomator.UiObjectNotFoundException; 37 import android.view.View; 38 39 import androidx.recyclerview.R; 40 41 import org.hamcrest.Matcher; 42 43 /** 44 * A test helper class that provides support for controlling the search UI 45 * programmatically, and making assertions against the state of the UI. 46 * <p> 47 * Support for working directly with Roots and Directory view can be found in the respective bots. 48 */ 49 public class SearchBot extends Bots.BaseBot { 50 51 // Dumb search layout changes substantially between Ryu and Angler. 52 @SuppressWarnings("unchecked") 53 private static final Matcher<View> SEARCH_WIDGET = allOf( 54 withId(R.id.option_menu_search), 55 anyOf(isClickable(), hasDescendant(isClickable()))); 56 57 // Note that input is visible when the clicky button is not 58 // present. So to clearly qualify the two...we explicitly 59 // require this input be not clickable. 60 @SuppressWarnings("unchecked") 61 private static final Matcher<View> SEARCH_INPUT = allOf( 62 withId(R.id.search_src_text), 63 isDisplayed()); 64 SearchBot(UiDevice device, Context context, int timeout)65 public SearchBot(UiDevice device, Context context, int timeout) { 66 super(device, context, timeout); 67 } 68 clickIcon()69 public void clickIcon() throws UiObjectNotFoundException { 70 UiObject searchView = findSearchView(); 71 searchView.click(); 72 } 73 clickSearchViewClearButton()74 public void clickSearchViewClearButton() throws UiObjectNotFoundException { 75 UiObject clear = findSearchViewClearButton(); 76 clear.click(); 77 } 78 setInputText(String query)79 public void setInputText(String query) throws UiObjectNotFoundException { 80 onView(SEARCH_INPUT).perform(typeText(query)); 81 } 82 assertIconVisible(boolean visible)83 public void assertIconVisible(boolean visible) { 84 if (visible) { 85 assertTrue( 86 "Search icon should be visible.", 87 Matchers.present(SEARCH_WIDGET)); 88 } else { 89 assertFalse( 90 "Search icon should not be visible.", 91 Matchers.present(SEARCH_WIDGET)); 92 } 93 } 94 assertInputEquals(String query)95 public void assertInputEquals(String query) 96 throws UiObjectNotFoundException { 97 UiObject textField = findSearchViewTextField(); 98 99 assertTrue(textField.exists()); 100 assertEquals(query, textField.getText()); 101 } 102 assertInputFocused(boolean focused)103 public void assertInputFocused(boolean focused) 104 throws UiObjectNotFoundException { 105 UiObject textField = findSearchViewTextField(); 106 107 assertTrue(textField.exists()); 108 assertEquals(focused, textField.isFocused()); 109 } 110 assertInputExists(boolean exists)111 public void assertInputExists(boolean exists) 112 throws UiObjectNotFoundException { 113 assertEquals(exists, findSearchViewTextField().exists()); 114 } 115 findSearchView()116 private UiObject findSearchView() { 117 return findObject(mTargetPackage + ":id/option_menu_search"); 118 } 119 findSearchViewTextField()120 private UiObject findSearchViewTextField() { 121 return findObject(mTargetPackage + ":id/option_menu_search", 122 mTargetPackage + ":id/search_src_text"); 123 } 124 findSearchViewClearButton()125 private UiObject findSearchViewClearButton() { 126 return findObject(mTargetPackage + ":id/option_menu_search", 127 mTargetPackage + ":id/search_close_btn"); 128 } 129 findSearchViewIcon()130 private UiObject findSearchViewIcon() { 131 return mContext.getResources().getBoolean(R.bool.full_bar_search_view) 132 ? findObject(mTargetPackage + ":id/option_menu_search") 133 : findObject(mTargetPackage + ":id/option_menu_search", 134 "android:id/search_button"); 135 } 136 } 137