1 #!/usr/bin/env python 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 import os 7 import subprocess 8 import sys 9 10 import pyauto_functional # Must be imported before pyauto 11 import pyauto 12 import pyauto_errors 13 import test_utils 14 15 16 sys.path.append('/usr/local') # To make autotest libs importable. 17 from autotest.cros import cros_ui 18 from autotest.cros import cryptohome 19 20 21 class ChromeosLogin(pyauto.PyUITest): 22 """TestCases for Logging into ChromeOS.""" 23 24 assert os.geteuid() == 0, 'Need to run this test as root' 25 26 def ShouldAutoLogin(self): 27 return False 28 29 def setUp(self): 30 # We want a clean session_manager instance for every run, 31 # so restart ui now. 32 cros_ui.stop(allow_fail=True) 33 cryptohome.remove_all_vaults() 34 cros_ui.start(wait_for_login_prompt=False) 35 pyauto.PyUITest.setUp(self) 36 37 def _ValidCredentials(self, account_type='test_google_account'): 38 """Obtains a valid username and password from a data file. 39 40 Returns: 41 A dictionary with the keys 'username' and 'password' 42 """ 43 return self.GetPrivateInfo()[account_type] 44 45 def testExecuteJavascriptInOOBEWebUI(self): 46 """Test that javascript can be executed at the login page.""" 47 msg = 'test success' 48 ret = self.ExecuteJavascriptInOOBEWebUI( 49 'window.domAutomationController.send("%s");' % msg) 50 self.assertEqual(ret, msg) 51 52 def testGoodLogin(self): 53 """Test that login is successful with valid credentials.""" 54 credentials = self._ValidCredentials() 55 self.Login(credentials['username'], credentials['password']) 56 login_info = self.GetLoginInfo() 57 self.assertTrue(login_info['is_logged_in'], msg='Login failed.') 58 59 def testBadUsername(self): 60 """Test that login fails when passed an invalid username.""" 61 self.assertRaises( 62 pyauto_errors.JSONInterfaceError, 63 lambda: self.Login('doesnotexist (at] fakedomain.org', 'badpassword')) 64 login_info = self.GetLoginInfo() 65 self.assertFalse(login_info['is_logged_in'], 66 msg='Login succeeded, with bad credentials.') 67 68 def testBadPassword(self): 69 """Test that login fails when passed an invalid password.""" 70 credentials = self._ValidCredentials() 71 self.assertRaises( 72 pyauto_errors.JSONInterfaceError, 73 lambda: self.Login(credentials['username'], 'badpassword')) 74 login_info = self.GetLoginInfo() 75 self.assertFalse(login_info['is_logged_in'], 76 msg='Login succeeded, with bad credentials.') 77 78 def testLoginAsGuest(self): 79 """Test we can login with guest mode.""" 80 self.LoginAsGuest() 81 login_info = self.GetLoginInfo() 82 self.assertTrue(login_info['is_logged_in'], msg='Not logged in at all.') 83 self.assertTrue(login_info['is_guest'], msg='Not logged in as guest.') 84 85 def testLockScreenAfterLogin(self): 86 """Test after logging in that the screen can be locked.""" 87 self.testGoodLogin() 88 self.assertFalse(self.GetLoginInfo()['is_screen_locked'], 89 msg='Screen is locked, but the screen was not locked.') 90 self.LockScreen() 91 login_info = self.GetLoginInfo() 92 self.assertTrue(login_info['is_screen_locked'], msg='The screen is not ' 93 'locked after attempting to lock the screen.') 94 95 def testLockAndUnlockScreenAfterLogin(self): 96 """Test locking and unlocking the screen after logging in.""" 97 self.testLockScreenAfterLogin() 98 self.UnlockScreen(self._ValidCredentials()['password']) 99 login_info = self.GetLoginInfo() 100 self.assertFalse(login_info['is_screen_locked'], 101 msg='Screen is locked, but it should have been unlocked.') 102 103 def testLockAndUnlockScreenAfterLoginWithBadPassword(self): 104 """Test locking and unlocking the screen with the wrong password.""" 105 self.testLockScreenAfterLogin() 106 self.UnlockScreen('not_the_right_password') 107 login_info = self.GetLoginInfo() 108 self.assertTrue(login_info['is_screen_locked'], 109 msg='Screen is unlock, but it should have been unlocked ' 110 'since we attempted to unlock with a bad password') 111 112 def testLoginToCreateNewAccount(self): 113 """Test we can login as a guest and create a new account.""" 114 self.ShowCreateAccountUI() 115 # The login hook does not wait for the first tab to load, so we wait here. 116 self.assertTrue( 117 self.WaitUntil(self.GetActiveTabTitle, expect_retval='Google Accounts'), 118 msg='Could not verify that the Accounts tab was opened.') 119 login_info = self.GetLoginInfo() 120 self.assertTrue(login_info['is_guest'], msg='Not logged in as guest.') 121 122 def testGoodLoginForTransitionedDomainAccount(self): 123 """Test that login is successful with valid credentials for a domain. 124 125 ChromeOS only allows GA+ accounts to login, there are also known as 126 transitioned accounts. 127 128 """ 129 credentials = self._ValidCredentials(account_type='test_domain_account') 130 self.Login(credentials['username'], credentials['password']) 131 login_info = self.GetLoginInfo() 132 self.assertTrue(login_info['is_logged_in'], msg='Login failed.') 133 134 def testNavigateAfterLogin(self): 135 """Test that page navigation is successful after logging in.""" 136 self.testGoodLogin() 137 self.NavigateToURL("http://www.google.com") 138 self.assertEqual(self.GetActiveTabTitle(), 'Google', 139 msg='Unable to navigate to Google and verify tab title.') 140 141 def testSigningOutFromLockedScreen(self): 142 """Test logout can be performed from the lock screen.""" 143 self.testLockScreenAfterLogin() 144 self.SignoutInScreenLocker() 145 self.assertFalse(self.GetLoginInfo()['is_logged_in'], 146 msg='Still logged in when we should be logged out.') 147 148 def testLoginSequenceSanity(self): 149 """Test that the interface can maintain a connection after multiple logins. 150 151 This test is to verify the stability of the automation interface. 152 153 """ 154 self.testGoodLogin() 155 self.Logout() 156 self.testBadPassword() 157 self.testLoginAsGuest() 158 self.Logout() 159 self.testLoginToCreateNewAccount() 160 161 def testLogoutWithNoWindows(self): 162 """Verify logout when no browser windows are present.""" 163 self.testGoodLogin() 164 for i in range(5): 165 self.OpenNewBrowserWindow(True) 166 for _ in range(self.GetBrowserWindowCount()): 167 self.CloseBrowserWindow(0) 168 self.assertEqual(0, self.GetBrowserWindowCount(), 169 msg='Could not close all browser windows') 170 self.Logout() 171 self.testGoodLogin() 172 173 def testInitialLoginState(self): 174 """Verify basic state of browser windows at initial login.""" 175 self.testGoodLogin() 176 # Should have 1 browser window with 1 tab. 177 info = self.GetBrowserInfo() 178 self.assertEqual(1, len(info['windows'])) 179 self.assertFalse(info['windows'][0]['incognito'], 180 msg='Did not expect incognito window after login') 181 self.assertEqual(1, len(info['windows'][0]['tabs'])) 182 183 self.OpenNewBrowserWindow(True) 184 # Should have 2 regular browser windows. 185 info = self.GetBrowserInfo() 186 self.assertEqual(2, len(info['windows'])) 187 self.assertFalse(info['windows'][0]['incognito']) 188 self.assertFalse(info['windows'][1]['incognito'], 189 msg='Expected a regular new window.') 190 191 def testProfilePreservedBetweenLogins(self): 192 """Verify that profile is preserved between two login sessions. 193 194 Also verify Local State. 195 """ 196 self.testGoodLogin() 197 198 # Build up some history and setup state in "Local State". 199 url = self.GetHttpURLForDataPath('title2.html') 200 self.NavigateToURL(url) 201 # chromeos often takes a while to register URLs into history. 202 self.assertTrue(self.WaitUntil(lambda: self.GetHistoryInfo().History()), 203 msg='Could not open %s successfully' % url) 204 open('/home/chronos/__magic__', 'w').close() 205 open('/home/chronos/user/__magic__', 'w').close() 206 207 def _VerifyProfile(): 208 history = self.GetHistoryInfo().History() 209 self.assertEqual(1, len(history)) 210 self.assertEqual(url, history[0]['url']) 211 self.assertTrue(os.path.exists('/home/chronos/__magic__'), 212 msg='/home/chronos/__magic__ did not persist across login sessions') 213 self.assertTrue(os.path.exists('/home/chronos/user/__magic__'), 214 msg='/home/chronos/user/__magic__ did not persist across ' 215 'login sessions') 216 217 _VerifyProfile() 218 self.Logout() 219 self.testGoodLogin() # Re-login with same account. 220 _VerifyProfile() 221 222 def testGuestCrosh(self): 223 """Verify we can use crosh in guest mode.""" 224 self.LoginAsGuest() 225 login_info = self.GetLoginInfo() 226 self.assertTrue(login_info['is_logged_in'], msg='Not logged in at all.') 227 self.assertTrue(login_info['is_guest'], msg='Not logged in as guest.') 228 for _ in range(self.GetBrowserWindowCount()): 229 self.CloseBrowserWindow(0) 230 test_utils.OpenCroshVerification(self) 231 232 # Verify crosh prompt. 233 self.WaitForHtermText(text='crosh> ', 234 msg='Could not find "crosh> " prompt') 235 self.assertTrue( 236 self.GetHtermRowsText(start=0, end=2).endswith('crosh> '), 237 msg='Could not find "crosh> " prompt') 238 239 # Run a crosh command. 240 self.SendKeysToHterm('help\\n') 241 self.WaitForHtermText(text='help_advanced', 242 msg='Could not find "help_advanced" in help output.') 243 244 # Exit crosh and close tab. 245 self.SendKeysToHterm('exit\\n') 246 self.WaitForHtermText(text='command crosh completed with exit code 0', 247 msg='Could not exit crosh.') 248 249 def testCroshPreservedBetweenLogins(self): 250 """Verify user can continue after re-login.""" 251 self.testGoodLogin() 252 self.CloseBrowserWindow(0) 253 test_utils.OpenCroshVerification(self) 254 255 # Verify crosh prompt. 256 self.WaitForHtermText(text='crosh> ', 257 msg='Could not find "crosh> " prompt') 258 self.assertTrue( 259 self.GetHtermRowsText(start=0, end=2).endswith('crosh> '), 260 msg='Could not find "crosh> " prompt') 261 262 # Open 2 other tabs. 263 self.AppendTab(self.GetHttpURLForDataPath('title2.html')) 264 self.assertEqual('Title Of Awesomeness', self.GetActiveTabTitle(), 265 msg='Unable to naviage to title2.html and ' 266 'verify tab title.') 267 self.AppendTab(self.GetHttpURLForDataPath('settings', 'image_page.html')) 268 self.assertEqual('Show an image', self.GetActiveTabTitle(), 269 msg='Unable to navigate to image_page and ' 270 'verify tab title.') 271 self.Logout() 272 self.testGoodLogin() # Re-Login with same account. 273 274 # Verify 3 tabs are still open after re-login. 275 self.assertEqual(3, len(self.GetBrowserInfo()['windows'][0]['tabs'])) 276 277 278 class ChromeosLoginCachedCredentialsAddUser(pyauto.PyUITest): 279 """TestCase for failing to add a user with invalid proxy settings.""" 280 assert os.geteuid() == 0, 'Need to run this test as root' 281 282 def ShouldAutoLogin(self): 283 return False 284 285 def setUp(self): 286 # We want a clean session_manager instance for every run, 287 # so restart ui now. 288 cros_ui.stop(allow_fail=True) 289 cryptohome.remove_all_vaults() 290 cros_ui.start(wait_for_login_prompt=False) 291 pyauto.PyUITest.setUp(self) 292 293 def tearDown(self): 294 self.ResetProxySettingsOnChromeOS() 295 pyauto.PyUITest.tearDown(self) 296 297 def _ValidCredentials(self, account_type='test_google_account'): 298 """Obtains a valid username and password from a data file. 299 300 Returns: 301 A dictionary with the keys 'username' and 'password' 302 """ 303 return self.GetPrivateInfo()[account_type] 304 305 def testCachedCredentialsAddUser(self): 306 self.SetSharedProxies(True) 307 proxy_config = { 308 'mode': 'fixed_servers', 309 'server': '127.0.0.1' 310 } 311 self.SetProxySettingOnChromeOS(proxy_config); 312 313 """Test that login fails.""" 314 credentials = self._ValidCredentials() 315 self.assertRaises( 316 pyauto_errors.JSONInterfaceError, 317 lambda: self.Login(credentials['username'], 318 credentials['password']) 319 ) 320 321 class ChromeosLoginCachedCredentialsUserPod(ChromeosLogin): 322 """TestCase for Logging into ChromeOS with cached credentials and 323 invalid proxy settings. 324 """ 325 assert os.geteuid() == 0, 'Need to run this test as root' 326 327 def ShouldAutoLogin(self): 328 return False 329 330 def setUp(self): 331 # We want a clean session_manager instance for every run, 332 # so restart ui now. 333 cros_ui.stop(allow_fail=True) 334 cryptohome.remove_all_vaults() 335 cros_ui.start(wait_for_login_prompt=False) 336 pyauto.PyUITest.setUp(self) 337 338 def tearDown(self): 339 self.ResetProxySettingsOnChromeOS() 340 pyauto.PyUITest.tearDown(self) 341 342 def _ValidCredentials(self, account_type='test_google_account'): 343 """Obtains a valid username and password from a data file. 344 345 Returns: 346 A dictionary with the keys 'username' and 'password' 347 """ 348 return self.GetPrivateInfo()[account_type] 349 350 def testCachedCredentialsUserPod(self): 351 """Test that we can login without connectivity if we have so before. 352 353 This test is currently disabled because testGoodLogin tries to 354 add a user after setting proxies, which is supposed to fail. To 355 make it pass we need a hook that simply calls Login on the delegate 356 in webui_login_display.cc ::ShowSigninScreenForCreds. 357 """ 358 self.testGoodLogin() 359 self.Logout() 360 self.SetSharedProxies(True) 361 proxy_config = { 362 'mode': 'fixed_servers', 363 'server': '127.0.0.1' 364 } 365 self.SetProxySettingOnChromeOS(proxy_config); 366 self.testGoodLogin() 367 self.ResetProxySettingsOnChromeOS() 368 369 370 if __name__ == '__main__': 371 pyauto_functional.Main() 372