Home | History | Annotate | Download | only in functional
      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