1ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# Copyright 2014 The Chromium OS Authors. All rights reserved. 2ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# Use of this source code is governed by a BSD-style license that can be 3ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# found in the LICENSE file. 4ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 5ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard""" 6ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan StoddardThis module allows tests to interact with the Chrome Web Store (CWS) 7ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardusing ChromeDriver. They should inherit from the webstore_test class, 8ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardand should override the run() method. 9ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard""" 10ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 11ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardimport logging 12ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardimport time 13ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 14ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom autotest_lib.client.bin import test 15ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom autotest_lib.client.common_lib import error 16ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom autotest_lib.client.common_lib.cros import chromedriver 17ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom autotest_lib.client.common_lib.global_config import global_config 18ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom selenium.webdriver.common.by import By 19ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom selenium.webdriver.support import expected_conditions 20ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardfrom selenium.webdriver.support.ui import WebDriverWait 21ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 22ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# How long to wait, in seconds, for an app to launch. This is larger 23ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# than it needs to be, because it might be slow on older Chromebooks 24ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard_LAUNCH_DELAY = 4 25ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 26ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# How long to wait before entering the password when logging in to the CWS 27ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard_ENTER_PASSWORD_DELAY = 2 28ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 29ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# How long to wait before entering payment info 30ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard_PAYMENT_DELAY = 5 31ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 32ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddarddef enum(*enumNames): 33ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 34ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Creates an enum. Returns an enum object with a value for each enum 35ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard name, as well as from_string and to_string mappings. 36ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 37ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param enumNames: The strings representing the values of the enum 38ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 39ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard enums = dict(zip(enumNames, range(len(enumNames)))) 40ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard reverse = dict((value, key) for key, value in enums.iteritems()) 41ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard enums['from_string'] = enums 42ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard enums['to_string'] = reverse 43ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return type('Enum', (), enums) 44ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 45ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# TODO: staging and PNL don't work in these tests (crbug/396660) 46ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan StoddardTestEnv = enum('staging', 'pnl', 'prod', 'sandbox') 47ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 48ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan StoddardItemType = enum( 49ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'hosted_app', 50ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'packaged_app', 51ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'chrome_app', 52ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'extension', 53ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'theme', 54ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard) 55ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 56ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard# NOTE: paid installs don't work right now 57ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan StoddardInstallType = enum( 58ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'free', 59ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'free_trial', 60ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'paid', 61ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard) 62ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 63ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddarddef _labeled_button(label): 64ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 65ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Returns a button with the class webstore-test-button-label and the 66ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard specified label 67ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 68ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param label: The label on the button 69ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 70ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return ('//div[contains(@class,"webstore-test-button-label") ' 71ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'and text()="' + label + '"]') 72ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 73ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddarddef _install_type_click_xpath(item_type, install_type): 74ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 75ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Returns the XPath of the button to install an item of the given type. 76ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 77ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param item_type: The type of the item to install 78ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param install_type: The type of installation being used 79ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 80ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if install_type == InstallType.free: 81ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return _labeled_button('Free') 82ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard elif install_type == InstallType.free_trial: 83ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard # Both of these cases return buttons that say "Add to Chrome", 84ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard # but they are actually different buttons with only one being 85ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard # visible at a time. 86ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if item_type == ItemType.hosted_app: 87ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return ('//div[@id="cxdialog-install-paid-btn" and ' 88ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard '@aria-label="Add to Chrome"]') 89ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard else: 90ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return _labeled_button('Add to Chrome') 91ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard else: 92ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return ('//div[contains(@aria-label,"Buy for") ' 93ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'and not(contains(@style,"display: none"))]') 94ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 95ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddarddef _get_chrome_flags(test_env): 96ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 97ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Returns the Chrome flags for the given test environment. 98ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 99ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard flags = ['--apps-gallery-install-auto-confirm-for-tests=accept'] 100ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if test_env == TestEnv.prod: 101ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return flags 102ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 103ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard url_middle = { 104ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.staging: 'staging.corp', 105ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.sandbox: 'staging.sandbox', 106ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.pnl: 'prod-not-live.corp' 107ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard }[test_env] 108ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard download_url_middle = { 109ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.staging: 'download-staging.corp', 110ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.sandbox: 'download-staging.sandbox', 111ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.pnl: 'omaha.sandbox' 112ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard }[test_env] 113ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard flags.append('--apps-gallery-url=https://webstore-' + url_middle + 114ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard '.google.com') 115ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard flags.append('--apps-gallery-update-url=https://' + download_url_middle + 116ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard '.google.com/service/update2/crx') 117ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard logging.info('Using flags %s', flags) 118ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return flags 119ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 120ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 121ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddardclass webstore_test(test.test): 122ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 123ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard The base class for tests that interact with the web store. 124ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 125ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Subclasses must define run(), but should not override run_once(). 126ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Subclasses should use methods in this module such as install_item, 127ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard but they can also use the driver directly if they need to. 128ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 129ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 130ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def initialize(self, test_env=TestEnv.sandbox, 131ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard account='cwsbotdeveloper1@gmail.com'): 132ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 133ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Initialize the test. 134ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 135ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param test_env: The test environment to use 136ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 137ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard super(webstore_test, self).initialize() 138ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 139ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.username = account 140ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.password = global_config.get_config_value( 141ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'CLIENT', 'webstore_test_password', type=str) 142ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 143ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.test_env = test_env 144ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self._chrome_flags = _get_chrome_flags(test_env) 145ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.webstore_url = { 146ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.staging: 147ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'https://webstore-staging.corp.google.com', 148ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.sandbox: 149ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'https://webstore-staging.sandbox.google.com/webstore', 150ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.pnl: 151ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'https://webstore-prod-not-live.corp.google.com/webstore', 152ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.prod: 153ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 'https://chrome.google.com/webstore' 154ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard }[test_env] 155ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 156ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 157ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def build_url(self, page): 158ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 159ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Builds a webstore URL for the specified page. 160ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 161ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param page: the page to build a URL for 162ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 163ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return self.webstore_url + page + "?gl=US" 164ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 165ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 166ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def detail_page(self, item_id): 167ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 168ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Returns the URL of the detail page for the given item 169ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 170ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param item_id: The item ID 171ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 172ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard return self.build_url("/detail/" + item_id) 173ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 174ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 175ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def wait_for(self, xpath): 176ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 177ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Waits until the element specified by the given XPath is visible 178ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 179ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param xpath: The xpath of the element to wait for 180ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 181ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self._wait.until(expected_conditions.visibility_of_element_located( 182ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard (By.XPATH, xpath))) 183ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 184ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 185ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def run_once(self, **kwargs): 186ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard with chromedriver.chromedriver( 187ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard username=self.username, 188ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard password=self.password, 189ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard extra_chrome_flags=self._chrome_flags) \ 190ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard as chromedriver_instance: 191ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver = chromedriver_instance.driver 192ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.implicitly_wait(15) 193ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self._wait = WebDriverWait(self.driver, 20) 194ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard logging.info('Running test on test environment %s', 195ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard TestEnv.to_string[self.test_env]) 196ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.run(**kwargs) 197ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 198ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 199ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def run(self): 200ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 201ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Runs the test. Should be overridden by subclasses. 202ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 203ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard raise error.TestError('The test needs to override run()') 204ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 205ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 206ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def install_item(self, item_id, item_type, install_type): 207ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 208ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Installs an item from the CWS. 209ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 210ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param item_id: The ID of the item to install 211ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard (a 32-char string of letters) 212ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param item_type: The type of the item to install 213ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param install_type: The type of installation 214ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard (free, free trial, or paid) 215ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 216ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard logging.info('Installing item %s of type %s with install_type %s', 217ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard item_id, ItemType.to_string[item_type], 218ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard InstallType.to_string[install_type]) 219ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 220ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard # We need to go to the CWS home page before going to the detail 221ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard # page due to a bug in the CWS 222ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.get(self.webstore_url) 223ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.get(self.detail_page(item_id)) 224ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 225ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard install_type_click_xpath = _install_type_click_xpath( 226ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard item_type, install_type) 227ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if item_type == ItemType.extension or item_type == ItemType.theme: 228ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard post_install_xpath = ( 229ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard '//div[@aria-label="Added to Chrome" ' 230ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard ' and not(contains(@style,"display: none"))]') 231ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard else: 232ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard post_install_xpath = _labeled_button('Launch app') 233ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 234ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard # In this case we need to sign in again 235ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if install_type != InstallType.free: 236ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard button_xpath = _labeled_button('Sign in to add') 237ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard logging.info('Clicking button %s', button_xpath) 238ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.find_element_by_xpath(button_xpath).click() 239ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard time.sleep(_ENTER_PASSWORD_DELAY) 240ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard password_field = self.driver.find_element_by_xpath( 241ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard '//input[@id="Passwd"]') 242ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard password_field.send_keys(self.password) 243ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.find_element_by_xpath('//input[@id="signIn"]').click() 244ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 245ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard logging.info('Clicking %s', install_type_click_xpath) 246ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.find_element_by_xpath(install_type_click_xpath).click() 247ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 248ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if install_type == InstallType.paid: 249ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard handle = self.driver.current_window_handle 250ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard iframe = self.driver.find_element_by_xpath( 251ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard '//iframe[contains(@src, "sandbox.google.com/checkout")]') 252ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.switch_to_frame(iframe) 253ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.find_element_by_id('purchaseButton').click() 254ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard time.sleep(_PAYMENT_DELAY) # Wait for animation to finish 255ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.find_element_by_id('finishButton').click() 256ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.switch_to_window(handle) 257ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 258ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.wait_for(post_install_xpath) 259ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 260ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 261ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard def launch_app(self, app_id): 262ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 263ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard Launches an app. Verifies that it launched by verifying that 264ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard a new tab/window was opened. 265ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard 266ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard @param app_id: The ID of the app to run 267ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard """ 268ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard logging.info('Launching app %s', app_id) 269ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard num_handles_before = len(self.driver.window_handles) 270ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.get(self.webstore_url) 271ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard self.driver.get(self.detail_page(app_id)) 272ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard launch_button = self.driver.find_element_by_xpath( 273ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard _labeled_button('Launch app')) 274ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard launch_button.click(); 275ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard time.sleep(_LAUNCH_DELAY) # Wait for the app to launch 276ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard num_handles_after = len(self.driver.window_handles) 277ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard if num_handles_after <= num_handles_before: 278ab583045d1e3e21da15eeb5152c2f808f4aea8ffNathan Stoddard raise error.TestError('App failed to launch') 279