Index: chrome/test/remoting/install_and_launch_app.py |
diff --git a/chrome/test/remoting/install_and_launch_app.py b/chrome/test/remoting/install_and_launch_app.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..6fb235e2c034fcbe6e7deaedb6e506320eaf11a2 |
--- /dev/null |
+++ b/chrome/test/remoting/install_and_launch_app.py |
@@ -0,0 +1,173 @@ |
+#!/usr/bin/python |
+# Copyright 2014 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. |
+ |
+"""A Chromedriver smoke-test that installs and launches a web-app. |
+ |
+ Args: |
+ driver_dir: Location of Chromedriver binary on local machine. |
+ profile_dir: A user-data-dir containing login token for the app user. |
+ app_id: App ID of web-app in Chrome web-store. |
+ app_window_title: The title of the window that should come up on app launch. |
+ |
+ TODO(anandc): Reduce the # of parameters required from the command-line. |
+ Maybe read from a JSON file. Also, map appID to expected app window title. |
+ |
+ This script navigates to the app-detail page on Chrome Web Store for the |
+ specified app-id. From there, it then installs the app and launches it. It |
+ then checks if the resulting new window has the expected title. |
+ |
+""" |
+ |
+import argparse |
+import os |
+import shutil |
+import tempfile |
+import time |
+ |
+from selenium import webdriver |
+from selenium.webdriver.chrome.options import Options |
+ |
+CWS_URL = 'https://chrome.google.com/webstore/detail' |
+WEBSTORE_BUTTON_LABEL = 'webstore-test-button-label' |
+FREE_BUTTON_XPATH = ( |
+ '//div[contains(@class, \"%s\") and text() = \"Free\"]' % |
+ (WEBSTORE_BUTTON_LABEL)) |
+LAUNCH_BUTTON_XPATH = ( |
+ '//div[contains(@class, \"%s\") and text() = \"Launch app\"]' % |
+ (WEBSTORE_BUTTON_LABEL)) |
+ |
+ |
+def CreateTempProfileDir(source_dir): |
+ """Creates a temporary profile directory, for use by the test. |
+ |
+ This avoids modifying the input user-data-dir by actions that the test |
+ performs. |
+ |
+ Args: |
+ source_dir: The directory to copy and place in a temp folder. |
+ |
+ Returns: |
+ tmp_dir: Name of the temporary folder that was created. |
+ profile_dir: Name of the profile-dir under the tmp_dir. |
+ """ |
+ |
+ tmp_dir = tempfile.mkdtemp() |
+ print 'Created folder %s' % (tmp_dir) |
+ profile_dir = os.path.join(tmp_dir, 'testuser') |
+ # Copy over previous created profile for this execution of Chrome Driver. |
+ shutil.copytree(source_dir, profile_dir) |
+ return tmp_dir, profile_dir |
+ |
+ |
+def ParseCmdLineArgs(): |
+ """Parses command line arguments and returns them. |
+ |
+ Returns: |
+ args: Parse command line arguments. |
+ """ |
+ parser = argparse.ArgumentParser() |
+ parser.add_argument( |
+ '-d', '--driver_dir', required=True, |
+ help='path to folder where Chromedriver has been installed.') |
+ parser.add_argument( |
+ '-p', '--profile_dir', required=True, |
+ help='path to user-data-dir with trusted-tester signed in.') |
+ parser.add_argument( |
+ '-a', '--app_id', required=True, |
+ help='app-id of web-store app being tested.') |
+ parser.add_argument( |
+ '-e', '--app_window_title', required=True, |
+ help='Title of the app window that we expect to come up.') |
+ |
+ # Use input json file if specified on command line. |
+ args = parser.parse_args() |
+ return args |
+ |
+ |
+def main(): |
+ |
+ args = ParseCmdLineArgs() |
+ |
+ org_profile_dir = args.profile_dir |
+ print 'Creating temp-dir using profile-dir %s' % org_profile_dir |
+ tmp_dir, profile_dir = CreateTempProfileDir(org_profile_dir) |
+ |
+ options = Options() |
+ options.add_argument('--user-data-dir=' + profile_dir) |
+ # Suppress the confirmation dialog that comes up. |
+ # With M39, this flag will no longer work. See https://crbug/357774. |
+ # TODO(anandc): Work with a profile-dir that already has extension downloaded, |
+ # and also add support for loading extension from a local directory. |
+ options.add_argument('--apps-gallery-install-auto-confirm-for-tests=accept') |
+ driver = webdriver.Chrome(args.driver_dir, chrome_options=options) |
+ |
+ try: |
+ |
+ # Navigate to chrome:apps first. |
+ # TODO(anandc): add check to make sure the app we are testing isn't already |
garykac
2014/09/18 23:33:16
nit: "Add"
(and "Is" below)
anandc
2014/09/19 21:05:31
Done.
|
+ # added for this user. |
+ chrome_apps_link = 'chrome://apps' |
+ driver.get(chrome_apps_link) |
+ # TODO(anandc): is there any event or state we could wait on? For now, |
+ # we have hard-coded sleeps. |
+ time.sleep(2) |
+ |
+ cws_app_detail_link = '%s/%s' % (CWS_URL, args.app_id) |
+ # Navigate to the app page at Chrome Web Store. |
+ driver.get(cws_app_detail_link) |
+ # Get the page again, to get all controls. This seems to be a bug, either |
+ # in ChromeDriver, or the app-page. Without this additional GET, we don't |
+ # get all controls. Even sleeping for 5 seconds doesn't suffice. |
+ # TODO(anandc): Investigate why the page doesn't work with just 1 call. |
+ driver.get(cws_app_detail_link) |
+ time.sleep(2) |
garykac
2014/09/18 23:33:16
Not sure if it's worth doing, but these time.sleep
anandc
2014/09/19 21:05:31
Done.
|
+ |
+ # Install the app by clicking the button that says "Free". |
+ free_button = driver.find_element_by_xpath(FREE_BUTTON_XPATH) |
+ free_button.click() |
+ time.sleep(2) |
+ |
+ # We should now be at a new tab; switch to it. |
+ current_tab = driver.window_handles[-1] |
+ driver.switch_to_window(current_tab) |
+ # Go to Chrome Apps |
+ # TODO(anandc): add check to make sure the app we are testing is now added. |
+ driver.get(chrome_apps_link) |
+ # Now that the app has been installed, go back to its details page, |
+ # and launch it. (2 GET calls again, once is not enough; see not above.) |
garykac
2014/09/18 23:33:16
The code will be a bit easier to follow if you hav
anandc
2014/09/19 21:05:32
Makes sense. Thanks.
Done, with a slight differe
|
+ driver.get(cws_app_detail_link) |
+ driver.get(cws_app_detail_link) |
+ time.sleep(2) |
+ |
+ launch_button = driver.find_element_by_xpath(LAUNCH_BUTTON_XPATH) |
garykac
2014/09/18 23:33:16
This chunk can be re-used as well:
def click_wait
anandc
2014/09/19 21:05:32
Done.
|
+ launch_button.click() |
+ time.sleep(2) |
+ |
+ # For now, make sure the "connecting" dialog comes up. |
+ # TODO(anandc): add more validation; ideally, wait for the separate app |
+ # window to appear. |
+ success = False |
+ for handle in driver.window_handles: |
+ driver.switch_to_window(handle) |
+ if driver.title == args.app_window_title: |
+ success = True |
+ print 'Webapp launched successfully.' |
+ break |
+ |
+ if not success: |
+ print 'Webapp did not launch successfully.' |
+ |
+ except Exception, e: |
+ raise e |
+ finally: |
+ # Cleanup |
+ print 'Deleting %s' % tmp_dir |
+ shutil.rmtree(profile_dir) |
+ os.rmdir(tmp_dir) |
+ driver.quit() |
+ |
+ |
+if __name__ == '__main__': |
+ main() |