Index: chrome/test/pyautolib/chromoting.py |
=================================================================== |
--- chrome/test/pyautolib/chromoting.py (revision 151721) |
+++ chrome/test/pyautolib/chromoting.py (working copy) |
@@ -2,16 +2,9 @@ |
# 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): |
"""MixIn for PyUITest that adds Chromoting-specific methods. |
@@ -28,52 +21,30 @@ |
""" |
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 @@ |
""" |
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 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 _GetHelper(self): |
- """Get chromoting_helper.py.""" |
- return os.path.join('chrome', 'test', 'pyautolib', 'chromoting_helper.py') |
+ 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 InstallHostDaemon(self): |
- """Installs the host daemon.""" |
- subprocess.call([self._GetHelperRunner(), self._GetHelper(), |
- 'install', self.BrowserPath()]) |
- |
- def UninstallHostDaemon(self): |
- """Uninstalls the host daemon.""" |
- subprocess.call([self._GetHelperRunner(), self._GetHelper(), |
- 'uninstall', self.BrowserPath()]) |
- |
- 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 @@ |
'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 @@ |
'{ 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 @@ |
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 @@ |
'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 Connect(self, access_code, wait_for_frame, tab_index=1, windex=0): |
+ """Connects to a Chromoting host and starts the session. |
- 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']) |
+ 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 |
- 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 wait_for_frame and not self._WaitForJavascriptCondition( |
+ 'remoting.clientSession && remoting.clientSession.hasReceivedFrame()', |
+ tab_index, windex): |
+ return False |
+ return True |
- if pin_exercise: |
- # Cancels the pin prompt |
- self._ExecuteJavascript( |
- 'document.getElementById("daemon-pin-cancel").click();', |
- tab_index, windex) |
+ def CancelShare(self, tab_index=1, windex=0): |
+ """Stops sharing the desktop on the host side. |
- # Enables again |
- self.assertTrue( |
- self._ExecuteAndWaitForMode( |
- 'document.getElementById("start-daemon").click();', |
- 'HOST_SETUP_ASK_PIN', tab_index, windex), |
- msg='Cannot start host setup') |
+ Returns: |
+ True on success; False otherwise. |
+ """ |
+ return self._ExecuteAndWaitForMode( |
+ 'remoting.cancelShare();', |
+ 'HOST_SHARE_FINISHED', tab_index, windex) |
- # 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') |
- |
- # 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) |
- |
- # 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 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 |
- |
- 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') |
- |
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') |
+ """Disconnects from the Chromoting session on the client side. |
- 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) |
- |
- # 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) |