18213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz/*
28213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * Copyright (C) 2012 The Android Open Source Project
38213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz *
48213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * Licensed under the Apache License, Version 2.0 (the "License");
58213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * you may not use this file except in compliance with the License.
68213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * You may obtain a copy of the License at
78213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz *
88213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz *      http://www.apache.org/licenses/LICENSE-2.0
98213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz *
108213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * Unless required by applicable law or agreed to in writing, software
118213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * distributed under the License is distributed on an "AS IS" BASIS,
128213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * See the License for the specific language governing permissions and
148213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * limitations under the License.
158213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz */
168213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazpackage com.android.test.uiautomator.demos;
178213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
188213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazimport android.util.Log;
198213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
208213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazimport com.android.uiautomator.core.UiObject;
218213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazimport com.android.uiautomator.core.UiObjectNotFoundException;
228213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazimport com.android.uiautomator.core.UiScrollable;
238213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazimport com.android.uiautomator.core.UiSelector;
248213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazimport com.android.uiautomator.testrunner.UiAutomatorTestCase;
258213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
268213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz/**
278213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * This demos how we can scroll list views and verify data in list view
288213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * items. Here we do the following:
298213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * <ul>
308213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * <li> Launch Settings </li>
318213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * <li> Select the About </li>
328213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * <li> Read the Build string </li>
338213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz * </ul>
348213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz */
358213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtazpublic class LogBuildNumber extends UiAutomatorTestCase {
368213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    public static final String LOG_TAG = LogBuildNumber.class.getSimpleName();
378213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
388213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    @Override
398213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    protected void setUp() throws Exception {
408213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        super.setUp();
418213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
428213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
438213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    /**
448213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * For the purpose of this demo, we're declaring the Launcher signatures here.
458213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * It may be more appropriate to declare signatures and methods related
468213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * to Launcher in their own reusable Launcher helper file.
478213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     */
488213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    public static class LauncherHelper {
498213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        public static final UiSelector ALL_APPS_BUTTON = new UiSelector().description("Apps");
508213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        public static final UiSelector LAUNCHER_CONTAINER = new UiSelector().scrollable(true);
518213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        public static final UiSelector LAUNCHER_ITEM =
528213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                new UiSelector().className(android.widget.TextView.class.getName());
538213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
548213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
558213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    /**
568213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * For the purpose of this demo, we're declaring the Settings signatures here.
578213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * It may be more appropriate to declare signatures and methods related
588213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * to Settings in their own reusable Settings helper file.
598213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     */
608213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    public static class SettingsHelper {
618213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        public static final UiSelector LIST_VIEW =
628213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                new UiSelector().className(android.widget.ListView.class.getName());
638213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        public static final UiSelector LIST_VIEW_ITEM =
648213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                new UiSelector().className(android.widget.LinearLayout.class.getName());
658213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
668213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
678213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    /**
688213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * Script starts here
698213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * @throws UiObjectNotFoundException
708213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     */
718213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    public void testDemo() throws UiObjectNotFoundException {
728213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // The following code is documented in the LaunchSettings demo. For detailed description
738213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // of how this code works, look at the demo LaunchSettings
748213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
758213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // Good to start from here
768213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        getUiDevice().pressHome();
778213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
788213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // open the All Apps view
798213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiObject allAppsButton = new UiObject(LauncherHelper.ALL_APPS_BUTTON);
808213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        allAppsButton.click();
818213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
828213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // clicking the APPS tab
838213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiSelector appsTabSelector =
848213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                new UiSelector().className(android.widget.TabWidget.class.getName())
858213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                    .childSelector(new UiSelector().text("Apps"));
868213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiObject appsTab = new UiObject(appsTabSelector);
878213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        appsTab.click();
888213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
898213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // Clicking the Settings
908213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiScrollable allAppsScreen = new UiScrollable(LauncherHelper.LAUNCHER_CONTAINER);
918213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        allAppsScreen.setAsHorizontalList();
928213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiObject settingsApp =
938213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                allAppsScreen.getChildByText(LauncherHelper.LAUNCHER_ITEM, "Settings");
948213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        settingsApp.click();
958213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
968213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // Now we will select the settings we need to work with. To make this operation a little
978213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // more generic we will put it in a function. We will try it as a phone first then as a
988213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // tablet if phone is not our device type
998213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        if (!selectSettingsFor("About phone"))
1008213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            selectSettingsFor("About tablet");
1018213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1028213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // Now we need to read the Build number text and return it
1038213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        String buildNum = getAboutItem("Build number");
1048213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1058213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // Log it - Use adb logcat to view the results
1068213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        Log.i(LOG_TAG, "Build = " + buildNum);
1078213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
1088213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1098213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    /**
1108213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * Select a settings items and perform scroll if needed to find it.
1118213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * @param name
1128213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     */
1138213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    private boolean selectSettingsFor(String name)  {
1148213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        try {
1158213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            UiScrollable appsSettingsList = new UiScrollable(SettingsHelper.LIST_VIEW);
1168213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            UiObject obj = appsSettingsList.getChildByText(SettingsHelper.LIST_VIEW_ITEM, name);
1178213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            obj.click();
1188213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        } catch (UiObjectNotFoundException e) {
1198213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            return false;
1208213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        }
1218213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        return true;
1228213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
1238213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1248213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    /**
1258213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * This function will detect the presence of 2 or 1 list view display fragments and
1268213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * targets the correct list view for the About item details
1278213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * @param item
1288213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * @return the details string of an about item entry
1298213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     * @throws UiObjectNotFoundException
1308213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz     */
1318213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    private String getAboutItem(String item) throws UiObjectNotFoundException {
1328213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // try accessing the second list view if one exists else we will assume the
1338213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // device is displaying a single list view
1348213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiScrollable aboutSettingsList = new UiScrollable(SettingsHelper.LIST_VIEW.instance(1));
1358213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        if (!aboutSettingsList.exists())
1368213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            aboutSettingsList = new UiScrollable(SettingsHelper.LIST_VIEW.instance(0));
1378213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1388213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // the returned aboutItem will be pointing at the node matching the
1398213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // SettingsOsr.LIST_VIEW_ITEM. So, aboutItem is a container of widgets where one
1408213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // actually contains the text (item) we're looking for.
1418213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiObject aboutItem = aboutSettingsList.getChildByText(SettingsHelper.LIST_VIEW_ITEM, item);
1428213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1438213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // Since aboutItem contains the text widgets for the requested details, we're assuming
1448213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // here that the param 'item' refers to the label and the second text is the value for it.
1458213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        UiObject txt = aboutItem.getChild(
1468213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz                new UiSelector().className(android.widget.TextView.class.getName()).instance(1));
1478213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1488213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // This is interesting. Since aboutItem is returned pointing a the layout containing the
1498213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // test values, we know it is visible else an exception would've been thrown. However,
1508213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // we're not certain that the instance(1) or second text view inside this layout is
1518213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        // in fact fully visible and not off the screen.
1528213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        if (!txt.exists())
1538213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz            aboutSettingsList.scrollForward(); // scroll it into view
1548213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1558213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        return txt.getText();
1568213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
1578213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz
1588213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    @Override
1598213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    protected void tearDown() throws Exception {
1608213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz        super.tearDown();
1618213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz    }
1628213206c6ea8be2060db1ddf8acc18e9bcf06e95Adam Momtaz}
163