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