def _NavigateLogin(self): """Navigates through oobe login screen""" if self._use_oobe_login_for_testing: logging.info('Invoking Oobe.loginForTesting') assert self.oobe util.WaitFor( lambda: self.oobe.EvaluateJavaScript( 'typeof Oobe !== \'undefined\''), 10) if self.oobe.EvaluateJavaScript( 'typeof Oobe.loginForTesting == \'undefined\''): raise exceptions.LoginException( 'Oobe.loginForTesting js api missing') self.oobe.ExecuteJavaScript( 'Oobe.loginForTesting(\'%s\', \'%s\');' % (self._username, self._password)) try: util.WaitFor(self._IsLoggedIn, 60) except util.TimeoutException: self._cri.TakeScreenShot('login-screen') raise exceptions.LoginException( 'Timed out going through login screen') # Wait for extensions to load. self._WaitForBrowserToComeUp() if self.chrome_branch_number < 1500: # Wait for the startup window, then close it. Startup window doesn't exist # post-M27. crrev.com/197900 util.WaitFor(self._StartupWindow, 20).Close() else: # Open a new window/tab. self.tab_list_backend.New(15)
def _NavigateLogin(self): """Navigates through oobe login screen""" if self._use_oobe_login_for_testing: logging.info('Invoking Oobe.loginForTesting') if not self.oobe_exists: raise exceptions.LoginException('Oobe missing') oobe = self.oobe util.WaitFor( lambda: oobe.EvaluateJavaScript('typeof Oobe !== \'undefined\'' ), 10) if oobe.EvaluateJavaScript( 'typeof Oobe.loginForTesting == \'undefined\''): raise exceptions.LoginException( 'Oobe.loginForTesting js api missing') oobe.ExecuteJavaScript( 'Oobe.loginForTesting(\'%s\', \'%s\');' % (self.browser_options.username, self.browser_options.password)) try: util.WaitFor(self._IsLoggedIn, 60) except util.TimeoutException: self._cri.TakeScreenShot('login-screen') raise exceptions.LoginException( 'Timed out going through login screen') # Wait for extensions to load. try: self._WaitForBrowserToComeUp() except util.TimeoutException: logging.error('Chrome args: %s' % self._GetChromeProcess()['args']) self._cri.TakeScreenShot('extension-timeout') raise if self.chrome_branch_number < 1500: # Wait for the startup window, then close it. Startup window doesn't exist # post-M27. crrev.com/197900 util.WaitFor(self._StartupWindow, 20).Close() else: # Workaround for crbug.com/329271, crbug.com/334726. retries = 3 while not len(self.tab_list_backend): try: # Open a new window/tab. tab = self.tab_list_backend.New(timeout=30) tab.Navigate('about:blank', timeout=10) except (exceptions.TabCrashException, util.TimeoutException, IndexError): retries -= 1 logging.warn('TabCrashException/TimeoutException in ' 'new tab creation/navigation, ' 'remaining retries %d' % retries) if not retries: raise
def _WaitForLogin(self): try: util.WaitFor(self._IsLoggedIn, 60) except util.TimeoutException: self._cri.TakeScreenShot('login-screen') raise exceptions.LoginException( 'Timed out going through login screen') # Wait for extensions to load. try: self._WaitForBrowserToComeUp() except util.TimeoutException: logging.error('Chrome args: %s' % self._GetChromeProcess()['args']) self._cri.TakeScreenShot('extension-timeout') raise # Workaround for crbug.com/329271, crbug.com/334726. retries = 3 while True: try: # Open a new window/tab. tab = self.tab_list_backend.New(timeout=30) tab.Navigate('about:blank', timeout=10) break except (exceptions.TabCrashException, util.TimeoutException, IndexError): retries -= 1 logging.warn('TabCrashException/TimeoutException in ' 'new tab creation/navigation, ' 'remaining retries %d' % retries) if not retries: raise
def _NavigateGuestLogin(self): """Navigates through oobe login screen as guest""" if not self.oobe_exists: raise exceptions.LoginException('Oobe missing') self._WaitForSigninScreen() self._ClickBrowseAsGuest() self._WaitForGuestFsMounted()
def Start(self): # Escape all commas in the startup arguments we pass to Chrome # because dbus-send delimits array elements by commas startup_args = [ a.replace(',', '\\,') for a in self.GetBrowserStartupArgs() ] # Restart Chrome with the login extension and remote debugging. logging.info('Restarting Chrome with flags and login') args = [ 'dbus-send', '--system', '--type=method_call', '--dest=org.chromium.SessionManager', '/org/chromium/SessionManager', 'org.chromium.SessionManagerInterface.EnableChromeTesting', 'boolean:true', 'array:string:"%s"' % ','.join(startup_args) ] self._cri.RunCmdOnDevice(args) if not self._cri.local: self._port = util.GetUnreservedAvailableLocalPort() self._forwarder = self.forwarder_factory.Create( forwarders.PortPairs(http=forwarders.PortPair( self._port, self._remote_debugging_port), https=None, dns=None), forwarding_flag='L') try: self._WaitForBrowserToComeUp(wait_for_extensions=False) self._PostBrowserStartupInitialization() except: import traceback traceback.print_exc() self.Close() raise # chrome_branch_number is set in _PostBrowserStartupInitialization. # Without --skip-hwid-check (introduced in crrev.com/203397), devices/VMs # will be stuck on the bad hwid screen. if self.chrome_branch_number <= 1500 and not self.hwid: raise exceptions.LoginException( 'Hardware id not set on device/VM. --skip-hwid-check not supported ' 'with chrome branches 1500 or earlier.') util.WaitFor(lambda: self.oobe_exists, 10) if self.browser_options.auto_login: if self._is_guest: pid = self.pid self._NavigateGuestLogin() # Guest browsing shuts down the current browser and launches an # incognito browser in a separate process, which we need to wait for. util.WaitFor(lambda: pid != self.pid, 10) self._WaitForBrowserToComeUp() else: self._NavigateLogin() logging.info('Browser is up!')
def Start(self): # Escape all commas in the startup arguments we pass to Chrome # because dbus-send delimits array elements by commas startup_args = [ a.replace(',', '\\,') for a in self.GetBrowserStartupArgs() ] # Restart Chrome with the login extension and remote debugging. logging.info('Restarting Chrome with flags and login') args = [ 'dbus-send', '--system', '--type=method_call', '--dest=org.chromium.SessionManager', '/org/chromium/SessionManager', 'org.chromium.SessionManagerInterface.EnableChromeTesting', 'boolean:true', 'array:string:"%s"' % ','.join(startup_args) ] self._cri.RunCmdOnDevice(args) if not self._cri.local: # TODO(crbug.com/404771): Move port forwarding to network_controller. self._port = util.GetUnreservedAvailableLocalPort() self._forwarder = self._platform_backend.forwarder_factory.Create( forwarders.PortPairs(http=forwarders.PortPair( self._port, self._remote_debugging_port), https=None, dns=None), use_remote_port_forwarding=False) # Wait for oobe. self._WaitForBrowserToComeUp() self._InitDevtoolsClientBackend( remote_devtools_port=self._remote_debugging_port) util.WaitFor(lambda: self.oobe_exists, 30) if self.browser_options.auto_login: try: if self._is_guest: pid = self.pid self.oobe.NavigateGuestLogin() # Guest browsing shuts down the current browser and launches an # incognito browser in a separate process, which we need to wait for. util.WaitFor(lambda: pid != self.pid, 10) elif self.browser_options.gaia_login: self.oobe.NavigateGaiaLogin(self._username, self._password) else: self.oobe.NavigateFakeLogin( self._username, self._password, self._gaia_id, not self.browser_options.disable_gaia_services) self._WaitForLogin() except exceptions.TimeoutException: self._cri.TakeScreenshotWithPrefix('login-screen') raise exceptions.LoginException( 'Timed out going through login screen. ' + self._GetLoginStatus()) logging.info('Browser is up!')
def _ExecuteOobeApi(self, api, *args): logging.info('Invoking %s' % api) self.WaitForJavaScriptExpression("typeof Oobe == 'function'", 20) if self.EvaluateJavaScript("typeof %s == 'undefined'" % api): raise exceptions.LoginException('%s js api missing' % api) js = api + '(' + ("'%s'," * len(args)).rstrip(',') + ');' self.ExecuteJavaScript(js % args)
def _ExecuteOobeApi(self, api, *args): logging.info('Invoking %s' % api) util.WaitFor( lambda: self.EvaluateJavaScript("typeof Oobe !== 'undefined'"), 10) if self.EvaluateJavaScript("typeof %s == 'undefined'" % api): raise exceptions.LoginException('%s js api missing' % api) js = api + '(' + ("'%s'," * len(args)).rstrip(',') + ');' self.ExecuteJavaScript(js % args)
def _WaitForSigninScreen(self): """Waits for oobe to be on the signin or account picker screen.""" def OnAccountPickerScreen(): signin_state = self._SigninUIState() # GAIA_SIGNIN or ACCOUNT_PICKER screens. return signin_state == 1 or signin_state == 2 try: util.WaitFor(OnAccountPickerScreen, 60) except util.TimeoutException: self._cri.TakeScreenShot('guest-screen') raise exceptions.LoginException('Timed out waiting for signin screen, ' 'signin state %d' % self._SigninUIState())
def _ExecuteOobeApi(self, api, *args): logging.info('Invoking %s' % api) self.WaitForJavaScriptCondition2("typeof Oobe == 'function'", timeout=120) if self.EvaluateJavaScript2( "typeof {{ @api }} == 'undefined'", api=api): raise exceptions.LoginException('%s js api missing' % api) # Example values: # |api|: 'doLogin' # |args|: ['username', 'pass', True] # Executes: 'doLogin("username", "pass", true)' self.ExecuteJavaScript2('{{ @f }}({{ *args }})', f=api, args=args)
def _ExecuteOobeApi(self, api, *args): logging.info('Invoking %s' % api) self.WaitForJavaScriptExpression("typeof Oobe == 'function'", 120) if self.EvaluateJavaScript("typeof %s == 'undefined'" % api): raise exceptions.LoginException('%s js api missing' % api) # Example values: # |api|: 'doLogin' # |args|: ['username', 'pass', True] # js: '{}({},{},{})' # js.format(...): 'doLogin("username","pass",true)' js = '{}(' + ('{},' * len(args)).rstrip(',') + ')' self.ExecuteJavaScript(js.format(api, *map(json.dumps, args)))
def _NavigateFakeLogin(self): """Logs in using Oobe.loginForTesting.""" logging.info('Invoking Oobe.loginForTesting') oobe = self.oobe util.WaitFor( lambda: oobe.EvaluateJavaScript('typeof Oobe !== \'undefined\''), 10) if oobe.EvaluateJavaScript( 'typeof Oobe.loginForTesting == \'undefined\''): raise exceptions.LoginException( 'Oobe.loginForTesting js api missing') oobe.ExecuteJavaScript( 'Oobe.loginForTesting(\'%s\', \'%s\');' % (self.browser_options.username, self.browser_options.password)) self._WaitForLogin()
def NavigateLogin(browser_backend, cri): """Navigates through oobe login screen""" # Dismiss the user image selection screen. try: util.WaitFor(lambda: _IsLoggedIn(browser_backend, cri), 30) except util.TimeoutException: raise exceptions.LoginException( 'Timed out going through oobe screen. Make sure the custom auth ' 'extension passed through --auth-ext-path is valid and belongs ' 'to user "chronos".') if browser_backend.chrome_branch_number < 1500: # Wait for the startup window, then close it. Startup window doesn't exist # post-M27. crrev.com/197900 util.WaitFor(lambda: _StartupWindow(browser_backend) is not None, 20) _StartupWindow(browser_backend).Close() else: # Open a new window/tab. browser_backend.tab_list_backend.New(15)
def _NavigateLogin(self): """Navigates through oobe login screen""" # Dismiss the user image selection screen. try: util.WaitFor(lambda: self._IsLoggedIn(), 60) # pylint: disable=W0108 except util.TimeoutException: self._cri.TakeScreenShot('login-screen') raise exceptions.LoginException( 'Timed out going through oobe screen. Make sure the custom auth ' 'extension passed through --auth-ext-path is valid and belongs ' 'to user "chronos".') if self.chrome_branch_number < 1500: # Wait for the startup window, then close it. Startup window doesn't exist # post-M27. crrev.com/197900 util.WaitFor(lambda: self._StartupWindow() is not None, 20) self._StartupWindow().Close() else: # Open a new window/tab. self.tab_list_backend.New(15)
def _RaiseOnLoginFailure(self, error): if self._platform_backend.CanTakeScreenshot(): self._cri.TakeScreenshotWithPrefix('login-screen') raise exceptions.LoginException(error)
def __init__(self, browser_type, options, cri, is_guest): super(CrOSBrowserBackend, self).__init__(is_content_shell=False, supports_extensions=not is_guest, options=options) # Initialize fields so that an explosion during init doesn't break in Close. self._browser_type = browser_type self._options = options self._cri = cri self._is_guest = is_guest self._remote_debugging_port = self._cri.GetRemotePort() self._port = self._remote_debugging_port self._login_ext_dir = os.path.join(os.path.dirname(__file__), 'chromeos_login_ext') # Push a dummy login extension to the device. # This extension automatically logs in as [email protected] # Note that we also perform this copy locally to ensure that # the owner of the extensions is set to chronos. logging.info('Copying dummy login extension to the device') cri.PushFile(self._login_ext_dir, '/tmp/') self._login_ext_dir = '/tmp/chromeos_login_ext' cri.RunCmdOnDevice(['chown', '-R', 'chronos:chronos', self._login_ext_dir]) # Copy extensions to temp directories on the device. # Note that we also perform this copy locally to ensure that # the owner of the extensions is set to chronos. for e in options.extensions_to_load: output = cri.RunCmdOnDevice(['mktemp', '-d', '/tmp/extension_XXXXX']) extension_dir = output[0].rstrip() cri.PushFile(e.path, extension_dir) cri.RunCmdOnDevice(['chown', '-R', 'chronos:chronos', extension_dir]) e.local_path = os.path.join(extension_dir, os.path.basename(e.path)) # Ensure the UI is running and logged out. self._RestartUI() util.WaitFor(lambda: self.IsBrowserRunning(), 20) # pylint: disable=W0108 # Delete [email protected]'s cryptohome vault (user data directory). if not options.dont_override_profile: logging.info('Deleting user\'s cryptohome vault (the user data dir)') self._cri.RunCmdOnDevice( ['cryptohome', '--action=remove', '--force', '[email protected]']) if options.profile_dir: profile_dir = '/home/chronos/Default' cri.RunCmdOnDevice(['rm', '-rf', profile_dir]) cri.PushFile(options.profile_dir + '/Default', profile_dir) cri.RunCmdOnDevice(['chown', '-R', 'chronos:chronos', profile_dir]) # Escape all commas in the startup arguments we pass to Chrome # because dbus-send delimits array elements by commas startup_args = [a.replace(',', '\\,') for a in self.GetBrowserStartupArgs()] # Restart Chrome with the login extension and remote debugging. logging.info('Restarting Chrome with flags and login') args = ['dbus-send', '--system', '--type=method_call', '--dest=org.chromium.SessionManager', '/org/chromium/SessionManager', 'org.chromium.SessionManagerInterface.EnableChromeTesting', 'boolean:true', 'array:string:"%s"' % ','.join(startup_args)] cri.RunCmdOnDevice(args) if not cri.local: # Find a free local port. self._port = util.GetAvailableLocalPort() # Forward the remote debugging port. logging.info('Forwarding remote debugging port') self._forwarder = SSHForwarder( cri, 'L', util.PortPair(self._port, self._remote_debugging_port)) # Wait for the browser to come up. logging.info('Waiting for browser to be ready') try: self._WaitForBrowserToComeUp() self._PostBrowserStartupInitialization() except: import traceback traceback.print_exc() self.Close() raise # chrome_branch_number is set in _PostBrowserStartupInitialization. # Without --skip-hwid-check (introduced in crrev.com/203397), devices/VMs # will be stuck on the bad hwid screen. if self.chrome_branch_number <= 1500 and not self.hwid: raise exceptions.LoginException( 'Hardware id not set on device/VM. --skip-hwid-check not supported ' 'with chrome branches 1500 or earlier.') if self._is_guest: pid = self.pid cros_util.NavigateGuestLogin(self, cri) # Guest browsing shuts down the current browser and launches an incognito # browser in a separate process, which we need to wait for. util.WaitFor(lambda: pid != self.pid, 10) self._WaitForBrowserToComeUp() else: cros_util.NavigateLogin(self, cri) logging.info('Browser is up!')