1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 """Test fixture for tests involving installing/updating Chrome. 6 7 Provides an interface to install or update chrome from within a testcase, and 8 allows users to run tests using installed version of Chrome. User and system 9 level installations are supported, and either one can be used for running the 10 tests. Currently the only platform it supports is Windows. 11 """ 12 13 import os 14 import sys 15 import unittest 16 import urllib 17 18 import chrome_installer_win 19 20 _DIRECTORY = os.path.dirname(os.path.abspath(__file__)) 21 sys.path.append(os.path.join(_DIRECTORY, os.path.pardir, os.path.pardir, 22 os.path.pardir, 'third_party', 'webdriver', 23 'pylib')) 24 sys.path.append(os.path.join(_DIRECTORY, os.path.pardir, os.path.pardir, 25 os.path.pardir, 'build', 'util', 'lib')) 26 27 # This import should go after sys.path is set appropriately. 28 from chrome import Chrome 29 from selenium import webdriver 30 import selenium.webdriver.chrome.service as service 31 from selenium.webdriver.chrome.service import WebDriverException 32 33 from common import util 34 35 36 class InstallTest(unittest.TestCase): 37 """Base updater test class. 38 39 All dependencies, like Chrome installers and ChromeDriver, are downloaded at 40 the beginning of the test. Dependencies are downloaded in the temp directory. 41 This download occurs only once, before the first test is executed. Each test 42 case starts an instance of ChromeDriver and terminates it upon completion. 43 All updater tests should derive from this class. 44 45 Example: 46 47 class SampleUpdater(InstallTest): 48 49 def testCanOpenGoogle(self): 50 self.Install(self.GetUpdateBuilds()[0]) 51 self.StartChrome() 52 self._driver.get('http://www.google.com/') 53 self.Install(self.GetUpdateBuilds()[1]) 54 self.StartChrome() 55 self._driver.get('http://www.google.org/') 56 57 Include the following in your updater test script to make it run standalone. 58 59 from install_test import Main 60 61 if __name__ == '__main__': 62 Main() 63 64 To fire off an updater test, use the command below. 65 python test_script.py --url=<URL> --update-builds=24.0.1299.0,24.0.1300.0 66 """ 67 68 _installer_paths = {} 69 _chrome_driver = '' 70 _installer_options = [] 71 _install_type = chrome_installer_win.InstallationType.USER 72 73 def __init__(self, methodName='runTest'): 74 unittest.TestCase.__init__(self, methodName) 75 self._driver = None 76 current_version = chrome_installer_win.ChromeInstallation.GetCurrent() 77 if current_version: 78 current_version.Uninstall() 79 80 def setUp(self): 81 """Called before each unittest to prepare the test fixture.""" 82 self._StartService() 83 84 def tearDown(self): 85 """Called at the end of each unittest to do any test related cleanup.""" 86 # Confirm ChromeDriver was instantiated, before attempting to quit. 87 if self._driver is not None: 88 try: 89 self._driver.quit() 90 except WebDriverException: 91 pass 92 self._service.stop() 93 self._installation.Uninstall() 94 95 def _StartService(self): 96 """Starts ChromeDriver service.""" 97 self._service = service.Service(InstallTest._chrome_driver) 98 self._service.start() 99 100 def StartChrome(self, caps={}, options=None): 101 """Creates a ChromeDriver instance. 102 103 If both caps and options have the same settings, the settings from options 104 will be used. 105 106 Args: 107 caps: Capabilities that will be passed to ChromeDriver. 108 options: ChromeOptions object that will be passed to ChromeDriver. 109 """ 110 self._driver = Chrome(self._service.service_url, caps, options) 111 112 def Install(self, build, master_pref=None): 113 """Helper method that installs the specified Chrome build. 114 115 Args: 116 build: Chrome version number that will be used for installation. 117 master_pref: Location of the master preferences file. 118 """ 119 if self._driver: 120 try: 121 self._driver.quit() 122 except WebDriverException: 123 pass 124 options = [] 125 options.extend(self._installer_options) 126 if self._install_type == chrome_installer_win.InstallationType.SYSTEM: 127 options.append('--system-level') 128 if master_pref: 129 options.append('--installerdata=%s' % master_pref) 130 self._installation = chrome_installer_win.Install( 131 self._installer_paths[build], 132 self._install_type, 133 build, 134 options) 135 136 def GetInstallBuild(self): 137 """Returns Chorme build to be used for install test scenarios.""" 138 return self._install_build 139 140 def GetUpdateBuilds(self): 141 """Returns Chrome builds to be used for update test scenarios.""" 142 return self._update_builds 143 144 @staticmethod 145 def _Download(url, path): 146 """Downloads a file from the specified URL. 147 148 Args: 149 url: URL where the file is located. 150 path: Location where file will be downloaded. 151 152 Raises: 153 RuntimeError: URL or file name is invalid. 154 """ 155 if not util.DoesUrlExist(url): 156 raise RuntimeError('Either the URL or the file name is invalid.') 157 urllib.urlretrieve(url, path) 158 159 @staticmethod 160 def SetInstallType(install_type): 161 """Sets Chrome installation type. 162 163 Args: 164 install_type: Type of installation(i.e., user or system). 165 """ 166 InstallTest._install_type = install_type 167 168 @staticmethod 169 def InitTestFixture(install_build, update_builds, base_url, options): 170 """Static method for passing command options to InstallTest. 171 172 We do not instantiate InstallTest. Therefore, command arguments cannot be 173 passed to its constructor. Since InstallTest needs to use these options, 174 and using globals is not an option, this method can be used by the Main 175 class to pass the arguments it parses onto InstallTest. 176 177 Args: 178 install_build: A string representing the Chrome build to be used for 179 install testing. Pass this argument only if testing 180 fresh install scenarios. 181 update_builds: A list that contains the Chrome builds to be used for 182 testing update scenarios. Pass this argument only if 183 testing upgrade scenarios. 184 base_url: Base url of the 'official chrome builds' page. 185 options: A list that contains options to be passed to Chrome installer. 186 """ 187 system = util.GetPlatformName() 188 InstallTest._install_build = install_build 189 InstallTest._update_builds = update_builds 190 InstallTest._installer_options = options 191 tempdir = util.MakeTempDir() 192 builds = [] 193 if InstallTest._install_build: 194 builds.append(InstallTest._install_build) 195 if InstallTest._update_builds: 196 builds.extend(InstallTest._update_builds) 197 # Remove any duplicate build numbers. 198 builds = list(frozenset(builds)) 199 for build in builds: 200 url = '%s%s/%s/mini_installer.exe' % (base_url, build, system) 201 installer_path = os.path.join(tempdir, 'mini_installer_%s.exe' % build) 202 InstallTest._installer_paths[build] = installer_path 203 InstallTest._Download(url, installer_path) 204 InstallTest._chrome_driver = os.path.join(tempdir, 'chromedriver.exe') 205 url = '%s%s/%s/%s/chromedriver.exe' % (base_url, build, system, 206 'chrome-win32.test') 207 InstallTest._Download(url, InstallTest._chrome_driver) 208