Moving Settings tests closer to the settings code

Change-Id: Ia456db3a8728b35390963c989d5788f4f23806cd
This commit is contained in:
Ashita Sriraman
2018-01-17 10:27:29 -08:00
parent d6b0490dea
commit 48813e0c26
19 changed files with 3285 additions and 0 deletions

35
tests/uitests/Android.mk Normal file
View File

@@ -0,0 +1,35 @@
# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := SettingsUITests
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE_TAGS := tests
LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
LOCAL_STATIC_JAVA_LIBRARIES := \
app-helpers-base \
launcher-helper-lib \
settings-helper \
timeresult-helper-lib \
ub-uiautomator \
sysui-helper \
metrics-helper-lib \
platform-test-annotations \
#LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.settings.ui">
<application>
<uses-library android:name="android.test.runner" />
</application>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.READ_LOGS" />
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.settings.ui"
android:label="Android Settings Functional UI Tests" />
</manifest>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration description="Run Android Settings Functional UI Tests.">
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="SettingsUITests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="SettingsUITests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.settings.ui" />
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
</test>
</configuration>

View File

@@ -0,0 +1,224 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.Intent;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
/** Verifies basic functionality of the About Phone screen */
public class AboutPhoneSettingsTests extends InstrumentationTestCase {
private static final boolean LOCAL_LOGV = false;
private static final String TAG = "AboutPhoneSettingsTest";
private static final int TIMEOUT = 2000;
private static final String SETTINGS_PACKAGE = "com.android.settings";
private UiDevice mDevice;
// TODO: retrieve using name/ids from com.android.settings package
private static final String[] sResourceTexts = {
"Status",
"Legal information",
"Regulatory labels",
"Model",
"Android version",
"Android security patch level",
"Baseband version",
"Kernel version",
"Build number"
};
private static final String[] sClickableResourceTexts = {
"Status", "Legal information", "Regulatory labels",
};
@Override
public void setUp() throws Exception {
if (LOCAL_LOGV) {
Log.d(TAG, "-------");
}
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("Failed to freeze device orientaion", e);
}
// make sure we are in a clean state before starting the test
mDevice.pressHome();
Thread.sleep(TIMEOUT * 2);
launchAboutPhoneSettings(Settings.ACTION_DEVICE_INFO_SETTINGS);
// TODO: make sure we are always at the top of the app
// currently this will fail if the user has navigated into submenus
UiObject2 view =
mDevice.wait(
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
assertNotNull("Could not find main About Phone screen", view);
view.scroll(Direction.UP, 1.0f);
}
@Override
protected void tearDown() throws Exception {
// Adding an extra pressBack so we exit About Phone Settings
// and finish the test cleanly
mDevice.pressBack();
mDevice.pressHome(); // finish settings activity
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
super.tearDown();
}
private void launchAboutPhoneSettings(String aboutSetting) throws Exception {
Intent aboutIntent = new Intent(aboutSetting);
aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getInstrumentation().getContext().startActivity(aboutIntent);
}
/**
* Callable actions that can be taken when a UIObject2 is found
*
* @param device The current UiDevice
* @param item The UiObject2 that was found and can be acted on
*
* @return {@code true} if the call was successful, and {@code false} otherwise
*/
public interface UIObject2Callback {
boolean call(UiDevice device, UiObject2 item) throws Exception;
}
/**
* Clicks the given item and then presses the Back button
*
* <p>Used to test whether a given UiObject2 can be successfully clicked.
* Presses Back to restore state to the previous screen.
*
* @param device The device that can be used to press Back
* @param item The item to click
*
* @return {@code true} if clicking the item succeeded, and {@code false} otherwise
*/
public class UiObject2Clicker implements UIObject2Callback {
public boolean call(UiDevice device, UiObject2 item) throws Exception {
item.click();
Thread.sleep(TIMEOUT * 2); // give UI time to finish animating
boolean pressWorked = device.pressBack();
Thread.sleep(TIMEOUT * 2);
return pressWorked;
}
}
/**
* Removes items found in the view and optionally takes some action.
*
* @param device The current UiDevice
* @param itemsLeftToFind The items to search for in the current view
* @param action Action to call on each item that is found; pass {@code null} to take no action
*/
private void removeItemsAndTakeAction(
UiDevice device, ArrayList<String> itemsLeftToFind, UIObject2Callback action) throws Exception {
for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
String itemText = iterator.next();
UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
if (item != null) {
if (LOCAL_LOGV) {
Log.d(TAG, itemText + " is present");
}
iterator.remove();
if (action != null) {
boolean success = action.call(device, item);
assertTrue("Calling action after " + itemText + " did not work", success);
}
} else {
if (LOCAL_LOGV) {
Log.d(TAG, "Could not find " + itemText);
}
}
}
}
/**
* Searches for UI elements in the current view and optionally takes some action.
*
* <p>Will scroll down the screen until it has found all elements or reached the bottom.
* This allows elements to be found and acted on even if they change order.
*
* @param device The current UiDevice
* @param itemsToFind The items to search for in the current view
* @param action Action to call on each item that is found; pass {@code null} to take no action
*/
public void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind, UIObject2Callback action)
throws Exception {
ArrayList<String> itemsLeftToFind = new ArrayList<String>(Arrays.asList(itemsToFind));
assertFalse(
"There must be at least one item to search for on the screen!",
itemsLeftToFind.isEmpty());
if (LOCAL_LOGV) {
Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
}
boolean canScrollDown = true;
while (canScrollDown && !itemsLeftToFind.isEmpty()) {
removeItemsAndTakeAction(device, itemsLeftToFind, action);
// when we've finished searching the current view, scroll down
UiObject2 view =
device.wait(
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")),
TIMEOUT * 2);
if (view != null) {
canScrollDown = view.scroll(Direction.DOWN, 1.0f);
} else {
canScrollDown = false;
}
}
// check the last items once we have reached the bottom of the view
removeItemsAndTakeAction(device, itemsLeftToFind, action);
assertTrue(
"The following items were not found on the screen: "
+ TextUtils.join(", ", itemsLeftToFind),
itemsLeftToFind.isEmpty());
}
@MediumTest // UI interaction
public void testAllMenuEntriesExist() throws Exception {
searchForItemsAndTakeAction(mDevice, sResourceTexts, null);
}
// Suppressing this test as it might be causing other test failures
// Will verify that this test is the cause before proceeding with solution
@Suppress
@MediumTest // UI interaction
public void testClickableEntriesCanBeClicked() throws Exception {
searchForItemsAndTakeAction(mDevice, sClickableResourceTexts, new UiObject2Clicker());
}
}

View File

