1 /* 2 * Copyright (C) 2015 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 junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertFalse; 21 import static junit.framework.Assert.assertNotNull; 22 import static junit.framework.Assert.assertTrue; 23 24 import android.content.Context; 25 import android.support.test.uiautomator.By; 26 import android.support.test.uiautomator.UiDevice; 27 import android.support.test.uiautomator.UiObject; 28 import android.support.test.uiautomator.UiObject2; 29 import android.support.test.uiautomator.UiObjectNotFoundException; 30 import android.support.test.uiautomator.UiSelector; 31 import android.support.test.uiautomator.Until; 32 33 import com.android.documentsui.R; 34 35 import java.util.Iterator; 36 import java.util.List; 37 38 /** 39 * A test helper class that provides support for controlling DocumentsUI activities 40 * programmatically, and making assertions against the state of the UI. 41 * 42 * <p>Support for working directly with Roots and Directory view can be found 43 * in the respective bots. 44 */ 45 public class UiBot extends BaseBot { 46 public static final String TARGET_PKG = "com.android.documentsui"; 47 private static final String LAUNCHER_PKG = "com.android.launcher"; 48 UiBot(UiDevice device, Context context, int timeout)49 public UiBot(UiDevice device, Context context, int timeout) { 50 super(device, context, timeout); 51 } 52 assertWindowTitle(String expected)53 public void assertWindowTitle(String expected) { 54 // Turns out the title field on a window does not have 55 // an id associated with it at runtime (which confuses the hell out of me) 56 // In code we address this via "android.R.id.title". 57 UiObject2 o = find(By.text(expected)); 58 // It's a bit of a conceit that we then *assert* that the title 59 // is the value that we used to identify the UiObject2. 60 // If the preceeding lookup fails, this'll choke with an NPE. 61 // But given the issue described in the comment above, we're 62 // going to do it anyway. Because we shouldn't be looking up 63 // the uiobject by it's expected content :| 64 assertEquals(expected, o.getText()); 65 } 66 assertMenuEnabled(int id, boolean enabled)67 public void assertMenuEnabled(int id, boolean enabled) { 68 UiObject2 menu= findMenuWithName(mContext.getString(id)); 69 assertNotNull(menu); 70 assertEquals(enabled, menu.isEnabled()); 71 } 72 assertSearchTextField(boolean isFocused, String query)73 public void assertSearchTextField(boolean isFocused, String query) 74 throws UiObjectNotFoundException { 75 UiObject textField = findSearchViewTextField(); 76 UiObject searchIcon = findSearchViewIcon(); 77 78 assertFalse(searchIcon.exists()); 79 assertTrue(textField.exists()); 80 assertEquals(isFocused, textField.isFocused()); 81 if(query != null) { 82 assertEquals(query, textField.getText()); 83 } 84 } 85 assertSearchTextFiledAndIcon(boolean searchTextFieldExists, boolean searchIconExists)86 public void assertSearchTextFiledAndIcon(boolean searchTextFieldExists, boolean searchIconExists) { 87 assertEquals(searchTextFieldExists, findSearchViewTextField().exists()); 88 assertEquals(searchIconExists, findSearchViewIcon().exists()); 89 } 90 assertInActionMode(boolean inActionMode)91 public void assertInActionMode(boolean inActionMode) { 92 UiObject actionModeBar = findActionModeBar(); 93 assertEquals(inActionMode, actionModeBar.exists()); 94 } 95 openSearchView()96 public void openSearchView() throws UiObjectNotFoundException { 97 UiObject searchView = findSearchView(); 98 searchView.click(); 99 assertTrue(searchView.exists()); 100 } 101 setSearchQuery(String query)102 public void setSearchQuery(String query) throws UiObjectNotFoundException { 103 UiObject searchView = findSearchView(); 104 assertTrue(searchView.exists()); 105 UiObject searchTextField = findSearchViewTextField(); 106 searchTextField.setText(query); 107 assertSearchTextField(true, query); 108 } 109 openOverflowMenu()110 public UiObject openOverflowMenu() throws UiObjectNotFoundException { 111 UiObject obj = findMenuMoreOptions(); 112 obj.click(); 113 mDevice.waitForIdle(mTimeout); 114 return obj; 115 } 116 setDialogText(String text)117 public void setDialogText(String text) throws UiObjectNotFoundException { 118 findDialogEditText().setText(text); 119 } 120 switchViewMode()121 void switchViewMode() { 122 UiObject2 mode = menuGridMode(); 123 if (mode != null) { 124 mode.click(); 125 } else { 126 menuListMode().click(); 127 } 128 } 129 menuGridMode()130 UiObject2 menuGridMode() { 131 // Note that we're using By.desc rather than By.res, because of b/25285770 132 return find(By.desc("Grid view")); 133 } 134 menuListMode()135 UiObject2 menuListMode() { 136 // Note that we're using By.desc rather than By.res, because of b/25285770 137 return find(By.desc("List view")); 138 } 139 menuDelete()140 public UiObject2 menuDelete() { 141 return find(By.res("com.android.documentsui:id/menu_delete")); 142 } 143 menuShare()144 public UiObject2 menuShare() { 145 return find(By.res("com.android.documentsui:id/menu_share")); 146 } 147 menuRename()148 public UiObject2 menuRename() { 149 return findMenuWithName(mContext.getString(R.string.menu_rename)); 150 } 151 menuNewFolder()152 public UiObject2 menuNewFolder() { 153 return findMenuWithName(mContext.getString(R.string.menu_create_dir)); 154 } 155 findSearchView()156 UiObject findSearchView() { 157 return findObject("com.android.documentsui:id/menu_search"); 158 } 159 findSearchViewTextField()160 UiObject findSearchViewTextField() { 161 return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text"); 162 } 163 findSearchViewIcon()164 UiObject findSearchViewIcon() { 165 return mContext.getResources().getBoolean(R.bool.full_bar_search_view) 166 ? findObject("com.android.documentsui:id/menu_search") 167 : findObject("com.android.documentsui:id/menu_search", "android:id/search_button"); 168 } 169 findActionModeBar()170 UiObject findActionModeBar() { 171 return findObject("android:id/action_mode_bar"); 172 } 173 findDialogEditText()174 public UiObject findDialogEditText() { 175 return findObject("android:id/content", "android:id/text1"); 176 } 177 findDownloadRetryDialog()178 public UiObject findDownloadRetryDialog() { 179 UiSelector selector = new UiSelector().text("Couldn't download"); 180 UiObject title = mDevice.findObject(selector); 181 title.waitForExists(mTimeout); 182 return title; 183 } 184 findDialogOkButton()185 public UiObject findDialogOkButton() { 186 UiObject object = findObject("android:id/content", "android:id/button1"); 187 object.waitForExists(mTimeout); 188 return object; 189 } 190 findDialogCancelButton()191 public UiObject findDialogCancelButton() { 192 UiObject object = findObject("android:id/content", "android:id/button2"); 193 object.waitForExists(mTimeout); 194 return object; 195 } 196 findMenuLabelWithName(String label)197 UiObject findMenuLabelWithName(String label) { 198 UiSelector selector = new UiSelector().text(label); 199 return mDevice.findObject(selector); 200 } 201 findMenuWithName(String label)202 UiObject2 findMenuWithName(String label) { 203 List<UiObject2> menuItems = mDevice.findObjects(By.clazz("android.widget.LinearLayout")); 204 Iterator<UiObject2> it = menuItems.iterator(); 205 206 UiObject2 menuItem = null; 207 while(it.hasNext()) { 208 menuItem = it.next(); 209 UiObject2 text = menuItem.findObject(By.text(label)); 210 if(text != null) { 211 break; 212 } 213 } 214 return menuItem; 215 } 216 findMenuMoreOptions()217 UiObject findMenuMoreOptions() { 218 UiSelector selector = new UiSelector().className("android.widget.ImageButton") 219 .descriptionContains("More options"); 220 //TODO: use the system string ? android.R.string.action_menu_overflow_description 221 return mDevice.findObject(selector); 222 } 223 pressKey(int keyCode)224 public void pressKey(int keyCode) { 225 mDevice.pressKeyCode(keyCode); 226 } 227 } 228