diff options
author | jhorwich@chromium.org <jhorwich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-15 19:09:40 +0000 |
---|---|---|
committer | jhorwich@chromium.org <jhorwich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-15 19:09:40 +0000 |
commit | 9c621c92cb46f0d9bd56e0bca9102a8a46994fd8 (patch) | |
tree | c68b5bbfe69d9e568a287ea5e228a0e056856ce4 | |
parent | 35d868140820f807fd6fda5093dcf557117d8525 (diff) | |
download | chromium_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_TESTS | 6 | ||||
-rwxr-xr-x | chrome/test/functional/chromoting/auth.py | 42 | ||||
-rwxr-xr-x | chrome/test/functional/chromoting/chromoting_base.py | 45 | ||||
-rwxr-xr-x | chrome/test/functional/chromoting/it2me_basic.py | 40 | ||||
-rwxr-xr-x | chrome/test/functional/chromoting/me2me_connect.py | 65 | ||||
-rwxr-xr-x | chrome/test/functional/chromoting/me2me_enable.py | 41 | ||||
-rw-r--r-- | chrome/test/functional/chromoting/mock_pref_pane.py | 126 | ||||
-rwxr-xr-x | chrome/test/functional/chromoting_basic.py | 64 | ||||
-rw-r--r-- | chrome/test/pyautolib/chromoting.py | 457 | ||||
-rw-r--r-- | chrome/test/pyautolib/chromoting_cert.p12 | bin | 2427 -> 0 bytes | |||
-rw-r--r-- | chrome/test/pyautolib/chromoting_helper.py | 184 | ||||
-rw-r--r-- | chrome/test/pyautolib/chromoting_key.p12 | bin | 2427 -> 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 Binary files differdeleted file mode 100644 index 4751cce..0000000 --- a/chrome/test/pyautolib/chromoting_cert.p12 +++ /dev/null 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 Binary files differdeleted file mode 100644 index 55c75f1..0000000 --- a/chrome/test/pyautolib/chromoting_key.p12 +++ /dev/null |