@@ -0,0 +1,279 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.support.test.metricshelper.MetricsAsserts;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import android.metrics.MetricsReader;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
public class AccessibilitySettingsTests extends InstrumentationTestCase {
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
private MetricsReader mMetricsReader;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
mMetricsReader = new MetricsReader();
// Clear out old logs
mMetricsReader.checkpoint();
}
@Override
protected void tearDown() throws Exception {
// Need to finish settings activity
mDevice.pressBack();
mDevice.pressHome();
mDevice.waitForIdle();
super.tearDown();
}
@Presubmit
@MediumTest
public void testHighContrastTextOn() throws Exception {
verifyAccessibilitySettingOnOrOff("High contrast text",
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0, 1);
}
@Presubmit
@MediumTest
public void testHighContrastTextOff() throws Exception {
verifyAccessibilitySettingOnOrOff("High contrast text",
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 1, 0);
}
@Presubmit
@MediumTest
public void testPowerButtonEndsCallOn() throws Exception {
verifyAccessibilitySettingOnOrOff("Power button ends call",
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 1, 2);
}
@Presubmit
@MediumTest
public void testPowerButtonEndsCallOff() throws Exception {
verifyAccessibilitySettingOnOrOff("Power button ends call",
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2, 1);
}
/* Suppressing these four tests. The settings don't play
* nice with Settings.System.putInt or Settings.Secure.putInt.
* Need further clarification. Filed bug b/27792029
*/
@Suppress
@MediumTest
public void testAutoRotateScreenOn() throws Exception {
verifyAccessibilitySettingOnOrOff("Auto-rotate screen",
Settings.System.ACCELEROMETER_ROTATION, 0, 1);
}
@Suppress
@MediumTest
public void testAutoRotateScreenOff() throws Exception {
verifyAccessibilitySettingOnOrOff("Auto-rotate screen",
Settings.System.ACCELEROMETER_ROTATION, 1, 0);
}
@Suppress
@MediumTest
public void testMonoAudioOn() throws Exception {
verifyAccessibilitySettingOnOrOff("Mono audio",
Settings.System.MASTER_MONO, 0, 1);
}
@Suppress
@MediumTest
public void testMonoAudioOff() throws Exception {
verifyAccessibilitySettingOnOrOff("Mono audio",
Settings.System.MASTER_MONO, 1, 0);
}
@Presubmit
@MediumTest
public void testLargeMousePointerOn() throws Exception {
verifyAccessibilitySettingOnOrOff("Large mouse pointer",
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, 1);
}
@Presubmit
@MediumTest
public void testLargeMousePointerOff() throws Exception {
verifyAccessibilitySettingOnOrOff("Large mouse pointer",
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 1, 0);
}
@Presubmit
@MediumTest
public void testColorCorrection() throws Exception {
verifySettingToggleAfterScreenLoad("Color correction",
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
MetricsAsserts.assertHasVisibilityLog("Missing color correction log",
mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_DALTONIZER, true);
}
// Suppressing this test, since UiAutomator + talkback don't play nice
@Suppress
@MediumTest
public void testTalkback() throws Exception {
verifySettingToggleAfterScreenLoad("TalkBack",
Settings.Secure.ACCESSIBILITY_ENABLED);
}
@Presubmit
@MediumTest
public void testCaptions() throws Exception {
verifySettingToggleAfterScreenLoad("Captions",
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
MetricsAsserts.assertHasVisibilityLog("Missing captions log",
mMetricsReader, MetricsEvent.ACCESSIBILITY_CAPTION_PROPERTIES, true);
}
@Presubmit
@MediumTest
public void testMagnificationGesture() throws Exception {
verifySettingToggleAfterScreenLoad("Magnification", "Magnify with triple-tap",
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
MetricsAsserts.assertHasVisibilityLog("Missing magnification log",
mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION, true);
}
@MediumTest
public void testClickAfterPointerStopsMoving() throws Exception {
verifySettingToggleAfterScreenLoad("Click after pointer stops moving",
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED);
}
@MediumTest
public void testAccessibilitySettingsLoadLog() throws Exception {
launchAccessibilitySettings();
MetricsAsserts.assertHasVisibilityLog("Missing accessibility settings load log",
mMetricsReader, MetricsEvent.ACCESSIBILITY, true);
}
public void launchAccessibilitySettings() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_ACCESSIBILITY_SETTINGS);
}
private void verifyAccessibilitySettingOnOrOff(String settingText,
String settingFlag, int initialFlagValue, int expectedFlagValue)
throws Exception {
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
settingFlag, initialFlagValue);
launchAccessibilitySettings();
UiObject2 settingsTitle = findItemOnScreen(settingText);
settingsTitle.click();
Thread.sleep(TIMEOUT);
int settingValue = Settings.Secure
.getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
assertEquals(settingText + " not correctly set after toggle",
expectedFlagValue, settingValue);
}
private void verifySettingToggleAfterScreenLoad(String settingText, String settingFlag)
throws Exception {
verifySettingToggleAfterScreenLoad(settingText, null, settingFlag);
}
private void verifySettingToggleAfterScreenLoad
(String settingText, String subSetting, String settingFlag) throws Exception {
// Load accessibility settings
launchAccessibilitySettings();
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
settingFlag, 0);
Thread.sleep(TIMEOUT);
// Tap on setting required
UiObject2 settingTitle = findItemOnScreen(settingText);
// Load screen
settingTitle.click();
Thread.sleep(TIMEOUT);
if (subSetting != null) {
UiObject2 subSettingObject = findItemOnScreen(subSetting);
subSettingObject.click();
Thread.sleep(TIMEOUT);
}
// Toggle value
UiObject2 settingToggle = mDevice.wait(Until.findObject(By.text("Off")),
TIMEOUT);
settingToggle.click();
dismissOpenDialog();
Thread.sleep(TIMEOUT);
// Assert new value
int settingValue = Settings.Secure.
getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
assertEquals(settingText + " value not set correctly", 1, settingValue);
// Toogle value
settingToggle.click();
dismissOpenDialog();
mDevice.pressBack();
Thread.sleep(TIMEOUT);
// Assert reset to old value
settingValue = Settings.Secure.
getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
assertEquals(settingText + " value not set correctly", 0, settingValue);
}
private UiObject2 findItemOnScreen(String item) throws Exception {
int count = 0;
UiObject2 settingsPanel = mDevice.wait(Until.findObject
(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT);
while (settingsPanel.fling(Direction.UP) && count < 3) {
count++;
}
count = 0;
UiObject2 setting = null;
while(count < 3 && setting == null) {
setting = mDevice.wait(Until.findObject(By.text(item)), TIMEOUT);
if (setting == null) {
settingsPanel.scroll(Direction.DOWN, 1.0f);
}
count++;
}
return setting;
}
private void dismissOpenDialog() throws Exception {
UiObject2 okButton = mDevice.wait(Until.findObject
(By.res("android:id/button1")), TIMEOUT*2);
if (okButton != null) {
okButton.click();
}
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.Intent;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.ActivityHelper;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
/** Verifies basic functionality of the About Phone screen */
public class AppsSettingsTests extends InstrumentationTestCase {
private static final boolean LOCAL_LOGV = false;
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final String TAG = "AboutPhoneSettingsTest";
private static final int TIMEOUT = 2000;
private ActivityHelper mActivityHelper = null;
private UiDevice mDevice;
private static final String[] sResourceTexts = {
"Storage",
"Data usage",
"Permissions",
"App notifications",
"Open by default",
"Battery",
"Memory"
};
@Override
public void setUp() throws Exception {
if (LOCAL_LOGV) {
Log.d(TAG, "-------");
}
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
mActivityHelper = ActivityHelper.getInstance();
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("Failed to freeze device orientaion", e);
}
// make sure we are in a clean state before starting the test
mDevice.pressHome();
Thread.sleep(TIMEOUT * 2);
launchAppsSettings();
UiObject2 view =
mDevice.wait(
Until.findObject(By.text("All apps")), TIMEOUT);
assertNotNull("Could not find Settings > Apps screen", view);
}
@Override
protected void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome(); // finish settings activity
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
super.tearDown();
}
@MediumTest
public void testAppSettingsListForCalculator() {
UiObject2 calculator = mDevice.wait(
Until.findObject(By.text("Calculator")), TIMEOUT);
calculator.click();
for (String setting : sResourceTexts) {
UiObject2 appSetting =
mDevice.wait(
Until.findObject(By.text(setting)), TIMEOUT);
assertNotNull("Missing setting for Calculator: " + setting, appSetting);
appSetting.scroll(Direction.DOWN, 10.0f);
}
}
@MediumTest
public void testDisablingAndEnablingSystemApp() throws Exception {
launchAppsSettings();
UiObject2 calculator = mDevice.wait(
Until.findObject(By.text("Calculator")), TIMEOUT);
calculator.click();
mDevice.waitForIdle(TIMEOUT);
UiObject2 appInfoList = mDevice.wait(
Until.findObject(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT);
appInfoList.scroll(Direction.DOWN, 100.0f);
UiObject2 disableButton = mDevice.wait(
Until.findObject(By.text("DISABLE")), TIMEOUT);
disableButton.click();
mDevice.waitForIdle(TIMEOUT);
// Click on "Disable App" on dialog.
mDevice.wait(
Until.findObject(By.text("DISABLE APP")), TIMEOUT).click();
mDevice.waitForIdle(TIMEOUT);
UiObject2 enableButton = mDevice.wait(
Until.findObject(By.text("ENABLE")), TIMEOUT);
assertNotNull("App not disabled successfully", enableButton);
enableButton.click();
mDevice.waitForIdle(TIMEOUT);
disableButton = mDevice.wait(
Until.findObject(By.text("DISABLE")), TIMEOUT);
assertNotNull("App not enabled successfully", disableButton);
}
private void launchAppsSettings() throws Exception {
Intent appsSettingsIntent = new
Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
mActivityHelper.launchIntent(appsSettingsIntent);
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.metrics.MetricsReader;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.support.test.metricshelper.MetricsAsserts;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
public class BluetoothNetworkSettingsTests extends InstrumentationTestCase {
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final int TIMEOUT = 2000;
private static final int LONG_TIMEOUT = 40000;
private UiDevice mDevice;
private MetricsReader mMetricsReader;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
mMetricsReader = new MetricsReader();
// Clear out old logs
mMetricsReader.checkpoint();
}
@Override
protected void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome();
mDevice.waitForIdle();
super.tearDown();
}
@Presubmit
@MediumTest
public void testBluetoothEnabled() throws Exception {
verifyBluetoothOnOrOff(true);
MetricsAsserts.assertHasActionLog("missing bluetooth toggle log",
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
}
@Presubmit
@MediumTest
public void testBluetoothDisabled() throws Exception {
verifyBluetoothOnOrOff(false);
MetricsAsserts.assertHasActionLog("missing bluetooth toggle log",
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
}
@MediumTest
public void testRenameOption() throws Exception {
launchBluetoothSettings();
verifyUiObjectClicked(By.text("Device name"), "Rename preference");
verifyUiObjectClicked(By.text("CANCEL"), "CANCEL button");
MetricsAsserts.assertHasActionLog("missing bluetooth rename device log",
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_RENAME);
MetricsAsserts.assertHasVisibilityLog("missing bluetooth rename dialog log",
mMetricsReader, MetricsEvent.DIALOG_BLUETOOTH_RENAME, true);
}
@MediumTest
public void testReceivedFilesOption() throws Exception {
launchBluetoothSettings();
verifyUiObjectClicked(By.text("Received files"), "Received files preference");
MetricsAsserts.assertHasActionLog("missing bluetooth received files log",
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_FILES);
}
@MediumTest
public void testHelpFeedbackOverflowOption() throws Exception {
launchBluetoothSettings();
// Verify help & feedback
assertNotNull("Help & feedback item not found under Bluetooth Settings",
mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT));
}
public void launchBluetoothSettings() throws Exception {
Intent btIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
btIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getInstrumentation().getContext().startActivity(btIntent);
Thread.sleep(TIMEOUT * 2);
}
/**
* Find the {@link UiObject2} by {@code itemSelector} and try to click it if possible.
*
* If not find, throw assertion error
* @param itemSelector used to find the {@link UiObject2}
* @param text the description of the {@link UiObject2}
*/
private void verifyUiObjectClicked(BySelector itemSelector, String text) throws Exception {
UiObject2 uiObject2 = mDevice.wait(Until.findObject(itemSelector), TIMEOUT);
assertNotNull(text + "is not present in bluetooth settings page", uiObject2);
uiObject2.click();
}
/**
* Toggles the Bluetooth switch and verifies that the change is reflected in Settings
*
* @param verifyOn set to whether you want the setting turned On or Off
*/
private void verifyBluetoothOnOrOff(boolean verifyOn) throws Exception {
String switchText = "ON";
BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getInstrumentation().getContext()
.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
if (verifyOn) {
switchText = "OFF";
bluetoothAdapter.disable();
} else {
bluetoothAdapter.enable();
}
launchBluetoothSettings();
mDevice.wait(Until
.findObject(By.res(SETTINGS_PACKAGE, "switch_widget").text(switchText)), TIMEOUT)
.click();
Thread.sleep(TIMEOUT);
String bluetoothValue =
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.BLUETOOTH_ON);
if (verifyOn) {
assertEquals("1", bluetoothValue);
} else {
assertEquals("0", bluetoothValue);
}
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.Context;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
import android.os.RemoteException;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class ConnectedDeviceTests {
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientation", e);
}
}
@After
public void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome();
}
// This NFC toggle test is set up this way since there's no way to set
// the NFC flag to enabled or disabled without touching UI.
// This way, we get coverage for whether or not the toggle button works.
@Test
public void testNFCToggle() throws Exception {
NfcManager manager = (NfcManager) InstrumentationRegistry.getTargetContext()
.getSystemService(Context.NFC_SERVICE);
NfcAdapter nfcAdapter = manager.getDefaultAdapter();
boolean nfcInitiallyEnabled = nfcAdapter.isEnabled();
InstrumentationRegistry.getContext().startActivity(new Intent()
.setClassName(
SETTINGS_PACKAGE,
"com.android.settings.Settings$ConnectedDeviceDashboardActivity"));
UiObject2 nfcSetting = mDevice.wait(Until.findObject(By.text("NFC")), TIMEOUT);
nfcSetting.click();
Thread.sleep(TIMEOUT * 2);
if (nfcInitiallyEnabled) {
assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled());
nfcSetting.click();
Thread.sleep(TIMEOUT * 2);
assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled());
} else {
assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled());
nfcSetting.click();
Thread.sleep(TIMEOUT * 2);
assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled());
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
public class DataUsageSettingsTests extends InstrumentationTestCase {
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
}
@Override
protected void tearDown() throws Exception {
// Need to finish settings activity
mDevice.pressBack();
mDevice.pressHome();
super.tearDown();
}
@MediumTest
public void testElementsOnDataUsageScreen() throws Exception {
launchDataUsageSettings();
assertNotNull("Data usage element not found",
mDevice.wait(Until.findObject(By.text("Usage")),
TIMEOUT));
assertNotNull("Data usage bar not found",
mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE,
"color_bar")), TIMEOUT));
assertNotNull("WiFi Data usage element not found",
mDevice.wait(Until.findObject(By.text("Wi-Fi data usage")),
TIMEOUT));
assertNotNull("Network restrictions element not found",
mDevice.wait(Until.findObject(By.text("Network restrictions")),
TIMEOUT));
}
public void launchDataUsageSettings() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_SETTINGS);
mDevice.wait(Until
.findObject(By.text("Network & Internet")), TIMEOUT)
.click();
Thread.sleep(TIMEOUT * 2);
assertNotNull("Network & internet screen not loaded", mDevice.wait(
Until.findObject(By.text("Data usage")), TIMEOUT));
mDevice.wait(Until
.findObject(By.text("Data usage")), TIMEOUT)
.click();
}
}

