blob: fe2a3c32098728033a144fef7214f61d938a93b0 [file] [log] [blame]
Steve McKayb9a20d12016-02-19 12:57:05 -08001/*
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
17package com.android.documentsui.bots;
18
19import static junit.framework.Assert.assertEquals;
20import static junit.framework.Assert.assertFalse;
21import static junit.framework.Assert.assertNotNull;
22import static junit.framework.Assert.assertTrue;
23
24import android.content.Context;
25import android.support.test.uiautomator.By;
26import android.support.test.uiautomator.UiDevice;
27import android.support.test.uiautomator.UiObject;
28import android.support.test.uiautomator.UiObject2;
29import android.support.test.uiautomator.UiObjectNotFoundException;
30import android.support.test.uiautomator.UiSelector;
31import android.support.test.uiautomator.Until;
32
33import com.android.documentsui.R;
34
35import java.util.Iterator;
36import 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 */
45public 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
49 public UiBot(UiDevice device, Context context, int timeout) {
50 super(device, context, timeout);
51 }
52
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
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
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
86 public void assertSearchTextFiledAndIcon(boolean searchTextFieldExists, boolean searchIconExists) {
87 assertEquals(searchTextFieldExists, findSearchViewTextField().exists());
88 assertEquals(searchIconExists, findSearchViewIcon().exists());
89 }
90
91 public void openSearchView() throws UiObjectNotFoundException {
92 UiObject searchView = findSearchView();
93 searchView.click();
94 assertTrue(searchView.exists());
95 }
96
97 public void setSearchQuery(String query) throws UiObjectNotFoundException {
98 UiObject searchView = findSearchView();
99 assertTrue(searchView.exists());
100 UiObject searchTextField = findSearchViewTextField();
101 searchTextField.setText(query);
102 assertSearchTextField(true, query);
103 }
104
105 public UiObject openOverflowMenu() throws UiObjectNotFoundException {
106 UiObject obj = findMenuMoreOptions();
107 obj.click();
108 mDevice.waitForIdle(mTimeout);
109 return obj;
110 }
111
112 public void setDialogText(String text) throws UiObjectNotFoundException {
113 findDialogEditText().setText(text);
114 }
115
116 void switchViewMode() {
117 UiObject2 mode = menuGridMode();
118 if (mode != null) {
119 mode.click();
120 } else {
121 menuListMode().click();
122 }
123 }
124
125 UiObject2 menuGridMode() {
126 // Note that we're using By.desc rather than By.res, because of b/25285770
127 return find(By.desc("Grid view"));
128 }
129
130 UiObject2 menuListMode() {
131 // Note that we're using By.desc rather than By.res, because of b/25285770
132 return find(By.desc("List view"));
133 }
134
135 public UiObject2 menuDelete() {
136 return find(By.res("com.android.documentsui:id/menu_delete"));
137 }
138
139 public UiObject2 menuShare() {
140 return find(By.res("com.android.documentsui:id/menu_share"));
141 }
142
143 public UiObject2 menuRename() {
144 return findMenuWithName(mContext.getString(R.string.menu_rename));
145 }
146
147 public UiObject2 menuNewFolder() {
148 return findMenuWithName(mContext.getString(R.string.menu_create_dir));
149 }
150
151 UiObject findSearchView() {
152 return findObject("com.android.documentsui:id/menu_search");
153 }
154
155 UiObject findSearchViewTextField() {
156 return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text");
157 }
158
159 UiObject findSearchViewIcon() {
160 return findObject("com.android.documentsui:id/menu_search", "android:id/search_button");
161 }
162
163 UiObject findActionModeBar() {
164 return findObject("android:id/action_mode_bar");
165 }
166
167 public UiObject findDialogEditText() {
168 return findObject("android:id/content", "android:id/text1");
169 }
170
171 public UiObject findRenameDialogOkButton() {
172 return findObject("android:id/content", "android:id/button1");
173 }
174
175 public UiObject findRenameDialogCancelButton() {
176 return findObject("android:id/content", "android:id/button2");
177 }
178
179 UiObject findMenuLabelWithName(String label) {
180 UiSelector selector = new UiSelector().text(label);
181 return mDevice.findObject(selector);
182 }
183
184 UiObject2 findMenuWithName(String label) {
185 List<UiObject2> menuItems = mDevice.findObjects(By.clazz("android.widget.LinearLayout"));
186 Iterator<UiObject2> it = menuItems.iterator();
187
188 UiObject2 menuItem = null;
189 while(it.hasNext()) {
190 menuItem = it.next();
191 UiObject2 text = menuItem.findObject(By.text(label));
192 if(text != null) {
193 break;
194 }
195 }
196 return menuItem;
197 }
198
199 UiObject findMenuMoreOptions() {
200 UiSelector selector = new UiSelector().className("android.widget.ImageButton")
201 .descriptionContains("More options");
202 //TODO: use the system string ? android.R.string.action_menu_overflow_description
203 return mDevice.findObject(selector);
204 }
205
206 public void revealLauncher() {
207 mDevice.pressHome();
208 mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), mTimeout);
209 }
210
211 public void revealApp() {
212 mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), mTimeout);
213 mDevice.waitForIdle();
214 }
215
216 public void pressKey(int keyCode) {
217 mDevice.pressKeyCode(keyCode);
218 }
219}