Index: chrome/test/pyautolib/chromoting.py |
=================================================================== |
--- chrome/test/pyautolib/chromoting.py (revision 150103) |
+++ chrome/test/pyautolib/chromoting.py (working copy) |
@@ -3,8 +3,23 @@ |
# found in the LICENSE file. |
import os |
+import subprocess |
+import sys |
+import time |
+def _GetHelperRunner(): |
Nirnimesh
2012/08/06 19:13:53
Is there a reason these functions have to be globa
yihongg
2012/08/08 01:04:48
Done.
|
+ """Returns the python binary name that runs chromoting_helper.py.""" |
+ if sys.platform.startswith('win'): |
+ return "python" |
+ else: |
+ return "suid-python" |
+ |
+def _GetHelper(): |
+ """Get chromoting_helper.py""" |
+ return os.path.join("chrome", "test", "pyautolib", "chromoting_helper.py") |
+ |
+ |
class ChromotingMixIn(object): |
"""MixIn for PyUITest that adds Chromoting-specific methods. |
@@ -18,11 +33,13 @@ |
self.LaunchApp(app) |
self.Authenticate() |
self.assertTrue(self.Share()) |
+ |
""" |
def _ExecuteJavascript(self, command, tab_index, windex): |
- """Helper that returns immediately after running a Javascript command.""" |
- return self.ExecuteJavascript( |
+ """Helper that returns immediately after running a Javascript command. |
+ """ |
+ self.ExecuteJavascript( |
'%s; window.domAutomationController.send("done");' % command, |
tab_index, windex) |
@@ -31,20 +48,33 @@ |
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. |
+ |
""" |
return self.WaitUntil(lambda: self.GetDOMValue( |
'(%s) ? "1" : ""' % condition, tab_index, windex)) |
def _ExecuteAndWaitForMode(self, command, mode, tab_index, windex): |
- self.assertTrue(self._ExecuteJavascript(command, tab_index, windex), |
- 'Javascript command did not return anything.') |
+ """ Executes JavaScript and wait for remoting app mode equal to |
+ the given mode. |
+ |
+ Returns: True if condition is satisfied or otherwise False. |
+ |
+ """ |
+ self._ExecuteJavascript(command, tab_index, windex) |
return self._WaitForJavascriptCondition( |
'remoting.currentMode == remoting.AppMode.%s' % mode, |
tab_index, windex) |
def _ExecuteAndWaitForMajorMode(self, command, mode, tab_index, windex): |
- self.assertTrue(self._ExecuteJavascript(command, tab_index, windex), |
- 'Javascript command did not return anything.') |
+ """ Executes JavaScript and wait for remoting app major mode equal to |
+ the given mode. |
+ |
+ Returns: True if condition is satisfied or otherwise False. |
+ |
+ """ |
+ self._ExecuteJavascript(command, tab_index, windex) |
return self._WaitForJavascriptCondition( |
'remoting.getMajorMode() == remoting.AppMode.%s' % mode, |
tab_index, windex) |
@@ -53,27 +83,38 @@ |
"""Returns the path to the webapp. |
Expects the webapp to be in the same place as the pyautolib binaries. |
+ |
""" |
return os.path.join(self.BrowserPath(), 'remoting', 'remoting.webapp') |
- 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 InstallHostDaemon(self): |
+ """Installs the host daemon.""" |
+ subprocess.call([self._GetHelperRunner(), self._GetHelper(), |
+ "install", 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 UninstallHostDaemon(self): |
+ """Uninstalls the host daemon.""" |
+ subprocess.call([self._GetHelperRunner(), self._GetHelper(), |
+ "uninstall", self.BrowserPath()]) |
- Raises: |
- AssertionError if the authentication flow changes or |
- the credentials are incorrect. |
- """ |
+ def ContinueAuth(self, tab_index=1, windex=0): |
+ """Starts authentication.""" |
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 LogIn(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), |
@@ -95,10 +136,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( |
@@ -112,12 +153,14 @@ |
'{ 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='Authentication failed. The username, password, or otp is invalid.') |
+ msg='Did not go to permission page.') |
self._ExecuteJavascript( |
'document.getElementById("submit_approve_access").click();', |
tab_index, windex) |
@@ -135,6 +178,37 @@ |
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.LogIn(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. |
@@ -148,40 +222,264 @@ |
'document.getElementById("access-code-display").innerText', |
tab_index, windex) |
- def Connect(self, access_code, wait_for_frame, tab_index=1, windex=0): |
- """Connects to a Chromoting host and starts the session. |
+ 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') |
- 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 |
+ 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"]) |
- if wait_for_frame and not self._WaitForJavascriptCondition( |
- 'remoting.clientSession && remoting.clientSession.hasReceivedFrame()', |
- tab_index, windex): |
- return False |
- return True |
+ 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') |
- def CancelShare(self, tab_index=1, windex=0): |
- """Stops sharing the desktop on the host side. |
+ if pin_exercise: |
+ # Cancels the pin prompt |
+ self._ExecuteJavascript( |
+ 'document.getElementById("daemon-pin-cancel").click();', |
+ tab_index, windex) |
- Returns: |
- True on success; False otherwise. |
- """ |
- return self._ExecuteAndWaitForMode( |
- 'remoting.cancelShare();', |
- 'HOST_SHARE_FINISHED', 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') |
+ |
+ # 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.""" |
+ time.sleep(2) |
+ subprocess.call([self._GetHelperRunner(), self._GetHelper(), "disable"]) |
+ |
+ self._ExecuteJavascript( |
+ 'window.location.reload();', |
+ tab_index, windex) |
+ time.sleep(2) |
+ |
+ 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.""" |
+ if sys.platform.startswith('win'): |
+ time.sleep(10) |
+ else: |
+ time.sleep(2) |
+ self._ExecuteJavascript( |
+ 'window.location.reload();', |
+ tab_index, windex) |
+ time.sleep(2) |
+ |
+ self.assertTrue( |
+ self._WaitForJavascriptCondition( |
+ 'document.getElementById("this-host-connect")', |
+ tab_index, windex), |
+ msg='This host did not appear') |
+ self.assertTrue( |
+ self._ExecuteAndWaitForMode( |
+ 'document.getElementById("this-host-name").click();', |
+ 'CLIENT_PIN_PROMPT', tab_index, windex), |
+ msg='Client pin prompt did not show') |
+ 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 session on the client side. |
+ """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') |
- Returns: |
- True on success; False otherwise. |
- """ |
- return self._ExecuteAndWaitForMode( |
- 'remoting.disconnect();', |
- 'CLIENT_SESSION_FINISHED_IT2ME', tab_index, windex) |
+ 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) |
+ time.sleep(2) |
+ 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') |