View File

@@ -0,0 +1,268 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.ContentResolver;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import android.system.helpers.SettingsHelper.SettingsType;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import java.util.regex.Pattern;
public class DisplaySettingsTest extends InstrumentationTestCase {
private static final String PAGE = Settings.ACTION_DISPLAY_SETTINGS;
private static final int TIMEOUT = 2000;
private static final FontSetting FONT_SMALL = new FontSetting("Small", 0.85f);
private static final FontSetting FONT_NORMAL = new FontSetting("Default", 1.00f);
private static final FontSetting FONT_LARGE = new FontSetting("Large", 1.15f);
private static final FontSetting FONT_HUGE = new FontSetting("Largest", 1.30f);
private UiDevice mDevice;
private ContentResolver mResolver;
private SettingsHelper mHelper;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
mDevice.setOrientationNatural();
mResolver = getInstrumentation().getContext().getContentResolver();
mHelper = new SettingsHelper();
}
@Override
public void tearDown() throws Exception {
// reset settings we touched that may impact others
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
mDevice.waitForIdle();
super.tearDown();
}
@Presubmit
@MediumTest
public void testAdaptiveBrightness() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
Thread.sleep(1000);
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness",
Settings.System.SCREEN_BRIGHTNESS_MODE));
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness",
Settings.System.SCREEN_BRIGHTNESS_MODE));
}
// blocked on b/27487224
@MediumTest
@Suppress
public void testDaydreamToggle() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
clickMore();
Pattern p = Pattern.compile("On|Off");
mHelper.clickSetting("Screen saver");
Thread.sleep(1000);
try {
assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p,
Settings.Secure.SCREENSAVER_ENABLED, false));
assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p,
Settings.Secure.SCREENSAVER_ENABLED, false));
} finally {
mDevice.pressBack();
}
}
@MediumTest
public void testAccelRotation() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
clickMore();
Thread.sleep(4000);
int currentAccelSetting = Settings.System.getInt(
mResolver, Settings.System.ACCELEROMETER_ROTATION);
mHelper.clickSetting("Auto-rotate screen");
int newAccelSetting = Settings.System.getInt(
mResolver, Settings.System.ACCELEROMETER_ROTATION);
assertTrue("Accelorometer setting unchanged after toggle", currentAccelSetting != newAccelSetting);
mHelper.clickSetting("Auto-rotate screen");
int revertedAccelSetting = Settings.System.getInt(
mResolver, Settings.System.ACCELEROMETER_ROTATION);
assertTrue("Accelorometer setting unchanged after toggle", revertedAccelSetting != newAccelSetting);
}
@MediumTest
public void testDaydream() throws Exception {
Settings.Secure.putInt(mResolver, Settings.Secure.SCREENSAVER_ENABLED, 1);
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
clickMore();
mHelper.scrollVert(false);
mDevice.wait(Until.findObject(By.text("Screen saver")), TIMEOUT).click();
try {
assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
"Current screen saver", "Clock", Settings.Secure.SCREENSAVER_COMPONENTS,
"com.google.android.deskclock/com.android.deskclock.Screensaver"));
assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
"Current screen saver", "Colors", Settings.Secure.SCREENSAVER_COMPONENTS,
"com.android.dreams.basic/com.android.dreams.basic.Colors"));
assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
"Current screen saver", "Photos", Settings.Secure.SCREENSAVER_COMPONENTS,
"com.google.android.apps.photos/com.google.android.apps.photos.daydream"
+ ".PhotosDreamService"));
} finally {
mDevice.pressBack();
Thread.sleep(2000);
}
}
@Presubmit
@MediumTest
public void testSleep15Seconds() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "15 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "15000"));
}
@MediumTest
public void testSleep30Seconds() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "30 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "30000"));
}
@MediumTest
public void testSleep1Minute() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "1 minute", Settings.System.SCREEN_OFF_TIMEOUT, "60000"));
}
@MediumTest
public void testSleep2Minutes() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "2 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "120000"));
}
@MediumTest
public void testSleep5Minutes() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "5 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "300000"));
}
@MediumTest
public void testSleep10Minutes() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "10 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "600000"));
}
@MediumTest
public void testSleep30Minutes() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(true);
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
"Sleep", "30 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "1800000"));
}
@Presubmit
@MediumTest
public void testFontSizeLarge() throws Exception {
verifyFontSizeSetting(1.00f, FONT_LARGE);
// Leaving the font size at large can make later tests fail, so reset it
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
// It takes a second for the new font size to be picked up
Thread.sleep(2000);
}
@MediumTest
public void testFontSizeDefault() throws Exception {
verifyFontSizeSetting(1.15f, FONT_NORMAL);
}
@MediumTest
public void testFontSizeLargest() throws Exception {
verifyFontSizeSetting(1.00f, FONT_HUGE);
// Leaving the font size at huge can make later tests fail, so reset it
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
// It takes a second for the new font size to be picked up
Thread.sleep(2000);
}
@MediumTest
public void testFontSizeSmall() throws Exception {
verifyFontSizeSetting(1.00f, FONT_SMALL);
}
private void verifyFontSizeSetting(float resetValue, FontSetting setting)
throws Exception {
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, resetValue);
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
clickMore();
mHelper.clickSetting("Font size");
try {
mDevice.wait(Until.findObject(By.desc(setting.getName())), TIMEOUT).click();
Thread.sleep(1000);
float changedValue = Settings.System.getFloat(
mResolver, Settings.System.FONT_SCALE);
assertEquals(setting.getSize(), changedValue, 0.0001);
} finally {
// Make sure to back out of the font menu
mDevice.pressBack();
}
}
private void clickMore() throws InterruptedException {
UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT);
if (more != null) {
more.click();
Thread.sleep(TIMEOUT);
}
}
private static class FontSetting {
private final String mSizeName;
private final float mSizeVal;
public FontSetting(String sizeName, float sizeVal) {
mSizeName = sizeName;
mSizeVal = sizeVal;
}
public String getName() {
return mSizeName;
}
public float getSize() {
return mSizeVal;
}
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import com.android.settings.ui.testutils.SettingsTestUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class HomepageDisplayTests {
private static final String[] HOMEPAGE_ITEMS = {
"Network & internet",
"Connected devices",
"Apps & notifications",
"Battery",
"Display",
"Sound",
"Storage",
"Security & location",
"Users & accounts",
"Accessibility",
"System",
"Support & tips"
};
private UiDevice mDevice;
private SettingsHelper mSettingsHelper;
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mSettingsHelper = new SettingsHelper();
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
}
@After
public void tearDown() throws Exception {
// Need to finish settings activity
mDevice.pressHome();
}
@Presubmit
@Test
public void testHomepageCategory() throws Exception {
// Launch Settings
SettingsHelper.launchSettingsPage(
InstrumentationRegistry.getContext(), Settings.ACTION_SETTINGS);
// Scroll to top
final UiObject2 view = mDevice.wait(
Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
TIMEOUT);
view.scroll(Direction.UP, 100f);
// Inspect each item
for (String item : HOMEPAGE_ITEMS) {
SettingsTestUtils.assertTitleMatch(mDevice, item);
}
}
}

