1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.ui; 18 19import android.content.Context; 20import android.net.wifi.WifiManager; 21import android.os.RemoteException; 22import android.platform.test.annotations.Presubmit; 23import android.provider.Settings; 24import android.support.test.uiautomator.By; 25import android.support.test.uiautomator.BySelector; 26import android.support.test.uiautomator.Direction; 27import android.support.test.uiautomator.StaleObjectException; 28import android.support.test.uiautomator.UiDevice; 29import android.support.test.uiautomator.UiObject2; 30import android.support.test.uiautomator.Until; 31import android.system.helpers.CommandsHelper; 32import android.system.helpers.SettingsHelper; 33import android.test.InstrumentationTestCase; 34import android.test.suitebuilder.annotation.MediumTest; 35import android.test.suitebuilder.annotation.Suppress; 36import android.util.Log; 37 38/** 39 * Additional tests for Wifi Settings. 40 */ 41public class MoreWirelessSettingsTest2 extends InstrumentationTestCase { 42 // These back button presses are performed in tearDown() to exit Wifi 43 // Settings sub-menus that a test might finish in. This number should be 44 // high enough to account for the deepest sub-menu a test might enter. 45 private static final int NUM_BACK_BUTTON_PRESSES = 5; 46 private static final int TIMEOUT = 2000; 47 private static final int SLEEP_TIME = 500; 48 private static final String AIRPLANE_MODE_BROADCAST = 49 "am broadcast -a android.intent.action.AIRPLANE_MODE"; 50 private static final String TAG="WirelessNetworkSettingsTests"; 51 52 // Note: The values of these variables might affect flakiness in tests that involve 53 // scrolling. Adjust where necessary. 54 private static final float SCROLL_UP_PERCENT = 10.0f; 55 private static final float SCROLL_DOWN_PERCENT = 0.5f; 56 private static final int MAX_SCROLL_ATTEMPTS = 10; 57 private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3; 58 private static final int SCROLL_SPEED = 2000; 59 60 private static final String TEST_SSID = "testSsid"; 61 private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char"; 62 private static final String TEST_PW_LT_8_CHAR = "lt8Char"; 63 private static final String TEST_DOMAIN = "testDomain.com"; 64 65 private static final String SETTINGS_PACKAGE = "com.android.settings"; 66 67 private static final String CHECKBOX_CLASS = "android.widget.CheckBox"; 68 private static final String SPINNER_CLASS = "android.widget.Spinner"; 69 private static final String EDIT_TEXT_CLASS = "android.widget.EditText"; 70 private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView"; 71 private static final String LISTVIEW_CLASS = "android.widget.ListView"; 72 73 private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL"; 74 private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE"; 75 private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network"; 76 private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences"; 77 private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced"; 78 private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select"; 79 private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates"; 80 private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate"; 81 private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select"; 82 private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide"; 83 private static final String SECURITY_OPTION_NONE_TEXT = "None"; 84 private static final String SECURITY_OPTION_WEP_TEXT = "WEP"; 85 private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK"; 86 private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP"; 87 private static final String EAP_METHOD_PEAP_TEXT = "PEAP"; 88 private static final String EAP_METHOD_TLS_TEXT = "TLS"; 89 private static final String EAP_METHOD_TTLS_TEXT = "TTLS"; 90 private static final String EAP_METHOD_PWD_TEXT = "PWD"; 91 private static final String EAP_METHOD_SIM_TEXT = "SIM"; 92 private static final String EAP_METHOD_AKA_TEXT = "AKA"; 93 private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'"; 94 private static final String PHASE2_MENU_NONE_TEXT = "None"; 95 private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2"; 96 private static final String PHASE2_MENU_GTC_TEXT = "GTC"; 97 98 private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox"; 99 private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings"; 100 private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings"; 101 private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security"; 102 private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method"; 103 private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid"; 104 private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2"; 105 private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert"; 106 private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert"; 107 private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning"; 108 private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning"; 109 private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain"; 110 private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain"; 111 private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity"; 112 private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous"; 113 private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout"; 114 private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID = 115 "show_password_layout"; 116 private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password"; 117 118 private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR = 119 By.scrollable(true).clazz(SCROLLVIEW_CLASS); 120 private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR = 121 By.scrollable(true).clazz(LISTVIEW_CLASS); 122 123 private UiDevice mDevice; 124 private CommandsHelper mCommandsHelper; 125 126 @Override 127 public void setUp() throws Exception { 128 super.setUp(); 129 mDevice = UiDevice.getInstance(getInstrumentation()); 130 try { 131 mDevice.setOrientationNatural(); 132 } catch (RemoteException e) { 133 throw new RuntimeException("failed to freeze device orientation", e); 134 } 135 // Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager. 136 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 137 Settings.Global.AIRPLANE_MODE_ON, "0"); 138 Log.d(TAG, "sending airplane mode broadcast to device"); 139 mCommandsHelper = CommandsHelper.getInstance(); 140 mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST); 141 } 142 143 @Override 144 protected void tearDown() throws Exception { 145 // Exit all settings sub-menus. 146 for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) { 147 mDevice.pressBack(); 148 } 149 mDevice.pressHome(); 150 super.tearDown(); 151 } 152 153 @MediumTest 154 public void testWifiMenuLoadConfigure() throws Exception { 155 loadWiFiConfigureMenu(); 156 Thread.sleep(SLEEP_TIME); 157 UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject 158 (By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT); 159 assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading); 160 } 161 162 @MediumTest 163 public void testNetworkNotificationsOn() throws Exception { 164 verifyNetworkNotificationsOnOrOff(true); 165 } 166 167 @MediumTest 168 public void testNetworkNotificationsOff() throws Exception { 169 verifyNetworkNotificationsOnOrOff(false); 170 } 171 172 @MediumTest 173 public void testAddNetworkMenu_Default() throws Exception { 174 loadAddNetworkMenu(); 175 176 // Submit button should be disabled by default, while cancel button should be enabled. 177 assertFalse(mDevice.wait(Until.findObject( 178 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 179 assertTrue(mDevice.wait(Until.findObject( 180 By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled()); 181 182 // Check that the SSID field is defaults to the hint. 183 assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By 184 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID) 185 .clazz(EDIT_TEXT_CLASS)), TIMEOUT*2) 186 .getText()); 187 188 // Check Security defaults to None. 189 assertEquals("None", mDevice.wait(Until.findObject(By 190 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID) 191 .clazz(SPINNER_CLASS)), TIMEOUT) 192 .getChildren().get(0).getText()); 193 194 // Check advanced options are collapsed by default. 195 assertFalse(mDevice.wait(Until.findObject(By 196 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) 197 .clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked()); 198 199 } 200 201 @Suppress 202 @MediumTest 203 public void testAddNetworkMenu_Proxy() throws Exception { 204 loadAddNetworkMenu(); 205 206 // Toggle advanced options. 207 mDevice.wait(Until.findObject(By 208 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) 209 .clazz(CHECKBOX_CLASS)), TIMEOUT).click(); 210 211 // Verify Proxy defaults to None. 212 BySelector proxySettingsBySelector = 213 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID) 214 .clazz(SPINNER_CLASS); 215 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); 216 assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT) 217 .getChildren().get(0).getText()); 218 219 // Verify that Proxy Manual fields appear. 220 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); 221 mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click(); 222 mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click(); 223 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 224 By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support")); 225 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 226 By.res(SETTINGS_PACKAGE, "proxy_hostname")); 227 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 228 By.res(SETTINGS_PACKAGE, "proxy_exclusionlist")); 229 230 // Verify that Proxy Auto-Config options appear. 231 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); 232 mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click(); 233 mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click(); 234 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 235 By.res(SETTINGS_PACKAGE, "proxy_pac")); 236 } 237 238 @Suppress 239 @MediumTest 240 public void testAddNetworkMenu_IpSettings() throws Exception { 241 loadAddNetworkMenu(); 242 243 // Toggle advanced options. 244 mDevice.wait(Until.findObject(By 245 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) 246 .clazz(CHECKBOX_CLASS)), TIMEOUT).click(); 247 248 // Verify IP settings defaults to DHCP. 249 BySelector ipSettingsBySelector = 250 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS); 251 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector); 252 assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT) 253 .getChildren().get(0).getText()); 254 255 // Verify that Static IP settings options appear. 256 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click(); 257 mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click(); 258 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 259 By.res(SETTINGS_PACKAGE, "ipaddress")); 260 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 261 By.res(SETTINGS_PACKAGE, "gateway")); 262 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 263 By.res(SETTINGS_PACKAGE, "network_prefix_length")); 264 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 265 By.res(SETTINGS_PACKAGE, "dns1")); 266 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 267 By.res(SETTINGS_PACKAGE, "dns2")); 268 } 269 270 @Suppress 271 @MediumTest 272 public void testPhase2Settings() throws Exception { 273 loadAddNetworkMenu(); 274 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 275 276 BySelector phase2SettingsBySelector = 277 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS); 278 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector); 279 assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until 280 .findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText()); 281 mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click(); 282 Thread.sleep(SLEEP_TIME); 283 284 // Verify Phase 2 authentication spinner options. 285 assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT)); 286 assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT)); 287 assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT)); 288 } 289 290 @Suppress 291 @MediumTest 292 public void testCaCertSettings() throws Exception { 293 loadAddNetworkMenu(); 294 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 295 296 BySelector caCertSettingsBySelector = 297 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS); 298 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector); 299 assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until 300 .findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText()); 301 mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click(); 302 Thread.sleep(SLEEP_TIME); 303 304 // Verify CA certificate spinner options. 305 assertNotNull(mDevice.wait(Until.findObject( 306 By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT)); 307 assertNotNull(mDevice.wait(Until.findObject( 308 By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT)); 309 assertNotNull(mDevice.wait(Until.findObject( 310 By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT)); 311 312 // Verify that a domain field and warning appear when the user selects the 313 // "Use system certificates" option. 314 mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click(); 315 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 316 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID)); 317 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 318 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID)); 319 320 // Verify that a warning appears when the user chooses the "Do Not Validate" option. 321 mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click(); 322 mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click(); 323 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 324 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID)); 325 } 326 327 @Suppress 328 @MediumTest 329 public void testAddNetwork_NoSecurity() throws Exception { 330 loadAddNetworkMenu(); 331 selectSecurityOption(SECURITY_OPTION_NONE_TEXT); 332 333 // Entering an SSID is enough to enable the submit button. // TODO THIS GUY 334 enterSSID(TEST_SSID); 335 assertTrue(mDevice.wait(Until 336 .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 337 } 338 339 @Suppress 340 @MediumTest 341 public void testAddNetwork_WEP() throws Exception { 342 loadAddNetworkMenu(); 343 selectSecurityOption(SECURITY_OPTION_WEP_TEXT); 344 assertFalse(mDevice.wait(Until.findObject( 345 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 346 347 // Verify that WEP fields appear. 348 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 349 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 350 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 351 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); 352 353 // Entering an SSID alone does not enable the submit button. 354 enterSSID(TEST_SSID); 355 assertFalse(mDevice.wait(Until.findObject( 356 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 357 358 // Submit button is only enabled after a password is entered. 359 enterPassword(TEST_PW_GE_8_CHAR); 360 assertTrue(mDevice.wait(Until 361 .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 362 } 363 364 @Suppress 365 @MediumTest 366 public void testAddNetwork_PSK() throws Exception { 367 loadAddNetworkMenu(); 368 selectSecurityOption(SECURITY_OPTION_PSK_TEXT); 369 assertFalse(mDevice.wait(Until.findObject( 370 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 371 372 // Verify that PSK fields appear. 373 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 374 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 375 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 376 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); 377 378 // Entering an SSID alone does not enable the submit button. 379 enterSSID(TEST_SSID); 380 assertFalse(mDevice.wait(Until.findObject( 381 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 382 383 // Entering an password that is too short does not enable submit button. 384 enterPassword(TEST_PW_LT_8_CHAR); 385 assertFalse(mDevice.wait(Until.findObject( 386 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 387 388 // Submit button is only enabled after a password of valid length is entered. 389 enterPassword(TEST_PW_GE_8_CHAR); 390 assertTrue(mDevice.wait(Until.findObject( 391 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 392 } 393 394 @Suppress 395 @MediumTest 396 public void testAddNetwork_EAP_PEAP() throws Exception { 397 loadAddNetworkMenu(); 398 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 399 assertFalse(mDevice.wait(Until.findObject( 400 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 401 402 selectEAPMethod(EAP_METHOD_PEAP_TEXT); 403 404 // Verify that EAP-PEAP fields appear. 405 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 406 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID)); 407 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 408 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); 409 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 410 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 411 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 412 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID)); 413 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 414 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 415 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 416 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); 417 418 // Entering an SSID alone does not enable the submit button. 419 enterSSID(TEST_SSID); 420 assertFalse(mDevice.wait(Until.findObject( 421 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 422 423 verifyCaCertificateSubmitConditions(); 424 } 425 426 @Suppress 427 @MediumTest 428 public void testAddNetwork_EAP_TLS() throws Exception { 429 loadAddNetworkMenu(); 430 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 431 assertFalse(mDevice.wait(Until.findObject( 432 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 433 434 selectEAPMethod(EAP_METHOD_TLS_TEXT); 435 436 // Verify that EAP-TLS fields appear. 437 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 438 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); 439 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 440 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID)); 441 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 442 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 443 444 // Entering an SSID alone does not enable the submit button. 445 enterSSID(TEST_SSID); 446 assertFalse(mDevice.wait(Until.findObject( 447 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 448 449 // Selecting the User certificate "Do not provide" option alone does not enable the submit 450 // button. 451 selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT); 452 assertFalse(mDevice.wait(Until.findObject( 453 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 454 455 verifyCaCertificateSubmitConditions(); 456 } 457 458 @Suppress 459 @MediumTest 460 public void testAddNetwork_EAP_TTLS() throws Exception { 461 loadAddNetworkMenu(); 462 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 463 assertFalse(mDevice.wait(Until.findObject( 464 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 465 466 selectEAPMethod(EAP_METHOD_TTLS_TEXT); 467 468 // Verify that EAP-TLS fields appear. 469 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 470 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID)); 471 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 472 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); 473 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 474 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 475 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 476 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID)); 477 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 478 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 479 480 // Entering an SSID alone does not enable the submit button. 481 enterSSID(TEST_SSID); 482 assertFalse(mDevice.wait(Until.findObject( 483 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 484 485 verifyCaCertificateSubmitConditions(); 486 } 487 488 @Suppress 489 @MediumTest 490 public void testAddNetwork_EAP_PWD() throws Exception { 491 loadAddNetworkMenu(); 492 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 493 assertFalse(mDevice.wait(Until.findObject( 494 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 495 496 selectEAPMethod(EAP_METHOD_PWD_TEXT); 497 498 // Verify that EAP-TLS fields appear. 499 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 500 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 501 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 502 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 503 504 // Entering an SSID alone enables the submit button. 505 enterSSID(TEST_SSID); 506 assertTrue(mDevice.wait(Until.findObject( 507 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 508 } 509 510 @Suppress 511 @MediumTest 512 public void testAddNetwork_EAP_SIM() throws Exception { 513 loadAddNetworkMenu(); 514 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 515 assertFalse(mDevice.wait(Until.findObject( 516 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 517 518 selectEAPMethod(EAP_METHOD_SIM_TEXT); 519 520 // Entering an SSID alone enables the submit button. 521 enterSSID(TEST_SSID); 522 assertTrue(mDevice.wait(Until.findObject( 523 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 524 } 525 526 @Suppress 527 @MediumTest 528 public void testAddNetwork_EAP_AKA() throws Exception { 529 loadAddNetworkMenu(); 530 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 531 assertFalse(mDevice.wait(Until.findObject( 532 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 533 534 selectEAPMethod(EAP_METHOD_AKA_TEXT); 535 536 // Entering an SSID alone enables the submit button. 537 enterSSID(TEST_SSID); 538 assertTrue(mDevice.wait(Until.findObject( 539 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 540 } 541 542 @Suppress 543 @MediumTest 544 public void testAddNetwork_EAP_AKA_PRIME() throws Exception { 545 loadAddNetworkMenu(); 546 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 547 assertFalse(mDevice.wait(Until.findObject( 548 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 549 550 selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT); 551 552 // Entering an SSID alone enables the submit button. 553 enterSSID(TEST_SSID); 554 assertTrue(mDevice.wait(Until.findObject( 555 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 556 } 557 558 private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue) 559 throws Exception { 560 loadWiFiConfigureMenu(); 561 mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT) 562 .click(); 563 mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView") 564 .text(settingToBeVerified)), TIMEOUT).click(); 565 Thread.sleep(SLEEP_TIME); 566 int keepWiFiOnSetting = 567 Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(), 568 Settings.Global.WIFI_SLEEP_POLICY); 569 assertEquals(settingValue, keepWiFiOnSetting); 570 } 571 572 private void verifyNetworkNotificationsOnOrOff(boolean verifyOn) 573 throws Exception { 574 // Enable network recommendations to enable the toggle switch for Network 575 // notifications 576 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 577 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1"); 578 if (verifyOn) { 579 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 580 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0"); 581 } 582 else { 583 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 584 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1"); 585 } 586 loadWiFiConfigureMenu(); 587 mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT) 588 .click(); 589 Thread.sleep(SLEEP_TIME); 590 String wifiNotificationValue = 591 Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), 592 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON); 593 if (verifyOn) { 594 assertEquals("1", wifiNotificationValue); 595 } 596 else { 597 assertEquals("0", wifiNotificationValue); 598 } 599 } 600 601 private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception { 602 String switchText = "On"; 603 if (verifyOn) { 604 switchText = "Off"; 605 } 606 loadWiFiSettingsPage(!verifyOn); 607 mDevice.wait(Until 608 .findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT) 609 .click(); 610 Thread.sleep(SLEEP_TIME); 611 String wifiValue = 612 Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), 613 Settings.Global.WIFI_ON); 614 if (verifyOn) { 615 // 1 is Enabled, 2 is Enabled while airplane mode is ON. 616 assertTrue(wifiValue.equals("1") || wifiValue.equals("2")); 617 } 618 else { 619 assertEquals("0", wifiValue); 620 } 621 } 622 623 private void verifyCaCertificateSubmitConditions() throws Exception { 624 // Selecting the CA certificate "Do not validate" option enables the submit button. 625 selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT); 626 assertTrue(mDevice.wait(Until.findObject( 627 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 628 629 // However, selecting the CA certificate "Use system certificates option" is not enough to 630 // enable the submit button. 631 selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT); 632 assertFalse(mDevice.wait(Until.findObject( 633 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 634 635 // Submit button is only enabled after a domain is entered as well. 636 enterDomain(TEST_DOMAIN); 637 assertTrue(mDevice.wait(Until.findObject( 638 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 639 } 640 641 private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception { 642 WifiManager wifiManager = (WifiManager)getInstrumentation().getContext() 643 .getSystemService(Context.WIFI_SERVICE); 644 wifiManager.setWifiEnabled(wifiEnabled); 645 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 646 Settings.ACTION_WIFI_SETTINGS); 647 } 648 649 private void loadWiFiConfigureMenu() throws Exception { 650 loadWiFiSettingsPage(false); 651 Thread.sleep(TIMEOUT); 652 mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click(); 653 mDevice.wait(Until.findObject( 654 By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click(); 655 } 656 657 private void loadAddNetworkMenu() throws Exception { 658 loadWiFiSettingsPage(true); 659 for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) { 660 try { 661 findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT)) 662 .click(); 663 } catch (StaleObjectException e) { 664 // The network list might have been updated between when the Add network button was 665 // found, and when it UI automator attempted to click on it. Retry. 666 continue; 667 } 668 // If we get here, we successfully clicked on the Add network button, so we are done. 669 Thread.sleep(SLEEP_TIME*5); 670 return; 671 } 672 673 fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS 674 + " retries"); 675 } 676 677 private void selectSecurityOption(String securityOption) throws Exception { 678 // We might not need to scroll to the security options if not enough add network menu 679 // options are visible. 680 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 681 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID) 682 .clazz(SPINNER_CLASS)).click(); 683 Thread.sleep(SLEEP_TIME); 684 mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click(); 685 } 686 687 private void selectEAPMethod(String eapMethod) throws Exception { 688 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 689 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS)) 690 .click(); 691 Thread.sleep(SLEEP_TIME); 692 findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click(); 693 } 694 695 private void selectUserCertificateOption(String userCertificateOption) throws Exception { 696 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 697 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS)) 698 .click(); 699 mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click(); 700 } 701 702 private void selectCaCertificateOption(String caCertificateOption) throws Exception { 703 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 704 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS)) 705 .click(); 706 mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click(); 707 } 708 709 private void enterSSID(String ssid) throws Exception { 710 // We might not need to scroll to the SSID option if not enough add network menu options 711 // are visible. 712 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 713 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS)) 714 .setText(ssid); 715 } 716 717 private void enterPassword(String password) throws Exception { 718 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 719 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS)) 720 .setText(password); 721 } 722 723 private void enterDomain(String domain) throws Exception { 724 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 725 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain); 726 } 727 728 // Use this if the UI object might or might not need to be scrolled to. 729 private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector) 730 throws Exception { 731 UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT); 732 if (object == null) { 733 object = scrollToObject(scrollableSelector, objectSelector); 734 } 735 return object; 736 } 737 738 private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector) 739 throws Exception { 740 UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT); 741 if (scrollable == null) { 742 fail("Could not find scrollable UI object identified by " + scrollableSelector); 743 } 744 UiObject2 found = null; 745 // Scroll all the way up first, then all the way down. 746 while (true) { 747 // Optimization: terminate if we find the object while scrolling up to reset, so 748 // we save the time spent scrolling down again. 749 boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT, 750 SCROLL_SPEED); 751 found = mDevice.findObject(objectSelector); 752 if (found != null) return found; 753 if (!canScrollAgain) break; 754 } 755 for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) { 756 // Return value of UiObject2.scroll() is not reliable, so do not use it in loop 757 // condition, in case it causes this loop to terminate prematurely. 758 scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED); 759 found = mDevice.findObject(objectSelector); 760 } 761 if (found == null) { 762 fail("Could not scroll to UI object identified by " + objectSelector); 763 } 764 return found; 765 } 766} 767