120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat# Copyright 2016 The Chromium OS Authors. All rights reserved. 220257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat# Use of this source code is governed by a BSD-style license that can be 320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat# found in the LICENSE file. 420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat# 520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat# arc_util.py is supposed to be called from chrome.py for ARC specific logic. 620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat# It should not import arc.py since it will create a import loop. 720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatimport logging 9b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavezimport os 10b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavezimport select 1120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatimport tempfile 12b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavezimport time 1320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 1420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatfrom autotest_lib.client.common_lib import error 1520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatfrom autotest_lib.client.common_lib import file_utils 1620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatfrom autotest_lib.client.common_lib.cros import arc_common 1720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatfrom telemetry.internal.browser import extension_page 1820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 1920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat_ARC_SUPPORT_HOST_URL = 'chrome-extension://cnbgggchhmkkdmeppjobngjoejnihlei/' 20ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld_ARC_SUPPORT_HOST_PAGENAME = '_generated_background_page.html' 21b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez_DUMPSTATE_DEFAULT_TIMEOUT = 20 22b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez_DUMPSTATE_PATH = '/var/log/arc-dumpstate.log' 23b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez_DUMPSTATE_PIPE_PATH = '/var/run/arc/bugreport/pipe' 2490ba12ece4886e6deeed8849dd6c24b83f03e3e4Derek Basehore_USERNAME = 'arcplusplustest@gmail.com' 2590ba12ece4886e6deeed8849dd6c24b83f03e3e4Derek Basehore_USERNAME_DISPLAY = 'arcplusplustest@gmail.com' 2690ba12ece4886e6deeed8849dd6c24b83f03e3e4Derek Basehore_ARCP_URL = 'https://sites.google.com/a/chromium.org/dev/chromium-os' \ 2790ba12ece4886e6deeed8849dd6c24b83f03e3e4Derek Basehore '/testing/arcplusplus-testing/arcp' 28d33c21d5d384efdb53643bf1168b17628905ac68Ben Cheng_OPT_IN_BEGIN = 'Initializing ARC opt-in flow.' 29d33c21d5d384efdb53643bf1168b17628905ac68Ben Cheng_OPT_IN_FINISH = 'ARC opt-in flow complete.' 3020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 3120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatdef should_start_arc(arc_mode): 32c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 33c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld Determines whether ARC should be started. 34c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 35c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld @param arc_mode: mode as defined in arc_common. 36c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 37c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld @returns: True or False. 38c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 39c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 4020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat logging.debug('ARC is enabled in mode ' + str(arc_mode)) 4120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat assert arc_mode is None or arc_mode in arc_common.ARC_MODES 4220257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat return arc_mode in [arc_common.ARC_MODE_ENABLED, 4320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat arc_common.ARC_MODE_ENABLED_ASYNC] 4420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 4520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 4620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatdef get_extra_chrome_flags(): 4720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat """Returns extra Chrome flags for ARC tests to run""" 4820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat return ['--disable-arc-opt-in-verification'] 4920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 5020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 5120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatdef post_processing_after_browser(chrome): 52c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 53c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld Called when a new browser instance has been initialized. 5420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 5520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat Note that this hook function is called regardless of arc_mode. 5620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 5720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat @param chrome: Chrome object. 58c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 5920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat """ 60b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez # Remove any stale dumpstate files. 61b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez if os.path.isfile(_DUMPSTATE_PATH): 62b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez os.unlink(_DUMPSTATE_PATH) 6320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 6431a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # Wait for Android container ready if ARC is enabled. 6531a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono if chrome.arc_mode == arc_common.ARC_MODE_ENABLED: 6631a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono try: 6731a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono arc_common.wait_for_android_boot() 6831a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono except Exception: 6931a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # Save dumpstate so that we can figure out why boot does not 7031a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # complete. 7131a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono _save_android_dumpstate() 7231a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono raise 7331a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono 7420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 7520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatdef pre_processing_before_close(chrome): 76c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 77c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld Called when the browser instance is being closed. 7820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 7920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat Note that this hook function is called regardless of arc_mode. 8020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 8120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat @param chrome: Chrome object. 82c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 8320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat """ 8420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat if not should_start_arc(chrome.arc_mode): 8520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat return 861565be1acdf46506acf71b67395f4296d94b0a13Junichi Uekawa # TODO(b/29341443): Implement stopping of adb logcat when we start adb 871565be1acdf46506acf71b67395f4296d94b0a13Junichi Uekawa # logcat for all tests 8820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 89b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez # Save dumpstate just before logout. 9031a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono _save_android_dumpstate() 91b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez 92b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez 93b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavezdef _save_android_dumpstate(timeout=_DUMPSTATE_DEFAULT_TIMEOUT): 94b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez """ 95b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez Triggers a dumpstate and saves its contents to to /var/log/arc-dumpstate.log 9631a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono with logging. 9731a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono 9831a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono Exception thrown while doing dumpstate will be ignored. 99b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez 100b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez @param timeout: The timeout in seconds. 101b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez """ 102b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez 10331a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono try: 10431a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono logging.info('Saving Android dumpstate.') 10531a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono with open(_DUMPSTATE_PATH, 'w') as out: 10631a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # _DUMPSTATE_PIPE_PATH is a named pipe, so it permanently blocks if 10731a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # opened normally if the other end has not been opened. In order to 10831a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # avoid that, open the file with O_NONBLOCK and use a select loop to 10931a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # read from the file with a timeout. 11031a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono fd = os.open(_DUMPSTATE_PIPE_PATH, os.O_RDONLY | os.O_NONBLOCK) 11131a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono with os.fdopen(fd, 'r') as pipe: 11231a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono end_time = time.time() + timeout 11331a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono while True: 11431a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono remaining_time = end_time - time.time() 11531a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono if remaining_time <= 0: 11631a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono break 11731a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono rlist, _, _ = select.select([pipe], [], [], remaining_time) 11831a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono if pipe not in rlist: 11931a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono break 12031a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono buf = os.read(pipe.fileno(), 1024) 12131a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono if len(buf) == 0: 12231a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono break 12331a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono out.write(buf) 12431a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono logging.info('Android dumpstate successfully saved.') 12531a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono except Exception: 12631a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono # Dumpstate is nice-to-have stuff. Do not make it as a fatal error. 12731a79e07cd33d9469c8bdc669c365df00da3b091Daichi Hirono logging.exception('Failed to save Android dumpstate.') 128b6168e5d23e8916922564de8823f0cd915260c53Luis Hector Chavez 12920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 13020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichatdef set_browser_options_for_opt_in(b_options): 131c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 132c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld Setup Chrome for gaia login and opt_in. 133c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 134c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld @param b_options: browser options object used by chrome.Chrome. 135c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 136c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 13720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat b_options.username = _USERNAME 13820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat with tempfile.NamedTemporaryFile() as pltp: 13990ba12ece4886e6deeed8849dd6c24b83f03e3e4Derek Basehore file_utils.download_file(_ARCP_URL, pltp.name) 14020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat b_options.password = pltp.read().rstrip() 14120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat b_options.disable_default_apps = False 14220257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat b_options.disable_component_extensions_with_background_pages = False 14320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat b_options.gaia_login = True 14420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 14520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 146ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkelddef enable_arc_setting(browser): 147c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 148ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld Enable ARC++ via the settings page checkbox. 149ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 150ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld Do nothing if the account is managed. 151c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 152c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld @param browser: chrome.Chrome broswer object. 153c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 154ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @returns: True if the opt-in should continue; else False. 155c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld 156c64d6f280cf6c327f88532e61317eb241840e494Katherine Threlkeld """ 157be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat settings_tab = browser.tabs.New() 15820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 15920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat try: 160ef2eaccbed2a30105e3b6efdeb0640923c5390f1khmel settings_tab.Navigate('chrome://settings-frame') 161be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat settings_tab.WaitForDocumentReadyStateToBeComplete() 162be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 163be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat try: 164be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat settings_tab.ExecuteJavaScript( 165be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 'assert(document.getElementById("android-apps-enabled"))') 166be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat except Exception, e: 167be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat raise error.TestFail('Could not locate section in chrome://settings' 168be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat ' to enable arc. Make sure ARC is available.') 169be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 170be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat # Skip enabling for managed users, since value is policy enforced. 171be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat # Return early if a managed user has ArcEnabled set to false. 172be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat is_managed = settings_tab.EvaluateJavaScript( 173be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 'document.getElementById("android-apps-enabled").disabled') 174be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat if is_managed: 175be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat logging.info('Determined that ARC is managed by user policy.') 176be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat policy_value = settings_tab.EvaluateJavaScript( 177be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 'document.getElementById("android-apps-enabled").checked') 178be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat if not policy_value: 179be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat logging.info( 180be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 'Returning early since ARC is policy-enforced off.') 181be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat return False 182be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat else: 183be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat settings_tab.ExecuteJavaScript( 184be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat 'Preferences.setBooleanPref("arc.enabled", true, true)') 185be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat finally: 186be39cd54afe24d6cc346689ab81c03147e7290efDaniel Erat settings_tab.Close() 18720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 188ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld return True 189ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 190ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 191ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkelddef find_opt_in_extension_page(browser): 192ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld """ 193ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld Find and verify the opt-in extension extension page. 194ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 195ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @param browser: chrome.Chrome broswer object. 196ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 197ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @returns: the extension page. 198ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 199ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @raises: error.TestFail if extension is not found or is mal-formed. 200ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 201ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld """ 202ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld opt_in_extension_id = extension_page.UrlToExtensionId(_ARC_SUPPORT_HOST_URL) 203ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld try: 204ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld extension_pages = browser.extensions.GetByExtensionId( 205ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld opt_in_extension_id) 206ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld except Exception, e: 2070c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld raise error.TestFail('Could not locate extension for arc opt-in. ' 2080c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld 'Make sure disable_default_apps is False. ' 2090c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld '"%s".' % e) 210ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 211ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld extension_main_page = None 212ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld for page in extension_pages: 213ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld url = page.EvaluateJavaScript('location.href;') 214ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld if url.endswith(_ARC_SUPPORT_HOST_PAGENAME): 215ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld extension_main_page = page 216ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld break 217ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld if not extension_main_page: 218ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld raise error.TestError('Found opt-in extension but not correct page!') 219ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld extension_main_page.WaitForDocumentReadyStateToBeComplete() 220ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 221dd18afb9a111c8f33e3821af5413cf9ad0497757Chung-yih Wang js_code_did_start_conditions = ['termsPage != null', 222952a041496fbdae50a01268edd01d1635d657f02Chung-yih Wang '(termsPage.isManaged_ || termsPage.state_ == LoadState.LOADED)'] 2230c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld try: 2240c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld for condition in js_code_did_start_conditions: 2250309dc99e4f2ffae6211c80e4e46a62579807486Achuith Bhandarkar extension_main_page.WaitForJavaScriptCondition(condition, 2260309dc99e4f2ffae6211c80e4e46a62579807486Achuith Bhandarkar timeout=60) 2270c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld except Exception, e: 2280c9b8816e646213e740ede2775bf20bfe8a00efeKatherine Threlkeld raise error.TestError('Error waiting for "%s": "%s".' % (condition, e)) 22920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 230ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld return extension_main_page 231ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 232ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 233867874a283bc8ae42b70c2df1c344d8b6ab9161eVictor Hsiehdef opt_in_and_wait_for_completion(extension_main_page): 234ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld """ 235867874a283bc8ae42b70c2df1c344d8b6ab9161eVictor Hsieh Step through the user input of the opt-in extension and wait for completion. 236ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 237ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @param extension_main_page: opt-in extension object. 238ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 239867874a283bc8ae42b70c2df1c344d8b6ab9161eVictor Hsieh @raises error.TestFail if opt-in doesn't complete after timeout. 240ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 241ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld """ 24220257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat js_code_click_agree = """ 24320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat doc = appWindow.contentWindow.document; 24420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat agree_button_element = doc.getElementById('button-agree'); 24520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat agree_button_element.click(); 24620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat """ 24720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat extension_main_page.ExecuteJavaScript(js_code_click_agree) 24820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 24920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat SIGN_IN_TIMEOUT = 120 25020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat try: 2510309dc99e4f2ffae6211c80e4e46a62579807486Achuith Bhandarkar extension_main_page.WaitForJavaScriptCondition('!appWindow', 2520309dc99e4f2ffae6211c80e4e46a62579807486Achuith Bhandarkar timeout=SIGN_IN_TIMEOUT) 25320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat except Exception, e: 25420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat js_read_error_message = """ 25520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat err = appWindow.contentWindow.document.getElementById( 25620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat "error-message"); 25720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat if (err) { 25820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat err.innerText; 25920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat } 26020257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat """ 26120257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat err_msg = extension_main_page.EvaluateJavaScript(js_read_error_message) 26220257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat err_msg = err_msg.strip() 26320257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat logging.error('Error: %s', err_msg.strip()) 26420257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat if err_msg: 26520257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat raise error.TestFail('Opt-in app error: %s' % err_msg) 26620257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat else: 26720257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat raise error.TestFail('Opt-in app did not finish running after %s ' 26820257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 'seconds!' % SIGN_IN_TIMEOUT) 26920257f0b6214b283f4821cde39425dfffba8b3b6Nicolas Boichat 270ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 271ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkelddef opt_in(browser): 272ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld """ 273ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld Step through opt in and wait for it to complete. 274ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 275ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld Return early if the arc_setting cannot be set True. 276ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 277ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @param browser: chrome.Chrome broswer object. 278ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 279ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld @raises: error.TestFail if opt in fails. 280ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld 281ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld """ 282ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld logging.info(_OPT_IN_BEGIN) 283ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld if not enable_arc_setting(browser): 284ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld return 285ba12a34aa06205a215e7908a9a1c1e3a332177e0Katherine Threlkeld extension_main_page = find_opt_in_extension_page(browser) 286867874a283bc8ae42b70c2df1c344d8b6ab9161eVictor Hsieh opt_in_and_wait_for_completion(extension_main_page) 287d33c21d5d384efdb53643bf1168b17628905ac68Ben Cheng logging.info(_OPT_IN_FINISH) 288