View File

@@ -0,0 +1,243 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
public class LocationSettingsTests extends InstrumentationTestCase {
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
}
@Override
protected void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome();
super.tearDown();
}
@MediumTest
public void testLoadingLocationSettings () throws Exception {
// Load Security
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_SECURITY_SETTINGS);
SettingsHelper helper = new SettingsHelper();
helper.scrollVert(true);
// Tap on location
UiObject2 settingsPanel = mDevice.wait(Until.findObject
(By.res(SETTINGS_PACKAGE, "main_content")), TIMEOUT);
int count = 0;
UiObject2 locationTitle = null;
while(count < 6 && locationTitle == null) {
locationTitle = mDevice.wait(Until.findObject(By.text("Location")), TIMEOUT);
if (locationTitle == null) {
settingsPanel.scroll(Direction.DOWN, 1.0f);
}
count++;
}
// Verify location settings loads.
locationTitle.click();
Thread.sleep(TIMEOUT);
assertNotNull("Location screen has not loaded correctly",
mDevice.wait(Until.findObject(By.text("Location services")), TIMEOUT));
}
@Presubmit
@MediumTest
public void testLocationSettingOn() throws Exception {
verifyLocationSettingsOnOrOff(true);
}
@MediumTest
public void testLocationSettingOff() throws Exception {
verifyLocationSettingsOnOrOff(false);
}
@MediumTest
public void testLocationDeviceOnlyMode() throws Exception {
// Changing the value from default before testing the toggle to Device only mode
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
dismissAlertDialogs();
Thread.sleep(TIMEOUT);
verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
}
@MediumTest
public void testLocationBatterySavingMode() throws Exception {
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
Thread.sleep(TIMEOUT);
verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
}
@MediumTest
public void testLocationHighAccuracyMode() throws Exception {
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
Thread.sleep(TIMEOUT);
verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
}
@MediumTest
public void testLocationSettingsElements() throws Exception {
String[] textElements = {"Location", "Mode", "Recent location requests",
"Location services"};
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
Thread.sleep(TIMEOUT);
for (String element : textElements) {
assertNotNull(element + " item not found under Location Settings",
mDevice.wait(Until.findObject(By.text(element)), TIMEOUT));
}
}
@MediumTest
public void testLocationSettingsOverflowMenuElements() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
// Verify help & feedback
assertNotNull("Help & feedback item not found under Location Settings",
mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT));
// Verify scanning
assertNotNull("Scanning item not found under Location Settings",
mDevice.wait(Until.findObject(By.text("Scanning")), TIMEOUT));
}
private void verifyLocationSettingsMode(int mode) throws Exception {
int modeIntValue = 1;
String textMode = "Device only";
if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
modeIntValue = 3;
textMode = "High accuracy";
}
else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
modeIntValue = 2;
textMode = "Battery saving";
}
// Load location settings
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
// Tap on mode
dismissAlertDialogs();
// Load location settings
mDevice.wait(Until.findObject(By.text("Mode")), TIMEOUT).click();
Thread.sleep(TIMEOUT);
assertNotNull("Location mode screen not loaded", mDevice.wait(Until.findObject
(By.text("Location mode")), TIMEOUT));
// Choose said mode
mDevice.wait(Until.findObject(By.text(textMode)), TIMEOUT).click();
Thread.sleep(TIMEOUT);
dismissAlertDialogs();
mDevice.wait(Until.findObject(By.desc("Navigate up")), TIMEOUT).click();
Thread.sleep(TIMEOUT);
if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY ||
mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
dismissAlertDialogs();
}
// get setting and verify value
// Verify change of mode
int locationSettingMode =
Settings.Secure.getInt(getInstrumentation().getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE);
assertEquals(mode + " value not set correctly for location.", modeIntValue,
locationSettingMode);
}
private void verifyLocationSettingsOnOrOff(boolean verifyOn) throws Exception {
// Set location flag
if (verifyOn) {
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
}
else {
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
}
dismissAlertDialogs();
// Load location settings
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
dismissAlertDialogs();
// Toggle UI
mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT).click();
dismissAlertDialogs();
Thread.sleep(TIMEOUT);
// Verify change in setting
int locationEnabled = Settings.Secure.getInt(getInstrumentation()
.getContext().getContentResolver(),
Settings.Secure.LOCATION_MODE);
if (verifyOn) {
assertFalse("Location not enabled correctly", locationEnabled == 0);
}
else {
assertEquals("Location not disabled correctly", 0, locationEnabled);
}
}
// This method dismisses both alert dialogs that might popup and
// interfere with the test. Since the order in which the dialog
// shows up changes in no specific known way, we're checking for
// both dialogs in any order for a robust test. Bug b/36233151
// filed against Location team for specifications. This is a
// workaround in the meantime to ensure coverage.
private void dismissAlertDialogs() throws Exception {
for (int count = 0; count < 2; count++) {
UiObject2 agreeDialog = mDevice.wait(Until.findObject
(By.text("Improve location accuracy?")), TIMEOUT);
UiObject2 previousChoiceYesButton = mDevice.wait(Until.findObject
(By.text("YES")), TIMEOUT);
if (agreeDialog != null) {
mDevice.wait(Until.findObject
(By.text("AGREE")), TIMEOUT).click();
Thread.sleep(TIMEOUT);
assertNull("Improve location dialog not dismissed",
mDevice.wait(Until.findObject
(By.text("Improve location accuracy?")), TIMEOUT));
}
if (previousChoiceYesButton != null) {
previousChoiceYesButton.click();
// Short sleep to wait for the new screen
Thread.sleep(TIMEOUT);
}
}
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
public class MoreWirelessSettingsTests extends InstrumentationTestCase {
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
}
@Override
protected void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome();
super.tearDown();
}
@Presubmit
@MediumTest
public void testAirplaneModeEnabled() throws Exception {
verifyAirplaneModeOnOrOff(true);
// Toggling this via the wifi network settings page
// because of bug b/34858716. Once that is fixed,
// we should be able to set this via Settings putString.
toggleAirplaneModeSwitch();
}
@Presubmit
@MediumTest
public void testAirplaneModeDisabled() throws Exception {
verifyAirplaneModeOnOrOff(false);
}
@MediumTest
public void testTetheringMenuLoad() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_WIRELESS_SETTINGS);
mDevice.wait(Until
.findObject(By.text("Hotspot & tethering")), TIMEOUT)
.click();
Thread.sleep(TIMEOUT);
UiObject2 usbTethering = mDevice.wait(Until
.findObject(By.text("USB tethering")), TIMEOUT);
assertNotNull("Tethering screen did not load correctly", usbTethering);
}
@MediumTest
public void testVPNMenuLoad() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_WIRELESS_SETTINGS);
mDevice.wait(Until
.findObject(By.text("VPN")), TIMEOUT)
.click();
Thread.sleep(TIMEOUT);
UiObject2 usbTethering = mDevice.wait(Until
.findObject(By.res(SETTINGS_PACKAGE, "vpn_create")), TIMEOUT);
assertNotNull("VPN screen did not load correctly", usbTethering);
}
private void verifyAirplaneModeOnOrOff(boolean verifyOn) throws Exception {
if (verifyOn) {
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, "0");
}
else {
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, "1");
}
toggleAirplaneModeSwitch();
String airplaneModeValue = Settings.Global
.getString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON);
if (verifyOn) {
assertEquals("1", airplaneModeValue);
}
else {
assertEquals("0", airplaneModeValue);
}
}
private void toggleAirplaneModeSwitch() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_WIRELESS_SETTINGS);
mDevice.wait(Until
.findObject(By.text("Airplane mode")), TIMEOUT)
.click();
Thread.sleep(TIMEOUT);
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.Intent;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.ActivityHelper;
import android.system.helpers.SettingsHelper;
import android.widget.ListView;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
/** Verifies that you can get to the notification app listing page from the apps & notifications
* page */
public class NotificationSettingsTests extends InstrumentationTestCase {
private static final boolean LOCAL_LOGV = false;
private static final String TAG = "NotifiSettingsTests";
private static final int TIMEOUT = 2000;
private ActivityHelper mActivityHelper = null;
private SettingsHelper mSettingsHelper = null;
private UiDevice mDevice;
@Override
public void setUp() throws Exception {
if (LOCAL_LOGV) {
Log.d(TAG, "-------");
}
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
mActivityHelper = ActivityHelper.getInstance();
mSettingsHelper = SettingsHelper.getInstance();
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("Failed to freeze device orientaion", e);
}
// make sure we are in a clean state before starting the test
mDevice.pressHome();
Thread.sleep(TIMEOUT * 2);
launchAppsSettings();
}
@Override
protected void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome(); // finish settings activity
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
super.tearDown();
}
@MediumTest
public void testNotificationsSettingsListForCalculator() {
UiObject2 configureNotifications = mDevice.wait(
Until.findObject(By.text("Notifications")), TIMEOUT);
configureNotifications.click();
mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT);
UiObject2 appNotifications = mDevice.wait(
Until.findObject(By.text("On for all apps")), TIMEOUT);
appNotifications.click();
UiObject2 view =
mDevice.wait(
Until.findObject(By.text("All apps")), TIMEOUT);
assertNotNull("Could not find Settings > Apps screen", view);
UiObject2 app = mDevice.wait(Until.findObject(By.text("Calculator")), TIMEOUT);
assertNotNull("Could not find Calculator notification settings", app);
}
@MediumTest
public void testNotificationsSettingsListForPhone() {
UiObject2 configureNotifications = mDevice.wait(
Until.findObject(By.text("Notifications")), TIMEOUT);
configureNotifications.click();
mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT);
UiObject2 appNotifications = mDevice.wait(
Until.findObject(By.text("On for all apps")), TIMEOUT);
appNotifications.click();
UiObject2 view =
mDevice.wait(
Until.findObject(By.text("All apps")), TIMEOUT);
assertNotNull("Could not find Settings > Apps screen", view);
final BySelector preferenceListSelector = By.clazz(ListView.class).res("android:id/list");
UiObject2 apps = mDevice.wait(Until.findObject(preferenceListSelector), TIMEOUT);
UiObject2 phone = scrollTo(mDevice, apps, By.text("Phone"), Direction.DOWN);
assertNotNull("Could not find Phone notification settings", phone);
phone.click();
UiObject2 incomingCalls = mDevice.wait(Until.findObject(By.text("Incoming calls")), TIMEOUT);
assertNotNull("Could not find incoming calls channel", incomingCalls);
incomingCalls.click();
// here's the meat of this test: make sure that you cannot change
// most settings for this channel
UiObject2 importance = mDevice.wait(Until.findObject(By.text("Importance")), TIMEOUT);
assertNotNull("Could not find importance toggle", importance);
assertFalse(importance.isEnabled());
assertFalse(mDevice.wait(Until.findObject(By.text("Sound")), TIMEOUT).isEnabled());;
assertFalse(mDevice.wait(Until.findObject(By.text("Vibrate")), TIMEOUT).isEnabled());
assertFalse(mDevice.wait(Until.findObject(By.text("Override Do Not Disturb")), TIMEOUT).isEnabled());
}
private UiObject2 scrollTo(UiDevice device, UiObject2 scrollable,
BySelector target, Direction direction) {
while (!device.hasObject(target) && scrollable.scroll(direction, 1.0f)) {
// continue
}
if (!device.hasObject(target)) {
// Scroll once more if not found; in some cases UiObject2.scroll can return false when
// the last item is not fully visible yet for list views.
scrollable.scroll(direction, 1.0f);
}
return device.findObject(target);
}
private void launchAppsSettings() throws Exception {
Intent appsSettingsIntent = new Intent(Settings.ACTION_SETTINGS);
mActivityHelper.launchIntent(appsSettingsIntent);
mSettingsHelper.flingSettingsToStart();
UiObject2 view = mDevice.wait(
Until.findObject(By.text("Apps & notifications")), TIMEOUT);
view.click();
UiObject2 title = mDevice.wait(
Until.findObject(By.text("Apps & notifications")), TIMEOUT);
assertNotNull("Could not find Settings > Apps & notifications screen", title);
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.system.helpers.SettingsHelper;
import com.android.settings.ui.testutils.SettingsTestUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class SecuritySettingsLaunchTest {
// Items we really want to always show
private static final String[] CATEGORIES = new String[]{
"Security status",
"Device security",
"Privacy",
};
private UiDevice mDevice;
private SettingsHelper mHelper;
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mHelper = SettingsHelper.getInstance();
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
}
@After
public void tearDown() throws Exception {
// Go back to home for next test.
mDevice.pressHome();
}
@Test
public void launchSecuritySettings() throws Exception {
// Launch Settings
SettingsHelper.launchSettingsPage(
InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS);
mHelper.scrollVert(false);
for (String category : CATEGORIES) {
SettingsTestUtils.assertTitleMatch(mDevice, category);
}
}
}

