summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhorwich@chromium.org <jhorwich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-15 19:09:40 +0000
committerjhorwich@chromium.org <jhorwich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-15 19:09:40 +0000
commit9c621c92cb46f0d9bd56e0bca9102a8a46994fd8 (patch)
treec68b5bbfe69d9e568a287ea5e228a0e056856ce4
parent35d868140820f807fd6fda5093dcf557117d8525 (diff)
downloadchromium_src-9c621c92cb46f0d9bd56e0bca9102a8a46994fd8.zip
chromium_src-9c621c92cb46f0d9bd56e0bca9102a8a46994fd8.tar.gz
chromium_src-9c621c92cb46f0d9bd56e0bca9102a8a46994fd8.tar.bz2
Revert 151717 - Initial checkin of the me2me pyauto automation
- Modified chromoting.py to enable me2me automation - Added chromoting_helper.py to handle install, uninstall, enable, disable, changepin which requires admin privilege - Added chromoting.base.py as the base for all chromoting test cases - Modified chromoting_basic, renamed it it2me_basic and moved it under chromoting dir - Added auth, me2me_enable, me2me_connect test - Added a cert and a private key for signing host on mac - Added mock_pref_pane.* files to mock the pref pane for different scenarios NOTRY=true Review URL: https://chromiumcodereview.appspot.com/10821015 TBR=yihongg@chromium.org Review URL: https://chromiumcodereview.appspot.com/10837266 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151722 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/functional/PYAUTO_TESTS6
-rwxr-xr-xchrome/test/functional/chromoting/auth.py42
-rwxr-xr-xchrome/test/functional/chromoting/chromoting_base.py45
-rwxr-xr-xchrome/test/functional/chromoting/it2me_basic.py40
-rwxr-xr-xchrome/test/functional/chromoting/me2me_connect.py65
-rwxr-xr-xchrome/test/functional/chromoting/me2me_enable.py41
-rw-r--r--chrome/test/functional/chromoting/mock_pref_pane.py126
-rwxr-xr-xchrome/test/functional/chromoting_basic.py64
-rw-r--r--chrome/test/pyautolib/chromoting.py457
-rw-r--r--chrome/test/pyautolib/chromoting_cert.p12bin2427 -> 0 bytes
-rw-r--r--chrome/test/pyautolib/chromoting_helper.py184
-rw-r--r--chrome/test/pyautolib/chromoting_key.p12bin2427 -> 0 bytes
12 files changed, 122 insertions, 948 deletions
diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS
index 8645d9a..d1813f0 100644
--- a/chrome/test/functional/PYAUTO_TESTS
+++ b/chrome/test/functional/PYAUTO_TESTS
@@ -40,7 +40,7 @@
'bookmarks',
'browser',
'browsing_data',
- 'chromoting.it2me_basic',
+ 'chromoting_basic',
'codesign',
'content',
'cookies',
@@ -314,7 +314,7 @@
# You cannot resize the browser window on ChromeOS.
'-browser.BrowserTest.testWindowResize',
# ChromeOS doesn't yet support the chromoting host.
- '-chromoting.it2me_basic',
+ '-chromoting_basic',
# No codesign verification on ChromeOS.
'-codesign',
# Import tests are invalid on ChromeOS since Chrome is the only browser.
@@ -497,7 +497,7 @@
# Permanently-disabled tests.
# ===========================
# The chromoting webapp isn't currently available when FULL is run.
- '-chromoting.it2me_basic',
+ '-chromoting_basic',
# ==================================================
# Disabled tests that need to be investigated/fixed.
diff --git a/chrome/test/functional/chromoting/auth.py b/chrome/test/functional/chromoting/auth.py
deleted file mode 100755
index 283b339..0000000
--- a/chrome/test/functional/chromoting/auth.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Chromoting authentication related test cases."""
-
-import chromoting_base
-import pyauto
-
-
-class ChromotingAuth(chromoting_base.ChromotingBase):
- """Chromoting authentication related test cases."""
-
- def setUp(self):
- """Set up for auth test."""
- pyauto.PyUITest.setUp(self)
-
- webapp = self.InstallExtension(self.GetWebappPath())
- self.host.LaunchApp(webapp)
- self.account = self.GetPrivateInfo()['test_chromoting_account']
-
- def testDenyAllowAccess(self):
- """Denies access and then allows access."""
- self.host.ContinueAuth()
- self.host.SignIn(self.account['username'], self.account['password'])
- self.host.DenyAccess()
- self.host.ContinueAuth()
- self.host.AllowAccess()
-
- def testSignOutAndSignBackIn(self):
- """Signs out from chromoting and signs back in."""
- self.host.ContinueAuth()
- self.host.SignIn(self.account['username'], self.account['password'])
- self.host.AllowAccess()
- self.host.SignOut()
- self.host.ContinueAuth()
- self.host.AllowAccess()
-
-
-if __name__ == '__main__':
- chromoting_base.Main()
diff --git a/chrome/test/functional/chromoting/chromoting_base.py b/chrome/test/functional/chromoting/chromoting_base.py
deleted file mode 100755
index 7e893d9..0000000
--- a/chrome/test/functional/chromoting/chromoting_base.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Common imports, setup, etc for chromoting tests."""
-
-import os
-
-
-def _SetupPaths():
- """Add chrome/test/functional to sys.path for importing pyauto_functional"""
- functional_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- os.sys.path.append(functional_dir)
-
-_SetupPaths()
-
-
-import pyauto_functional # Must come before chromoting and pyauto.
-from pyauto_functional import Main
-import chromoting
-import pyauto
-
-
-class ChromotingBase(chromoting.ChromotingMixIn, pyauto.PyUITest):
- """Chromoting pyauto test base class.
-
- The following member variables can be used in the child classes:
- client_local: True if the client is on the same machines as host
- host: The chromoting host side, instance of ChromotingBase
- client: The chromoting client side, intance of ChromotingBase
- client_tab_index: The tab index to the chromoting client tab
- """
-
- def __init__(self, methodName):
- pyauto.PyUITest.__init__(self, methodName)
-
- self.client_local = (self.remote == None)
- self.host = self
- self.client = self if self.client_local else self.remote
- self.client_tab_index = 2 if self.client_local else 1
-
- def ExtraChromeFlags(self):
- """Add --allow-nacl-socket-api to connect chromoting successfully."""
- extra_chrome_flags = ['--allow-nacl-socket-api=*',]
- return pyauto.PyUITest.ExtraChromeFlags(self) + extra_chrome_flags \ No newline at end of file
diff --git a/chrome/test/functional/chromoting/it2me_basic.py b/chrome/test/functional/chromoting/it2me_basic.py
deleted file mode 100755
index 9cdf38f..0000000
--- a/chrome/test/functional/chromoting/it2me_basic.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Basic tests for Chromoting it2me."""
-
-import chromoting_base
-import pyauto
-
-
-class IT2MeBasic(chromoting_base.ChromotingBase):
- """Drives it2me basic test cases."""
-
- def setUp(self):
- """Set up for it2me basic test."""
- pyauto.PyUITest.setUp(self)
-
- webapp = self.InstallExtension(self.GetWebappPath())
- self.LaunchApp(webapp)
- self.Authenticate()
-
- if self.client_local:
- self.client.LaunchApp(webapp)
-
- def testIT2MeBasic(self):
- """Verify that we can start and disconnect a Chromoting it2me session."""
- access_code = self.host.Share()
- self.assertTrue(access_code,
- msg='Host attempted to share, but it failed. '
- 'No access code was found.')
-
- self.client.Connect(access_code, self.client_tab_index)
-
- self.host.CancelShare()
- self.client.Disconnect(self.client_tab_index)
-
-
-if __name__ == '__main__':
- chromoting_base.Main()
diff --git a/chrome/test/functional/chromoting/me2me_connect.py b/chrome/test/functional/chromoting/me2me_connect.py
deleted file mode 100755
index 3525158..0000000
--- a/chrome/test/functional/chromoting/me2me_connect.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Chromoting me2me connect/disconnect related test cases."""
-
-import chromoting_base
-import pyauto
-
-
-class Me2MeConnect(chromoting_base.ChromotingBase):
- """Drives me2me connect test cases."""
-
- def setUp(self):
- """Set up for me2me connect test."""
- pyauto.PyUITest.setUp(self)
-
- self.InstallHostDaemon()
- webapp = self.InstallExtension(self.GetWebappPath())
- self.host.LaunchApp(webapp)
- self.host.Authenticate()
- self.host.StartMe2Me()
- self.host.EnableConnectionsInstalled()
- self.client.LaunchApp(webapp)
-
- def tearDown(self):
- """Mainly uninstalls the host daemon."""
- self.host.DisableConnections()
- self.UninstallHostDaemon()
-
- pyauto.PyUITest.tearDown(self)
-
- def testMe2MeConnectDisconnectReconnectDisconnect(self):
- """Connects, disconnects, reconnects and disconnects"""
- self.client.ConnectMe2Me('111111', 'IN_SESSION',
- self.client_tab_index)
- self.client.DisconnectMe2Me(False, self.client_tab_index)
- self.client.ReconnectMe2Me('111111', self.client_tab_index)
- self.client.DisconnectMe2Me(True, self.client_tab_index)
-
- def testMe2MeConnectWithWrongPin(self):
- """Connects and disconnects."""
- self.client.ConnectMe2Me('222222', 'CLIENT_CONNECT_FAILED_ME2ME',
- self.client_tab_index)
- self.client.ReconnectMe2Me('111111', self.client_tab_index)
- self.client.DisconnectMe2Me(True, self.client_tab_index)
-
- def testMe2MeChangePin(self):
- """Changes pin, connects with new pin and then disconnects."""
- self.host.ChangePin('222222')
- self.client.ConnectMe2Me('222222', 'IN_SESSION',
- self.client_tab_index)
- self.client.DisconnectMe2Me(True, self.client_tab_index)
-
- def testMe2MeChangeName(self):
- """Changes host name, connects and then disconnects."""
- self.client.ChangeName("Changed")
- self.client.ConnectMe2Me('111111', 'IN_SESSION',
- self.client_tab_index)
- self.client.DisconnectMe2Me(True, self.client_tab_index)
-
-
-if __name__ == '__main__':
- chromoting_base.Main()
diff --git a/chrome/test/functional/chromoting/me2me_enable.py b/chrome/test/functional/chromoting/me2me_enable.py
deleted file mode 100755
index a8b89b6..0000000
--- a/chrome/test/functional/chromoting/me2me_enable.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Chromoting me2me enable/disable related test cases."""
-
-import chromoting_base
-import pyauto
-
-
-class Me2MeEnable(chromoting_base.ChromotingBase):
- """Drives the me2me enable test cases."""
-
- def setUp(self):
- """Set up for me2me enable test."""
- pyauto.PyUITest.setUp(self)
-
- self.InstallHostDaemon()
- webapp = self.InstallExtension(self.GetWebappPath())
- self.host.LaunchApp(webapp)
- self.host.Authenticate()
- self.host.StartMe2Me()
-
- def tearDown(self):
- """Mainly uninstalls the host daemon."""
- self.UninstallHostDaemon()
-
- pyauto.PyUITest.tearDown(self)
-
- def testMe2MeEnableDisable(self):
- """Enables/disables remote connections.
-
- This test also exercises different pin conditions.
- """
- self.host.EnableConnectionsInstalled(True)
- self.host.DisableConnections()
-
-
-if __name__ == '__main__':
- chromoting_base.Main()
diff --git a/chrome/test/functional/chromoting/mock_pref_pane.py b/chrome/test/functional/chromoting/mock_pref_pane.py
deleted file mode 100644
index 97191c5..0000000
--- a/chrome/test/functional/chromoting/mock_pref_pane.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Mock pref pane for testing purpose on Mac."""
-
-import Foundation
-import os
-import signal
-import subprocess
-import sys
-import tempfile
-import time
-
-
-class MockPrefPane(object):
- """Mock Pref Pane to enable/disable/changepin without system prompt.
-
- This only applies to Mac.
- """
-
- def __init__(self):
- self._service_name = 'org.chromium.chromoting'
- self._real_user_id = os.getuid()
- self._config_file = os.path.join(tempfile.gettempdir(),
- '%s.json' % self._service_name)
- self._tool_script = '/Library/PrivilegedHelperTools/%s.me2me.sh' % \
- self._service_name
-
- def _GetJobPid(self):
- """Gets the org.chromium.chromoting job id."""
- process = subprocess.Popen(['launchctl', 'list'], stdout=subprocess.PIPE)
- pid = None
- for line in process.stdout:
- # Format is:
- # 12345 - my.job (if my.job is running, number is job's PID)
- # - 0 my.other.job (if my.other.job is not running)
- fields = line.strip().split('\t')
- if fields[2] == self._service_name and fields[0] != "-":
- pid = fields[0]
- break
- process.wait()
- return pid
-
- def Enable(self):
- """Handles what pref pane does for enabling connection."""
- # Elevate privileges, otherwise tool_script executes with EUID != 0.
- os.setuid(0)
- subprocess.call([self._tool_script, '--enable'],
- stdin=open(self._config_file))
-
- # Drop privileges, start the launchd job as the logged-in user.
- os.setuid(self._real_user_id)
- subprocess.call(['launchctl', 'start', self._service_name])
-
- # Starting a launchd job is an asynchronous operation that typically takes
- # a couple of seconds, so poll until the job has started.
- for _ in range(1, 10):
- if self._GetJobPid():
- print '*** org.chromium.chromoting is running ***'
- break
- time.sleep(2)
-
- def Disable(self):
- """Handles what pref pane does for disabling connection."""
- # Elevate privileges, otherwise tool_script executes with EUID != 0.
- os.setuid(0)
- subprocess.call([self._tool_script, '--disable'],
- stdin=open(self._config_file))
-
- # Drop privileges, stop the launchd job as the logged-in user.
- os.setuid(self._real_user_id)
- subprocess.call(['launchctl', 'stop', self._service_name])
-
- # Stopping a launchd job is an asynchronous operation that typically takes
- # a couple of seconds, so poll until the job has stopped.
- for _ in range(1, 10):
- if not self._GetJobPid():
- print '*** org.chromium.chromoting is not running ***'
- break
- time.sleep(2)
-
- def ChangePin(self):
- """Handles what pref pane does for changing pin."""
- # Elevate privileges, otherwise tool_script executes with EUID != 0.
- os.setuid(0)
- subprocess.call([self._tool_script, '--save-config'],
- stdin=open(self._config_file))
-
- # Drop privileges and send SIGHUP to org.chromium.chromoting
- os.setuid(self._real_user_id)
- os.kill(int(self._GetJobPid()), signal.SIGHUP)
-
- def NotifyWebapp(self):
- """Notifies the web app that pref pane operation is done."""
- notif_center = Foundation.NSDistributedNotificationCenter.defaultCenter()
- notif_center.postNotificationName_object_userInfo_(
- self._service_name + '.update_succeeded', None, None)
-
-
-def Main():
- """Handles the mock pref pane actions."""
- assert sys.platform.startswith('darwin')
-
- print '*** Started mock pref pane ***'
- print '*** EUID=%d, UID=%d ***' % (os.geteuid(), os.getuid())
-
- pref_pane = MockPrefPane()
-
- if sys.argv[1] == 'enable':
- pref_pane.Enable()
- elif sys.argv[1] == 'disable':
- pref_pane.Disable()
- elif sys.argv[1] == 'changepin':
- pref_pane.ChangePin()
- else:
- print >>sys.stderr, 'Invalid syntax'
- return
-
- pref_pane.NotifyWebapp()
-
-
-if __name__ == '__main__':
- Main()
-
diff --git a/chrome/test/functional/chromoting_basic.py b/chrome/test/functional/chromoting_basic.py
new file mode 100755
index 0000000..e28ab52
--- /dev/null
+++ b/chrome/test/functional/chromoting_basic.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+
+import pyauto_functional # Must come before chromoting and pyauto.
+import chromoting
+import pyauto
+
+
+class ChromotingBasic(chromoting.ChromotingMixIn, pyauto.PyUITest):
+ """Basic tests for Chromoting."""
+
+ _EXTRA_CHROME_FLAGS = [
+ '--allow-nacl-socket-api=*',
+ ]
+
+ def ExtraChromeFlags(self):
+ """Ensures Chrome is launched with some custom flags.
+
+ Overrides the default list of extra flags passed to Chrome. See
+ ExtraChromeFlags() in pyauto.py.
+ """
+ return pyauto.PyUITest.ExtraChromeFlags(self) + self._EXTRA_CHROME_FLAGS
+
+ def setUp(self):
+ """Set up test for Chromoting on both local and remote machines.
+
+ Installs the Chromoting app, launches it, and authenticates
+ using the default Chromoting test account.
+ """
+ super(ChromotingBasic, self).setUp()
+ self._app = self.InstallExtension(self.GetWebappPath())
+ self.LaunchApp(self._app)
+ account = self.GetPrivateInfo()['test_chromoting_account']
+ self.Authenticate(account['username'], account['password'])
+
+ def testChromoting(self):
+ """Verify that we can start and disconnect from a Chromoting session."""
+ client_local = (self.remote == None)
+ host = self
+ client = self if client_local else self.remote
+ client_tab_index = 2 if client_local else 1
+
+ access_code = host.Share()
+ self.assertTrue(access_code,
+ msg='Host attempted to share, but it failed. '
+ 'No access code was found.')
+
+ if client_local:
+ client.LaunchApp(self._app)
+
+ self.assertTrue(client.Connect(access_code, True, client_tab_index),
+ msg='The client attempted to connect to the host, '
+ 'but the chromoting session did not start.')
+
+ host.CancelShare()
+ client.Disconnect(client_tab_index)
+
+
+if __name__ == '__main__':
+ pyauto_functional.Main()
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)
diff --git a/chrome/test/pyautolib/chromoting_cert.p12 b/chrome/test/pyautolib/chromoting_cert.p12
deleted file mode 100644
index 4751cce..0000000
--- a/chrome/test/pyautolib/chromoting_cert.p12
+++ /dev/null
Binary files differ
diff --git a/chrome/test/pyautolib/chromoting_helper.py b/chrome/test/pyautolib/chromoting_helper.py
deleted file mode 100644
index 0d29d9c..0000000
--- a/chrome/test/pyautolib/chromoting_helper.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Chromoting helper to install/uninstall host and replace pref pane."""
-
-import abc
-import os
-import shutil
-import sys
-import subprocess
-
-
-class ChromotingHelper(object):
- """Chromoting helper base class."""
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def InstallHost(self, bin_dir):
- """Installs the chromoting host"""
- return
-
- @abc.abstractmethod
- def UninstallHost(self, bin_dir):
- """Uninstalls the chromoting host"""
- return
-
-
-class ChromotingHelperMac(ChromotingHelper):
- """Chromoting Helper class for Mac.
-
- Installs/uninstalls host and replace the pref pane for testing purpose.
- """
-
- def InstallHost(self, bin_dir):
- """Installs host on Mac."""
- assert os.geteuid() == 0, 'Need superuser privileges'
-
- # Run most of the steps here with login user
- login_uid = os.getuid()
- os.seteuid(login_uid)
-
- # Change the working dir to the dir that has the host zip file
- current_dir = os.getcwd()
- os.chdir(bin_dir)
- host_dir = 'remoting-me2me-host-mac'
- output_dir = os.path.join(host_dir, 'output')
-
- # Remove remoting-me2me-host-mac dir just in case
- shutil.rmtree(host_dir, True)
-
- # Unzip the host archive and prepare the files/dirs
- subprocess.call('unzip remoting-me2me-host-mac.zip', shell=True)
- subprocess.call('mkdir ' + output_dir, shell=True)
-
- # Prepare security identity for code signing purpose
- os.seteuid(0)
- key_chain = '/Library/Keychains/ChromotingTest'
- password = '1111'
- key = os.path.join(current_dir, 'chrome', 'test',
- 'pyautolib', 'chromoting_key.p12')
- cert = os.path.join(current_dir, 'chrome', 'test',
- 'pyautolib', 'chromoting_cert.p12')
- subprocess.call(['security', 'delete-keychain', key_chain])
- subprocess.call(['security', 'create-keychain', '-p',
- password, key_chain])
- subprocess.call(['security', 'import', key,
- '-k', key_chain, '-P', password, '-A'])
- subprocess.call(['security', 'import', cert,
- '-k', key_chain, '-P', password])
- os.seteuid(login_uid)
-
- # Sign the host
- do_signing = os.path.join(host_dir, 'do_signing.sh')
- subprocess.call(do_signing + ' ' + output_dir + ' ' + host_dir + ' ' +
- key_chain + ' "Chromoting Test"', shell=True)
-
- # Remove security identify
- os.seteuid(0)
- subprocess.call(['security', 'delete-keychain', key_chain])
- os.seteuid(login_uid)
-
- # Figure out the dmg name
- version = ""
- for output_file in os.listdir(output_dir):
- if output_file.endswith('.dmg'):
- version = os.path.basename(output_file)[len('ChromotingHost-'):-4]
-
- # Mount before installation
- dmg = os.path.join(output_dir, 'ChromotingHost-' + version + '.dmg')
- subprocess.call('hdiutil' + ' mount ' + dmg, shell=True)
-
- # Install host
- os.seteuid(0)
- mpkg = os.path.join('/Volumes', 'Chromoting Host ' + version,
- 'Chromoting Host.mpkg')
- subprocess.call(['/usr/sbin/installer', '-pkg',
- mpkg, '-target', '/'])
- os.seteuid(login_uid)
-
- # Unmount after installation
- mounted = os.path.join('/Volumes', 'Chromoting Host ' + version)
- subprocess.call('hdiutil unmount "' + mounted + '"', shell=True)
-
- # Clean up remoting-me2me-host-mac dir
- shutil.rmtree(host_dir, True)
-
- # Resume the original working dir
- os.chdir(current_dir)
-
- def UninstallHost(self, bin_dir):
- """Uninstalls host on Mac."""
- assert os.geteuid() == 0, 'Need superuser privileges'
- uninstall_app = os.path.join('/', 'Applications',
- 'Chromoting Host Uninstaller.app')
- subprocess.call(['open', '-a', uninstall_app])
-
- def ReplacePrefPaneMac(self, operation):
- """Constructs mock pref pane to replace the actual pref pane on Mac."""
- assert os.geteuid() == 0, 'Need superuser privileges'
-
- pref_pane_dir = os.path.join('/Library', 'PreferencePanes')
-
- mock_pref_pane = os.path.join(pref_pane_dir, 'mock_pref_pane')
- pref_pane = os.path.join(pref_pane_dir, 'org.chromium.chromoting.prefPane')
- mock_pref_pane_python = os.path.join(os.getcwd(), 'chrome', 'test',
- 'functional', 'chromoting',
- 'mock_pref_pane.py')
-
- shutil.rmtree(mock_pref_pane, True)
-
- mock_pref_pane_file = open(mock_pref_pane, 'w')
- mock_pref_pane_file.write('#!/bin/bash\n')
- mock_pref_pane_file.write('\n')
- mock_pref_pane_file.write('suid-python' +
- ' ' + mock_pref_pane_python + ' ' + operation)
- mock_pref_pane_file.close()
-
- subprocess.call(['chmod', 'a+x', mock_pref_pane])
- shutil.rmtree(pref_pane, True)
- subprocess.call(['ln', '-s', mock_pref_pane, pref_pane])
-
-
-class ChromotingHelperWindows(ChromotingHelper):
- """Chromoting Helper class for Windows for installing/uninstalling host."""
-
- def InstallHost(self, bin_dir):
- """Installs host on Windows."""
- host_msi = os.path.join(bin_dir, 'remoting-host.msi')
- subprocess.Popen(['msiexec', '/i', host_msi, '/passive']).wait()
-
- def UninstallHost(self, bin_dir):
- """Uninstalls host on Windows."""
- host_msi = os.path.join(bin_dir, 'remoting-host.msi')
- subprocess.Popen(['msiexec', '/x', host_msi, '/passive']).wait()
-
-
-def Main():
- """Main function to dispatch operations."""
- assert sys.platform.startswith('win') or \
- sys.platform.startswith('darwin'), \
- 'Only support Windows and Mac'
-
- if sys.platform.startswith('win'):
- helper = ChromotingHelperWindows()
- elif sys.platform.startswith('darwin'):
- helper = ChromotingHelperMac()
-
- if sys.argv[1] == 'install':
- helper.InstallHost(sys.argv[2])
- elif sys.argv[1] == 'uninstall':
- helper.UninstallHost(sys.argv[2])
- elif sys.argv[1] in ['enable', 'disable', 'changepin']:
- assert sys.platform.startswith('darwin'), \
- 'Replacing pref pane is Mac specific'
- helper.ReplacePrefPaneMac(sys.argv[1])
- else:
- print >>sys.stderr, 'Invalid syntax'
- return 1
-
-
-if __name__ == '__main__':
- Main() \ No newline at end of file
diff --git a/chrome/test/pyautolib/chromoting_key.p12 b/chrome/test/pyautolib/chromoting_key.p12
deleted file mode 100644
index 55c75f1..0000000
--- a/chrome/test/pyautolib/chromoting_key.p12
+++ /dev/null
Binary files differ