1 /* 2 * Copyright (C) 2012 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 package com.android.test.uiautomator.demos; 17 18 import android.util.Log; 19 20 import com.android.uiautomator.core.UiObject; 21 import com.android.uiautomator.core.UiObjectNotFoundException; 22 import com.android.uiautomator.core.UiScrollable; 23 import com.android.uiautomator.core.UiSelector; 24 import com.android.uiautomator.testrunner.UiAutomatorTestCase; 25 26 /** 27 * This demos how we can scroll list views and verify data in list view 28 * items. Here we do the following: 29 * <ul> 30 * <li> Launch Settings </li> 31 * <li> Select the About </li> 32 * <li> Read the Build string </li> 33 * </ul> 34 */ 35 public class LogBuildNumber extends UiAutomatorTestCase { 36 public static final String LOG_TAG = LogBuildNumber.class.getSimpleName(); 37 38 @Override setUp()39 protected void setUp() throws Exception { 40 super.setUp(); 41 } 42 43 /** 44 * For the purpose of this demo, we're declaring the Launcher signatures here. 45 * It may be more appropriate to declare signatures and methods related 46 * to Launcher in their own reusable Launcher helper file. 47 */ 48 public static class LauncherHelper { 49 public static final UiSelector ALL_APPS_BUTTON = new UiSelector().description("Apps"); 50 public static final UiSelector LAUNCHER_CONTAINER = new UiSelector().scrollable(true); 51 public static final UiSelector LAUNCHER_ITEM = 52 new UiSelector().className(android.widget.TextView.class.getName()); 53 } 54 55 /** 56 * For the purpose of this demo, we're declaring the Settings signatures here. 57 * It may be more appropriate to declare signatures and methods related 58 * to Settings in their own reusable Settings helper file. 59 */ 60 public static class SettingsHelper { 61 public static final UiSelector LIST_VIEW = 62 new UiSelector().className(android.widget.ListView.class.getName()); 63 public static final UiSelector LIST_VIEW_ITEM = 64 new UiSelector().className(android.widget.LinearLayout.class.getName()); 65 } 66 67 /** 68 * Script starts here 69 * @throws UiObjectNotFoundException 70 */ testDemo()71 public void testDemo() throws UiObjectNotFoundException { 72 // The following code is documented in the LaunchSettings demo. For detailed description 73 // of how this code works, look at the demo LaunchSettings 74 75 // Good to start from here 76 getUiDevice().pressHome(); 77 78 // open the All Apps view 79 UiObject allAppsButton = new UiObject(LauncherHelper.ALL_APPS_BUTTON); 80 allAppsButton.click(); 81 82 // clicking the APPS tab 83 UiSelector appsTabSelector = 84 new UiSelector().className(android.widget.TabWidget.class.getName()) 85 .childSelector(new UiSelector().text("Apps")); 86 UiObject appsTab = new UiObject(appsTabSelector); 87 appsTab.click(); 88 89 // Clicking the Settings 90 UiScrollable allAppsScreen = new UiScrollable(LauncherHelper.LAUNCHER_CONTAINER); 91 allAppsScreen.setAsHorizontalList(); 92 UiObject settingsApp = 93 allAppsScreen.getChildByText(LauncherHelper.LAUNCHER_ITEM, "Settings"); 94 settingsApp.click(); 95 96 // Now we will select the settings we need to work with. To make this operation a little 97 // more generic we will put it in a function. We will try it as a phone first then as a 98 // tablet if phone is not our device type 99 if (!selectSettingsFor("About phone")) 100 selectSettingsFor("About tablet"); 101 102 // Now we need to read the Build number text and return it 103 String buildNum = getAboutItem("Build number"); 104 105 // Log it - Use adb logcat to view the results 106 Log.i(LOG_TAG, "Build = " + buildNum); 107 } 108 109 /** 110 * Select a settings items and perform scroll if needed to find it. 111 * @param name 112 */ selectSettingsFor(String name)113 private boolean selectSettingsFor(String name) { 114 try { 115 UiScrollable appsSettingsList = new UiScrollable(SettingsHelper.LIST_VIEW); 116 UiObject obj = appsSettingsList.getChildByText(SettingsHelper.LIST_VIEW_ITEM, name); 117 obj.click(); 118 } catch (UiObjectNotFoundException e) { 119 return false; 120 } 121 return true; 122 } 123 124 /** 125 * This function will detect the presence of 2 or 1 list view display fragments and 126 * targets the correct list view for the About item details 127 * @param item 128 * @return the details string of an about item entry 129 * @throws UiObjectNotFoundException 130 */ getAboutItem(String item)131 private String getAboutItem(String item) throws UiObjectNotFoundException { 132 // try accessing the second list view if one exists else we will assume the 133 // device is displaying a single list view 134 UiScrollable aboutSettingsList = new UiScrollable(SettingsHelper.LIST_VIEW.instance(1)); 135 if (!aboutSettingsList.exists()) 136 aboutSettingsList = new UiScrollable(SettingsHelper.LIST_VIEW.instance(0)); 137 138 // the returned aboutItem will be pointing at the node matching the 139 // SettingsOsr.LIST_VIEW_ITEM. So, aboutItem is a container of widgets where one 140 // actually contains the text (item) we're looking for. 141 UiObject aboutItem = aboutSettingsList.getChildByText(SettingsHelper.LIST_VIEW_ITEM, item); 142 143 // Since aboutItem contains the text widgets for the requested details, we're assuming 144 // here that the param 'item' refers to the label and the second text is the value for it. 145 UiObject txt = aboutItem.getChild( 146 new UiSelector().className(android.widget.TextView.class.getName()).instance(1)); 147 148 // This is interesting. Since aboutItem is returned pointing a the layout containing the 149 // test values, we know it is visible else an exception would've been thrown. However, 150 // we're not certain that the instance(1) or second text view inside this layout is 151 // in fact fully visible and not off the screen. 152 if (!txt.exists()) 153 aboutSettingsList.scrollForward(); // scroll it into view 154 155 return txt.getText(); 156 } 157 158 @Override tearDown()159 protected void tearDown() throws Exception { 160 super.tearDown(); 161 } 162 } 163