View File

@@ -0,0 +1,334 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.app.NotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.support.test.uiautomator.UiObject2;
import android.system.helpers.SettingsHelper;
import android.system.helpers.SettingsHelper.SettingsType;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import java.util.HashMap;
public class SoundSettingsTest extends InstrumentationTestCase {
private static final String PAGE = Settings.ACTION_SOUND_SETTINGS;
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
private ContentResolver mResolver;
private SettingsHelper mHelper;
private HashMap ringtoneSounds = new HashMap<String, String>() {{
put("angler","Dione");
put("bullhead","Dione");
put("marlin","Spaceship");
put("sailfish","Spaceship");
put("walleye","Copycat");
put("taimen","Copycat");
}};
private HashMap ringtoneCodes = new HashMap<String, String>() {{
put("angler","38");
put("bullhead","38");
put("marlin","37");
put("sailfish","37");
put("walleye","26");
put("taimen","26");
}};
private HashMap alarmSounds = new HashMap<String, String>() {{
put("angler","Awaken");
put("bullhead","Awaken");
put("marlin","Bounce");
put("sailfish","Bounce");
put("walleye","Cuckoo clock");
put("taimen","Cuckoo clock");
}};
private HashMap alarmCodes = new HashMap<String, String>() {{
put("angler","6");
put("bullhead","6");
put("marlin","49");
put("sailfish","49");
put("walleye","15");
put("taimen","15");
}};
private HashMap notificationSounds = new HashMap<String, String>() {{
put("angler","Ceres");
put("bullhead","Ceres");
put("marlin","Trill");
put("sailfish","Trill");
put("walleye","Pipes");
put("taimen","Pipes");
}};
private HashMap notificationCodes = new HashMap<String, String>() {{
put("angler","26");
put("bullhead","26");
put("marlin","57");
put("sailfish","57");
put("walleye","69");
put("taimen","69");
}};
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
mDevice.setOrientationNatural();
mResolver = getInstrumentation().getContext().getContentResolver();
mHelper = new SettingsHelper();
}
@Override
public void tearDown() throws Exception {
mDevice.pressBack();
mDevice.pressHome();
mDevice.waitForIdle();
mDevice.unfreezeRotation();
super.tearDown();
}
@MediumTest
public void testCallVibrate() throws Exception {
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
"Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING));
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
"Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING));
}
@MediumTest
public void testOtherSoundsDialPadTones() throws Exception {
loadOtherSoundsPage();
assertTrue("Dial pad tones not toggled", mHelper.verifyToggleSetting(
SettingsType.SYSTEM, PAGE, "Dial pad tones",
Settings.System.DTMF_TONE_WHEN_DIALING));
}
@MediumTest
public void testOtherSoundsScreenLocking() throws Exception {
loadOtherSoundsPage();
assertTrue("Screen locking sounds not toggled",
mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
"Screen locking sounds", Settings.System.LOCKSCREEN_SOUNDS_ENABLED));
}
@MediumTest
public void testOtherSoundsCharging() throws Exception {
loadOtherSoundsPage();
assertTrue("Charging sounds not toggled",
mHelper.verifyToggleSetting(SettingsType.GLOBAL, PAGE,
"Charging sounds", Settings.Global.CHARGING_SOUNDS_ENABLED));
}
@MediumTest
public void testOtherSoundsTouch() throws Exception {
loadOtherSoundsPage();
assertTrue("Touch sounds not toggled",
mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
"Touch sounds", Settings.System.SOUND_EFFECTS_ENABLED));
}
@MediumTest
public void testOtherSoundsVibrateOnTap() throws Exception {
loadOtherSoundsPage();
assertTrue("Vibrate on tap not toggled",
mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
"Vibrate on tap", Settings.System.HAPTIC_FEEDBACK_ENABLED));
}
private void loadOtherSoundsPage() throws Exception {
launchSoundSettings();
mHelper.scrollVert(false);
Thread.sleep(1000);
}
private void launchSoundSettings() throws Exception {
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
mHelper.scrollVert(false);
clickMore();
Thread.sleep(1000);
mHelper.scrollVert(true);
Thread.sleep(1000);
}
/*
* Rather than verifying every ringtone, verify the ones least likely to change
* (None and Hangouts) and an arbitrary one from the ringtone pool.
*/
@MediumTest
public void testPhoneRingtoneNone() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Phone ringtone");
verifyRingtone(new RingtoneSetting("None", "null"),
Settings.System.RINGTONE);
}
@MediumTest
@Suppress
public void testPhoneRingtoneHangouts() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Phone ringtone");
verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE);
}
@MediumTest
public void testPhoneRingtone() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Phone ringtone");
String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString();
String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString();
verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue),
Settings.System.RINGTONE);
}
@MediumTest
public void testNotificationRingtoneNone() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Default notification sound");
verifyRingtone(new RingtoneSetting("None", "null"),
Settings.System.NOTIFICATION_SOUND);
}
@MediumTest
@Suppress
public void testNotificationRingtoneHangouts() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Default notification sound");
verifyRingtone(new RingtoneSetting("Hangouts Message", "30"),
Settings.System.NOTIFICATION_SOUND);
}
@MediumTest
public void testNotificationRingtone() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Default notification sound");
String notificationRingtone = notificationSounds.get(mDevice.getProductName()).toString();
String notificationSettingValue = notificationCodes.get(mDevice.getProductName()).toString();
verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue),
Settings.System.NOTIFICATION_SOUND);
}
@MediumTest
public void testAlarmRingtoneNone() throws Exception {
launchSoundSettings();
mHelper.clickSetting("Default alarm sound");
verifyRingtone(new RingtoneSetting("None", "null"),
Settings.System.ALARM_ALERT);
}
@MediumTest
public void testAlarmRingtone() throws Exception {
launchSoundSettings();
String alarmRingtone = alarmSounds.get(mDevice.getProductName()).toString();
String alarmSettingValue = alarmCodes.get(mDevice.getProductName()).toString();
mHelper.clickSetting("Default alarm sound");
verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue),
Settings.System.ALARM_ALERT);
}
/*
* This method verifies that setting a custom ringtone changes the
* ringtone code setting on the system. Each ringtone sound corresponds
* to an arbitrary code. To see which ringtone code this is on your device, run
* adb shell settings get system ringtone
* The number you see at the end of the file path is the one you need.
* To see alarms and notifications ringtone codes, run the following:
* adb shell settings get system alarm_alert
* adb shell settings get system notification_sound
* @param r Ringtone setting - the name of the ringtone as displayed on device
* @param settingName - the code of the ringtone as explained above
* @param dir - the direction in which to scroll
*/
private void verifyRingtone(RingtoneSetting r, String settingName) throws Exception {
findRingtoneInList(r.getName()).click();
if (mDevice.getProductName().equals("walleye") || mDevice.getProductName().equals("taimen")) {
mDevice.wait(Until.findObject(By.text("SAVE")), TIMEOUT).click();
}
else {
mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click();
}
SystemClock.sleep(1000);
if (r.getVal().equals("null")) {
assertEquals(null,
Settings.System.getString(mResolver, settingName));
} else if (r.getName().contains("Hangouts")) {
assertEquals("content://media/external/audio/media/" + r.getVal(),
Settings.System.getString(mResolver, settingName));
} else {
assertEquals("content://media/internal/audio/media/" + r.getVal(),
Settings.System.getString(mResolver, settingName));
}
}
private enum ScrollDir {
UP,
DOWN,
NOSCROLL
}
class RingtoneSetting {
private final String mName;
private final String mMediaVal;
public RingtoneSetting(String name, String fname) {
mName = name;
mMediaVal = fname;
}
public String getName() {
return mName;
}
public String getVal() {
return mMediaVal;
}
}
private void clickMore() throws InterruptedException {
UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT);
if (more != null) {
more.click();
Thread.sleep(TIMEOUT);
}
}
private UiObject2 findRingtoneInList(String ringtone) throws Exception {
mHelper.scrollVert(false);
SystemClock.sleep(1000);
UiObject2 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT);
int count = 0;
while (ringToneObject == null && count < 5) {
mHelper.scrollVert(true);
SystemClock.sleep(1000);
ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT);
count++;
}
return ringToneObject;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.system.helpers.SettingsHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static junit.framework.Assert.assertTrue;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class SyncSettingsTest {
private static final int TIMEOUT = 2000;
private UiDevice mDevice;
@Before
public void setUp() throws Exception {
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientaion", e);
}
}
@After
public void tearDown() throws Exception {
// Need to finish settings activity
mDevice.pressHome();
}
@Test
public void syncPageShouldHaveAddAccountButton() throws Exception {
// Launch Settings
SettingsHelper.launchSettingsPage(
InstrumentationRegistry.getContext(), Settings.ACTION_SYNC_SETTINGS);
UiObject2 addAccount = mDevice.wait(
Until.findObject(By.text("Add account")), TIMEOUT);
assertTrue(addAccount != null);
}
}

