diff options
Diffstat (limited to 'chrome/test/pyautolib/chromoting.py')
-rw-r--r-- | chrome/test/pyautolib/chromoting.py | 457 |
1 files changed, 55 insertions, 402 deletions
diff --git a/chrome/test/pyautolib/chromoting.py b/chrome/test/pyautolib/chromoting.py index d9e439f..c608bb7 100644 --- a/chrome/test/pyautolib/chromoting.py +++ b/chrome/test/pyautolib/chromoting.py @@ -2,14 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Includes different methods to drive chromoting UI.""" - import os -import subprocess -import sys -import time - -from pyauto_errors import JSONInterfaceError class ChromotingMixIn(object): @@ -28,52 +21,30 @@ class ChromotingMixIn(object): """ def _ExecuteJavascript(self, command, tab_index, windex): - """Helper that returns immediately after running a Javascript command. - """ - try: - self.ExecuteJavascript( - '%s; window.domAutomationController.send("done");' % command, - tab_index, windex) - return True - except JSONInterfaceError: - print '_ExecuteJavascript threw JSONInterfaceError' - return False + """Helper that returns immediately after running a Javascript command.""" + return self.ExecuteJavascript( + '%s; window.domAutomationController.send("done");' % command, + tab_index, windex) def _WaitForJavascriptCondition(self, condition, tab_index, windex): """Waits until the Javascript condition is true. This is different from a naive self.WaitUntil(lambda: self.GetDOMValue()) because it uses Javascript to check the condition instead of Python. - - Returns: True if condition is satisfied or otherwise False. """ - try: - return self.WaitUntil(lambda: self.GetDOMValue( - '(%s) ? "1" : ""' % condition, tab_index, windex)) - except JSONInterfaceError: - print '_WaitForJavascriptCondition threw JSONInterfaceError' - return False + return self.WaitUntil(lambda: self.GetDOMValue( + '(%s) ? "1" : ""' % condition, tab_index, windex)) def _ExecuteAndWaitForMode(self, command, mode, tab_index, windex): - """ Executes JavaScript and wait for remoting app mode equal to - the given mode. - - Returns: True if condition is satisfied or otherwise False. - """ - if not self._ExecuteJavascript(command, tab_index, windex): - return False + self.assertTrue(self._ExecuteJavascript(command, tab_index, windex), + 'Javascript command did not return anything.') return self._WaitForJavascriptCondition( 'remoting.currentMode == remoting.AppMode.%s' % mode, tab_index, windex) def _ExecuteAndWaitForMajorMode(self, command, mode, tab_index, windex): - """ Executes JavaScript and wait for remoting app major mode equal to - the given mode. - - Returns: True if condition is satisfied or otherwise False. - """ - if not self._ExecuteJavascript(command, tab_index, windex): - return False + self.assertTrue(self._ExecuteJavascript(command, tab_index, windex), + 'Javascript command did not return anything.') return self._WaitForJavascriptCondition( 'remoting.getMajorMode() == remoting.AppMode.%s' % mode, tab_index, windex) @@ -85,44 +56,24 @@ class ChromotingMixIn(object): """ return os.path.join(self.BrowserPath(), 'remoting', 'remoting.webapp') - def _GetHelperRunner(self): - """Returns the python binary name that runs chromoting_helper.py.""" - if sys.platform.startswith('win'): - return 'python' - else: - return 'suid-python' - - def _GetHelper(self): - """Get chromoting_helper.py.""" - return os.path.join('chrome', 'test', 'pyautolib', 'chromoting_helper.py') - - def InstallHostDaemon(self): - """Installs the host daemon.""" - subprocess.call([self._GetHelperRunner(), self._GetHelper(), - 'install', self.BrowserPath()]) + def Authenticate(self, email=None, password=None, otp=None, + tab_index=1, windex=0): + """Logs a user in for Chromoting and accepts permissions for the app. - def UninstallHostDaemon(self): - """Uninstalls the host daemon.""" - subprocess.call([self._GetHelperRunner(), self._GetHelper(), - 'uninstall', self.BrowserPath()]) + PyAuto tests start with a clean profile, so Chromoting tests should call + this for every run after launching the app. If email or password is omitted, + the user can type it into the browser window manually. - def ContinueAuth(self, tab_index=1, windex=0): - """Starts authentication.""" + Raises: + AssertionError if the authentication flow changes or + the credentials are incorrect. + """ self.assertTrue( self._WaitForJavascriptCondition('window.remoting && remoting.oauth2', tab_index, windex), msg='Timed out while waiting for remoting app to finish loading.') self._ExecuteJavascript('remoting.oauth2.doAuthRedirect();', tab_index, windex) - - def SignIn(self, email=None, password=None, otp=None, - tab_index=1, windex=0): - """Logs a user in. - - PyAuto tests start with a clean profile, so Chromoting tests should call - this for every run after launching the app. If email or password is - omitted, the user can type it into the browser window manually. - """ self.assertTrue( self._WaitForJavascriptCondition('document.getElementById("signIn")', tab_index, windex), @@ -144,10 +95,10 @@ class ChromotingMixIn(object): 'document.getElementById("smsVerifyPin")', tab_index, windex), msg='Invalid username or password.') - self._ExecuteJavascript( - 'document.getElementById("smsUserPin").value = "%s";' - 'document.getElementById("smsVerifyPin").click();' % otp, - tab_index, windex) + self._ExecuteJavascript('document.getElementById("smsUserPin").value = ' + '"%s";' + 'document.getElementById("smsVerifyPin").click();' + % otp, tab_index, windex) # If the account adder screen appears, then skip it. self.assertTrue( @@ -161,14 +112,12 @@ class ChromotingMixIn(object): '{ document.getElementById("skip").click(); }', tab_index, windex) - def AllowAccess(self, tab_index=1, windex=0): - """Allows access to chromoting webapp.""" # Approve access. self.assertTrue( self._WaitForJavascriptCondition( 'document.getElementById("submit_approve_access")', tab_index, windex), - msg='Did not go to permission page.') + msg='Authentication failed. The username, password, or otp is invalid.') self._ExecuteJavascript( 'document.getElementById("submit_approve_access").click();', tab_index, windex) @@ -186,37 +135,6 @@ class ChromotingMixIn(object): tab_index, windex), msg='Chromoting app did not reload after authentication.') - def DenyAccess(self, tab_index=1, windex=0): - """Deny and then allow access to chromoting webapp.""" - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("submit_deny_access")', - tab_index, windex), - msg='Did not go to permission page.') - self._ExecuteJavascript( - 'document.getElementById("submit_deny_access").click();', - tab_index, windex) - - def SignOut(self, tab_index=1, windex=0): - """Signs out from chromoting and signs back in.""" - self._ExecuteAndWaitForMode( - 'document.getElementById("sign-out").click();', - 'UNAUTHENTICATED', tab_index, windex) - - def Authenticate(self, tab_index=1, windex=0): - """Finishes authentication flow for user.""" - self.ContinueAuth(tab_index, windex) - account = self.GetPrivateInfo()['test_chromoting_account'] - self.host.SignIn(account['username'], account['password'], None, - tab_index, windex) - self.host.AllowAccess(tab_index, windex) - - def StartMe2Me(self, tab_index=1, windex=0): - """Starts Me2Me. """ - self._ExecuteJavascript( - 'document.getElementById("get-started-me2me").click();', - tab_index, windex) - def Share(self, tab_index=1, windex=0): """Generates an access code and waits for incoming connections. @@ -230,305 +148,40 @@ class ChromotingMixIn(object): 'document.getElementById("access-code-display").innerText', tab_index, windex) - def CancelShare(self, tab_index=1, windex=0): - """Stops sharing the desktop on the host side.""" - self.assertTrue( - self._ExecuteAndWaitForMode( - 'remoting.cancelShare();', - 'HOST_SHARE_FINISHED', tab_index, windex), - msg='Stopping sharing from the host side failed') - - def EnableConnectionsInstalled(self, pin_exercise=False, - tab_index=1, windex=0): - """Enables the remote connections on the host side.""" - subprocess.call([self._GetHelperRunner(), self._GetHelper(), 'enable']) - - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("start-daemon").click();', - 'HOST_SETUP_ASK_PIN', tab_index, windex), - msg='Cannot start host setup') - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("ask-pin-form").hidden == false', - tab_index, windex), - msg='No ask pin dialog') - - if pin_exercise: - # Cancels the pin prompt - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-cancel").click();', - tab_index, windex) - - # Enables again - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("start-daemon").click();', - 'HOST_SETUP_ASK_PIN', tab_index, windex), - msg='Cannot start host setup') - - # Click ok without typing in pins - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-ok").click();', - tab_index, windex) - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("daemon-pin-error-message")', - tab_index, windex), - msg='No pin error message') - - # Mis-matching pins - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-entry").value = "111111";', - tab_index, windex) - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-confirm").value = "123456";', - tab_index, windex) - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("daemon-pin-error-message")', - tab_index, windex), - msg='No pin error message') - - # Types in correct pins - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-entry").value = "111111";', - tab_index, windex) - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-confirm").value = "111111";', - tab_index, windex) - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("daemon-pin-ok").click();', - 'HOST_SETUP_PROCESSING', tab_index, windex), - msg='Host setup was not started') - - # Handles preference panes - self.assertTrue( - self._WaitForJavascriptCondition( - 'remoting.currentMode == remoting.AppMode.HOST_SETUP_DONE', - tab_index, windex), - msg='Host setup was not done') + def Connect(self, access_code, wait_for_frame, tab_index=1, windex=0): + """Connects to a Chromoting host and starts the session. - # Dismisses the host config done dialog - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("host-setup-dialog")' - '.childNodes[5].hidden == false', - tab_index, windex), - msg='No host setup done dialog') - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("host-config-done-dismiss").click();', - 'HOME', tab_index, windex), - msg='Failed to dismiss host setup confirmation dialog') - - def EnableConnectionsUninstalledAndCancel(self, tab_index=1, windex=0): - """Enables remote connections while host is not installed yet.""" - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("start-daemon").click();', - 'HOST_SETUP_INSTALL', tab_index, windex), - msg='Cannot start host install') - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("host-config-install-dismiss").click();', - 'HOME', tab_index, windex), - msg='Failed to dismiss host install dialog') - - def DisableConnections(self, tab_index=1, windex=0): - """Disables the remote connections on the host side.""" - subprocess.call([self._GetHelperRunner(), self._GetHelper(), 'disable']) - - self._ExecuteJavascript( - 'document.getElementById("stop-daemon").click();', - tab_index, windex) - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("host-config-done-dismiss").click();', - 'HOME', tab_index, windex), - msg='Failed to dismiss host setup confirmation dialog') - - def Connect(self, access_code, tab_index=1, windex=0): - """Connects to a Chromoting host and starts the session.""" - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("access-code-entry").value = "%s";' - 'remoting.connectIt2Me();' % access_code, - 'IN_SESSION', tab_index, windex), - msg='Cannot connect it2me session') - - def ChangePin(self, pin='222222', tab_index=1, windex=0): - """Changes pin for enabled host.""" - subprocess.call([self._GetHelperRunner(), self._GetHelper(), 'changepin']) - - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("change-daemon-pin").click();', - 'HOST_SETUP_ASK_PIN', tab_index, windex), - msg='Cannot change daemon pin') - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("ask-pin-form").hidden == false', - tab_index, windex), - msg='No ask pin dialog') - - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-entry").value = "' + pin + '";', - tab_index, windex) - self._ExecuteJavascript( - 'document.getElementById("daemon-pin-confirm").value = "' + - pin + '";', tab_index, windex) - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("daemon-pin-ok").click();', - 'HOST_SETUP_PROCESSING', tab_index, windex), - msg='Host setup was not started') - - # Handles preference panes - self.assertTrue( - self._WaitForJavascriptCondition( - 'remoting.currentMode == remoting.AppMode.HOST_SETUP_DONE', - tab_index, windex), - msg='Host setup was not done') - - # Dismisses the host config done dialog - self.assertTrue( - self._WaitForJavascriptCondition( - 'document.getElementById("host-setup-dialog")' - '.childNodes[5].hidden == false', - tab_index, windex), - msg='No host setup done dialog') - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("host-config-done-dismiss").click();', - 'HOME', tab_index, windex), - msg='Failed to dismiss host setup confirmation dialog') - - def ChangeName(self, new_name='Changed', tab_index=1, windex=0): - """Changes the host name.""" - self._ExecuteJavascript( - 'document.getElementById("this-host-rename").click();', - tab_index, windex) - self._ExecuteJavascript( - 'document.getElementById("this-host-name").childNodes[0].value = "' + - new_name + '";', tab_index, windex) - self._ExecuteJavascript( - 'document.getElementById("this-host-rename").click();', - tab_index, windex) - - def ConnectMe2Me(self, pin='111111', mode='IN_SESSION', - tab_index=1, windex=0): - """Connects to a Chromoting host and starts the session.""" - - # There is delay from the enabling remote connections to the host - # showing up in the host list. We need to reload the web app to get - # the host to show up. We will repeat this a few times to make sure - # eventually host appears. - for _ in range(1, 3): - self._ExecuteJavascript( - 'window.location.reload();', - tab_index, windex) - - # pyauto _GetResultFromJSONRequest throws JSONInterfaceError after - # ~60 seconds if ExecuteJavascript is called right after reload. - # Waiting 2s here can avoid this. So instead of getting the error and - # wait ~60s, we wait 2s here. If the error still happens, the following - # retry will handle that. - time.sleep(2) - - # If this-host-connect is still not enabled, let's retry 3 times here. - this_host_connect_enabled = False - for _ in range(1, 3): - this_host_connect_enabled = self._WaitForJavascriptCondition( - 'document.getElementById("this-host-connect")' - '.getAttribute("data-daemon-state") == "enabled"', - tab_index, windex) - if this_host_connect_enabled: - break - if this_host_connect_enabled: - break; - - # Clicking this-host-connect does work right after this-host-connect - # is enabled. Need to retry. - for _ in range(1, 3): - self._ExecuteJavascript( - 'document.getElementById("this-host-connect").click();', - tab_index, windex) + Returns: + True on success; False otherwise. + """ + if not self._ExecuteAndWaitForMode( + 'document.getElementById("access-code-entry").value = "%s";' + 'remoting.connectIt2Me();' % access_code, + 'IN_SESSION', tab_index, windex): + return False - # pyauto _GetResultFromJSONRequest throws JSONInterfaceError after - # a long time out if WaitUntil is called right after click. - # Waiting 2s here can avoid this. - time.sleep(2) + if wait_for_frame and not self._WaitForJavascriptCondition( + 'remoting.clientSession && remoting.clientSession.hasReceivedFrame()', + tab_index, windex): + return False + return True - # If cannot detect that pin-form appears, try 3 times. - pin_form_exposed = False - for _ in range(1, 3): - pin_form_exposed = self._WaitForJavascriptCondition( - 'document.getElementById("client-dialog")' - '.childNodes[9].hidden == false', - tab_index, windex) - if pin_form_exposed: - break - if pin_form_exposed: - break + def CancelShare(self, tab_index=1, windex=0): + """Stops sharing the desktop on the host side. - self._ExecuteJavascript( - 'document.getElementById("pin-entry").value = "' + pin + '";', - tab_index, windex) - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("pin-form").childNodes[5].click();', - mode, tab_index, windex), - msg='Session was not started') + Returns: + True on success; False otherwise. + """ + return self._ExecuteAndWaitForMode( + 'remoting.cancelShare();', + 'HOST_SHARE_FINISHED', tab_index, windex) def Disconnect(self, tab_index=1, windex=0): - """Disconnects from the Chromoting it2me session on the client side.""" - self.assertTrue( - self._ExecuteAndWaitForMode( - 'remoting.disconnect();', - 'CLIENT_SESSION_FINISHED_IT2ME', tab_index, windex), - msg='Disconnecting it2me session from the client side failed') - - def DisconnectMe2Me(self, confirmation=True, tab_index=1, windex=0): - """Disconnects from the Chromoting me2me session on the client side.""" - self.assertTrue( - self._ExecuteAndWaitForMode( - 'remoting.disconnect();', - 'CLIENT_SESSION_FINISHED_ME2ME', tab_index, windex), - msg='Disconnecting me2me session from the client side failed') - - if confirmation: - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("client-finished-me2me-button")' - '.click();', 'HOME', tab_index, windex), - msg='Failed to dismiss session finished dialog') - - def ReconnectMe2Me(self, pin='111111', tab_index=1, windex=0): - """Reconnects the me2me session.""" - self._ExecuteJavascript( - 'document.getElementById("client-reconnect-button").click();', - tab_index, windex) - - # pyauto _GetResultFromJSONRequest throws JSONInterfaceError after - # a long time out if WaitUntil is called right after click. - time.sleep(2) + """Disconnects from the Chromoting session on the client side. - # If cannot detect that pin-form appears, try 3 times. - for _ in range(1, 3): - pin_form_exposed = self._WaitForJavascriptCondition( - 'document.getElementById("client-dialog")' - '.childNodes[9].hidden == false', - tab_index, windex) - if pin_form_exposed: - break - - self._ExecuteJavascript( - 'document.getElementById("pin-entry").value = "' + pin + '";', - tab_index, windex) - self.assertTrue( - self._ExecuteAndWaitForMode( - 'document.getElementById("pin-form").childNodes[5].click();', - 'IN_SESSION', tab_index, windex), - msg='Session was not started') + Returns: + True on success; False otherwise. + """ + return self._ExecuteAndWaitForMode( + 'remoting.disconnect();', + 'CLIENT_SESSION_FINISHED_IT2ME', tab_index, windex) |