View File

@@ -0,0 +1,777 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.system.helpers.CommandsHelper;
import android.system.helpers.SettingsHelper;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.StaleObjectException;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import junit.framework.AssertionFailedError;
public class WirelessNetworkSettingsTests extends InstrumentationTestCase {
// These back button presses are performed in tearDown() to exit Wifi
// Settings sub-menus that a test might finish in. This number should be
// high enough to account for the deepest sub-menu a test might enter.
private static final int NUM_BACK_BUTTON_PRESSES = 5;
private static final int TIMEOUT = 2000;
private static final int SLEEP_TIME = 500;
private static final String AIRPLANE_MODE_BROADCAST =
"am broadcast -a android.intent.action.AIRPLANE_MODE";
private static final String TAG="WirelessNetworkSettingsTests";
// Note: The values of these variables might affect flakiness in tests that involve
// scrolling. Adjust where necessary.
private static final float SCROLL_UP_PERCENT = 10.0f;
private static final float SCROLL_DOWN_PERCENT = 0.5f;
private static final int MAX_SCROLL_ATTEMPTS = 10;
private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3;
private static final int SCROLL_SPEED = 2000;
private static final String TEST_SSID = "testSsid";
private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char";
private static final String TEST_PW_LT_8_CHAR = "lt8Char";
private static final String TEST_DOMAIN = "testDomain.com";
private static final String SETTINGS_PACKAGE = "com.android.settings";
private static final String CHECKBOX_CLASS = "android.widget.CheckBox";
private static final String SPINNER_CLASS = "android.widget.Spinner";
private static final String EDIT_TEXT_CLASS = "android.widget.EditText";
private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView";
private static final String LISTVIEW_CLASS = "android.widget.ListView";
private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL";
private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE";
private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network";
private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "WiFi preferences";
private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced";
private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select";
private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates";
private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate";
private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select";
private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide";
private static final String SECURITY_OPTION_NONE_TEXT = "None";
private static final String SECURITY_OPTION_WEP_TEXT = "WEP";
private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK";
private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP";
private static final String EAP_METHOD_PEAP_TEXT = "PEAP";
private static final String EAP_METHOD_TLS_TEXT = "TLS";
private static final String EAP_METHOD_TTLS_TEXT = "TTLS";
private static final String EAP_METHOD_PWD_TEXT = "PWD";
private static final String EAP_METHOD_SIM_TEXT = "SIM";
private static final String EAP_METHOD_AKA_TEXT = "AKA";
private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'";
private static final String PHASE2_MENU_NONE_TEXT = "None";
private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2";
private static final String PHASE2_MENU_GTC_TEXT = "GTC";
private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox";
private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings";
private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings";
private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security";
private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method";
private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid";
private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2";
private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert";
private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert";
private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning";
private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning";
private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain";
private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain";
private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity";
private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous";
private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout";
private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID =
"show_password_layout";
private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password";
private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR =
By.scrollable(true).clazz(SCROLLVIEW_CLASS);
private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR =
By.scrollable(true).clazz(LISTVIEW_CLASS);
private UiDevice mDevice;
private CommandsHelper mCommandsHelper;
@Override
public void setUp() throws Exception {
super.setUp();
mDevice = UiDevice.getInstance(getInstrumentation());
try {
mDevice.setOrientationNatural();
} catch (RemoteException e) {
throw new RuntimeException("failed to freeze device orientation", e);
}
// Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, "0");
Log.d(TAG, "sending airplane mode broadcast to device");
mCommandsHelper = CommandsHelper.getInstance();
mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
}
@Override
protected void tearDown() throws Exception {
// Exit all settings sub-menus.
for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
mDevice.pressBack();
}
mDevice.pressHome();
super.tearDown();
}
@Presubmit
@MediumTest
public void testWiFiEnabled() throws Exception {
verifyWiFiOnOrOff(true);
}
@Presubmit
@MediumTest
public void testWiFiDisabled() throws Exception {
verifyWiFiOnOrOff(false);
}
@MediumTest
public void testWifiMenuLoadConfigure() throws Exception {
loadWiFiConfigureMenu();
Thread.sleep(SLEEP_TIME);
UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject
(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT);
assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading);
}
@MediumTest
public void testNetworkNotificationsOn() throws Exception {
verifyNetworkNotificationsOnOrOff(true);
}
@MediumTest
public void testNetworkNotificationsOff() throws Exception {
verifyNetworkNotificationsOnOrOff(false);
}
@MediumTest
public void testAddNetworkMenu_Default() throws Exception {
loadAddNetworkMenu();
// Submit button should be disabled by default, while cancel button should be enabled.
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Check that the SSID field is defaults to the hint.
assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID)
.clazz(EDIT_TEXT_CLASS)), TIMEOUT*2)
.getText());
// Check Security defaults to None.
assertEquals("None", mDevice.wait(Until.findObject(By
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
.clazz(SPINNER_CLASS)), TIMEOUT)
.getChildren().get(0).getText());
// Check advanced options are collapsed by default.
assertFalse(mDevice.wait(Until.findObject(By
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
.clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked());
}
@Suppress
@MediumTest
public void testAddNetworkMenu_Proxy() throws Exception {
loadAddNetworkMenu();
// Toggle advanced options.
mDevice.wait(Until.findObject(By
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
.clazz(CHECKBOX_CLASS)), TIMEOUT).click();
// Verify Proxy defaults to None.
BySelector proxySettingsBySelector =
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID)
.clazz(SPINNER_CLASS);
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT)
.getChildren().get(0).getText());
// Verify that Proxy Manual fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click();
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support"));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "proxy_hostname"));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "proxy_exclusionlist"));
// Verify that Proxy Auto-Config options appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click();
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "proxy_pac"));
}
@Suppress
@MediumTest
public void testAddNetworkMenu_IpSettings() throws Exception {
loadAddNetworkMenu();
// Toggle advanced options.
mDevice.wait(Until.findObject(By
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
.clazz(CHECKBOX_CLASS)), TIMEOUT).click();
// Verify IP settings defaults to DHCP.
BySelector ipSettingsBySelector =
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS);
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector);
assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT)
.getChildren().get(0).getText());
// Verify that Static IP settings options appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click();
mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click();
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "ipaddress"));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "gateway"));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "network_prefix_length"));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "dns1"));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, "dns2"));
}
@Suppress
@MediumTest
public void testPhase2Settings() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
BySelector phase2SettingsBySelector =
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS);
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector);
assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until
.findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText());
mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click();
Thread.sleep(SLEEP_TIME);
// Verify Phase 2 authentication spinner options.
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT));
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT));
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT));
}
@Suppress
@MediumTest
public void testCaCertSettings() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
BySelector caCertSettingsBySelector =
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS);
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector);
assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until
.findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText());
mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
Thread.sleep(SLEEP_TIME);
// Verify CA certificate spinner options.
assertNotNull(mDevice.wait(Until.findObject(
By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT));
assertNotNull(mDevice.wait(Until.findObject(
By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT));
assertNotNull(mDevice.wait(Until.findObject(
By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT));
// Verify that a domain field and warning appear when the user selects the
// "Use system certificates" option.
mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click();
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID));
// Verify that a warning appears when the user chooses the "Do Not Validate" option.
mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click();
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID));
}
@Suppress
@MediumTest
public void testAddNetwork_NoSecurity() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_NONE_TEXT);
// Entering an SSID is enough to enable the submit button. // TODO THIS GUY
enterSSID(TEST_SSID);
assertTrue(mDevice.wait(Until
.findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
@Suppress
@MediumTest
public void testAddNetwork_WEP() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_WEP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Verify that WEP fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
// Entering an SSID alone does not enable the submit button.
enterSSID(TEST_SSID);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Submit button is only enabled after a password is entered.
enterPassword(TEST_PW_GE_8_CHAR);
assertTrue(mDevice.wait(Until
.findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
@Suppress
@MediumTest
public void testAddNetwork_PSK() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_PSK_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Verify that PSK fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
// Entering an SSID alone does not enable the submit button.
enterSSID(TEST_SSID);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Entering an password that is too short does not enable submit button.
enterPassword(TEST_PW_LT_8_CHAR);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Submit button is only enabled after a password of valid length is entered.
enterPassword(TEST_PW_GE_8_CHAR);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_PEAP() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_PEAP_TEXT);
// Verify that EAP-PEAP fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
// Entering an SSID alone does not enable the submit button.
enterSSID(TEST_SSID);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
verifyCaCertificateSubmitConditions();
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_TLS() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_TLS_TEXT);
// Verify that EAP-TLS fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
// Entering an SSID alone does not enable the submit button.
enterSSID(TEST_SSID);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Selecting the User certificate "Do not provide" option alone does not enable the submit
// button.
selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
verifyCaCertificateSubmitConditions();
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_TTLS() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_TTLS_TEXT);
// Verify that EAP-TLS fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
// Entering an SSID alone does not enable the submit button.
enterSSID(TEST_SSID);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
verifyCaCertificateSubmitConditions();
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_PWD() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_PWD_TEXT);
// Verify that EAP-TLS fields appear.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
// Entering an SSID alone enables the submit button.
enterSSID(TEST_SSID);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_SIM() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_SIM_TEXT);
// Entering an SSID alone enables the submit button.
enterSSID(TEST_SSID);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_AKA() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_AKA_TEXT);
// Entering an SSID alone enables the submit button.
enterSSID(TEST_SSID);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
@Suppress
@MediumTest
public void testAddNetwork_EAP_AKA_PRIME() throws Exception {
loadAddNetworkMenu();
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT);
// Entering an SSID alone enables the submit button.
enterSSID(TEST_SSID);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)
throws Exception {
loadWiFiConfigureMenu();
mDevice.wait(Until.findObject(By.text("Keep WiFi on during sleep")), TIMEOUT)
.click();
mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView")
.text(settingToBeVerified)), TIMEOUT).click();
Thread.sleep(SLEEP_TIME);
int keepWiFiOnSetting =
Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
Settings.Global.WIFI_SLEEP_POLICY);
assertEquals(settingValue, keepWiFiOnSetting);
}
private void verifyNetworkNotificationsOnOrOff(boolean verifyOn)
throws Exception {
// Enable network recommendations to enable the toggle switch for Network
// notifications
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1");
if (verifyOn) {
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0");
}
else {
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
}
loadWiFiConfigureMenu();
mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT)
.click();
Thread.sleep(SLEEP_TIME);
String wifiNotificationValue =
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
if (verifyOn) {
assertEquals("1", wifiNotificationValue);
}
else {
assertEquals("0", wifiNotificationValue);
}
}
private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
String switchText = "On";
if (verifyOn) {
switchText = "Off";
}
loadWiFiSettingsPage(!verifyOn);
mDevice.wait(Until
.findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
.click();
Thread.sleep(SLEEP_TIME);
String wifiValue =
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
Settings.Global.WIFI_ON);
if (verifyOn) {
// 1 is Enabled, 2 is Enabled while airplane mode is ON.
assertTrue(wifiValue.equals("1") || wifiValue.equals("2"));
}
else {
assertEquals("0", wifiValue);
}
}
private void verifyCaCertificateSubmitConditions() throws Exception {
// Selecting the CA certificate "Do not validate" option enables the submit button.
selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// However, selecting the CA certificate "Use system certificates option" is not enough to
// enable the submit button.
selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT);
assertFalse(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
// Submit button is only enabled after a domain is entered as well.
enterDomain(TEST_DOMAIN);
assertTrue(mDevice.wait(Until.findObject(
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
}
private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(wifiEnabled);
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
Settings.ACTION_WIFI_SETTINGS);
}
private void loadWiFiConfigureMenu() throws Exception {
loadWiFiSettingsPage(false);
Thread.sleep(TIMEOUT);
mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click();
mDevice.wait(Until.findObject(
By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click();
}
private void loadAddNetworkMenu() throws Exception {
loadWiFiSettingsPage(true);
for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) {
try {
findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT))
.click();
} catch (StaleObjectException e) {
// The network list might have been updated between when the Add network button was
// found, and when it UI automator attempted to click on it. Retry.
continue;
}
// If we get here, we successfully clicked on the Add network button, so we are done.
Thread.sleep(SLEEP_TIME*5);
return;
}
fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS
+ " retries");
}
private void selectSecurityOption(String securityOption) throws Exception {
// We might not need to scroll to the security options if not enough add network menu
// options are visible.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
.clazz(SPINNER_CLASS)).click();
Thread.sleep(SLEEP_TIME);
mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click();
}
private void selectEAPMethod(String eapMethod) throws Exception {
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS))
.click();
Thread.sleep(SLEEP_TIME);
findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click();
}
private void selectUserCertificateOption(String userCertificateOption) throws Exception {
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS))
.click();
mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click();
}
private void selectCaCertificateOption(String caCertificateOption) throws Exception {
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS))
.click();
mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click();
}
private void enterSSID(String ssid) throws Exception {
// We might not need to scroll to the SSID option if not enough add network menu options
// are visible.
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS))
.setText(ssid);
}
private void enterPassword(String password) throws Exception {
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS))
.setText(password);
}
private void enterDomain(String domain) throws Exception {
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain);
}
// Use this if the UI object might or might not need to be scrolled to.
private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)
throws Exception {
UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT);
if (object == null) {
object = scrollToObject(scrollableSelector, objectSelector);
}
return object;
}
private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)
throws Exception {
UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT);
if (scrollable == null) {
fail("Could not find scrollable UI object identified by " + scrollableSelector);
}
UiObject2 found = null;
// Scroll all the way up first, then all the way down.
while (true) {
// Optimization: terminate if we find the object while scrolling up to reset, so
// we save the time spent scrolling down again.
boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT,
SCROLL_SPEED);
found = mDevice.findObject(objectSelector);
if (found != null) return found;
if (!canScrollAgain) break;
}
for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) {
// Return value of UiObject2.scroll() is not reliable, so do not use it in loop
// condition, in case it causes this loop to terminate prematurely.
scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED);
found = mDevice.findObject(objectSelector);
}
if (found == null) {
fail("Could not scroll to UI object identified by " + objectSelector);
}
return found;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.ui.testutils;
import static org.junit.Assert.assertNotNull;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
public class SettingsTestUtils {
public static final String SETTINGS_PACKAGE = "com.android.settings";
public static final int TIMEOUT = 2000;
private void scrollToTop(UiDevice device) throws Exception {
int count = 5;
UiObject2 view = null;
while (count >= 0) {
view = device.wait(
Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
TIMEOUT);
view.scroll(Direction.UP, 1.0f);
count--;
}
}
public static void assertTitleMatch(UiDevice device, String title) {
int maxAttempt = 5;
UiObject2 item = null;
UiObject2 view = null;
while (maxAttempt-- > 0) {
item = device.wait(Until.findObject(By.res("android:id/title").text(title)), TIMEOUT);
if (item == null) {
view = device.wait(
Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
TIMEOUT);
view.scroll(Direction.DOWN, 1.0f);
} else {
return;
}
}
assertNotNull(String.format("%s in Setting has not been loaded correctly", title), item);
}
}