blob: bef878bb385d839244b31dba5267aa1f64ccace5 [file] [log] [blame]
# 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.
"""Test fixture for tests involving installing/updating Chrome.
Provides an interface to install or update chrome from within a testcase, and
allows users to run tests using installed version of Chrome. User and system
level installations are supported, and either one can be used for running the
tests. Currently the only platform it supports is Windows.
"""
import os
import sys
import unittest
import urllib
import chrome_installer_win
_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(_DIRECTORY, os.path.pardir, os.path.pardir,
os.path.pardir, 'third_party', 'webdriver',
'pylib'))
sys.path.append(os.path.join(_DIRECTORY, os.path.pardir, os.path.pardir,
os.path.pardir, 'build', 'util', 'lib'))
# This import should go after sys.path is set appropriately.
from chrome import Chrome
from selenium import webdriver
import selenium.webdriver.chrome.service as service
from selenium.webdriver.chrome.service import WebDriverException
from common import util
class InstallTest(unittest.TestCase):
"""Base updater test class.
All dependencies, like Chrome installers and ChromeDriver, are downloaded at
the beginning of the test. Dependencies are downloaded in the temp directory.
This download occurs only once, before the first test is executed. Each test
case starts an instance of ChromeDriver and terminates it upon completion.
All updater tests should derive from this class.
Example:
class SampleUpdater(InstallTest):
def testCanOpenGoogle(self):
self.Install(self.GetUpdateBuilds()[0])
self.StartChrome()
self._driver.get('http://www.google.com/')
self.Install(self.GetUpdateBuilds()[1])
self.StartChrome()
self._driver.get('http://www.google.org/')
Include the following in your updater test script to make it run standalone.
from install_test import Main
if __name__ == '__main__':
Main()
To fire off an updater test, use the command below.
python test_script.py --url=<URL> --update-builds=24.0.1299.0,24.0.1300.0
"""
_installer_paths = {}
_chrome_driver = ''
_installer_options = []
_install_type = chrome_installer_win.InstallationType.USER
def __init__(self, methodName='runTest'):
unittest.TestCase.__init__(self, methodName)
self._driver = None
current_version = chrome_installer_win.ChromeInstallation.GetCurrent()
if current_version:
current_version.Uninstall()
def setUp(self):
"""Called before each unittest to prepare the test fixture."""
self._StartService()
def tearDown(self):
"""Called at the end of each unittest to do any test related cleanup."""
# Confirm ChromeDriver was instantiated, before attempting to quit.
if self._driver is not None:
try:
self._driver.quit()
except WebDriverException:
pass
self._service.stop()
self._installation.Uninstall()
def _StartService(self):
"""Starts ChromeDriver service."""
self._service = service.Service(InstallTest._chrome_driver)
self._service.start()
def StartChrome(self, caps={}, options=None):
"""Creates a ChromeDriver instance.
If both caps and options have the same settings, the settings from options
will be used.
Args:
caps: Capabilities that will be passed to ChromeDriver.
options: ChromeOptions object that will be passed to ChromeDriver.
"""
self._driver = Chrome(self._service.service_url, caps, options)
def Install(self, build, master_pref=None):
"""Helper method that installs the specified Chrome build.
Args:
build: Chrome version number that will be used for installation.
master_pref: Location of the master preferences file.
"""
if self._driver:
try:
self._driver.quit()
except WebDriverException:
pass
options = []
options.extend(self._installer_options)
if self._install_type == chrome_installer_win.InstallationType.SYSTEM:
options.append('--system-level')
if master_pref:
options.append('--installerdata=%s' % master_pref)
self._installation = chrome_installer_win.Install(
self._installer_paths[build],
self._install_type,
build,
options)
def GetInstallBuild(self):
"""Returns Chorme build to be used for install test scenarios."""
return self._install_build
def GetUpdateBuilds(self):
"""Returns Chrome builds to be used for update test scenarios."""
return self._update_builds
@staticmethod
def _Download(url, path):
"""Downloads a file from the specified URL.
Args:
url: URL where the file is located.
path: Location where file will be downloaded.
Raises:
RuntimeError: URL or file name is invalid.
"""
if not util.DoesUrlExist(url):
raise RuntimeError('Either the URL or the file name is invalid.')
urllib.urlretrieve(url, path)
@staticmethod
def SetInstallType(install_type):
"""Sets Chrome installation type.
Args:
install_type: Type of installation(i.e., user or system).
"""
InstallTest._install_type = install_type
@staticmethod
def InitTestFixture(install_build, update_builds, base_url, options):
"""Static method for passing command options to InstallTest.
We do not instantiate InstallTest. Therefore, command arguments cannot be
passed to its constructor. Since InstallTest needs to use these options,
and using globals is not an option, this method can be used by the Main
class to pass the arguments it parses onto InstallTest.
Args:
install_build: A string representing the Chrome build to be used for
install testing. Pass this argument only if testing
fresh install scenarios.
update_builds: A list that contains the Chrome builds to be used for
testing update scenarios. Pass this argument only if
testing upgrade scenarios.
base_url: Base url of the 'official chrome builds' page.
options: A list that contains options to be passed to Chrome installer.
"""
system = util.GetPlatformName()
InstallTest._install_build = install_build
InstallTest._update_builds = update_builds
InstallTest._installer_options = options
tempdir = util.MakeTempDir()
builds = []
if InstallTest._install_build:
builds.append(InstallTest._install_build)
if InstallTest._update_builds:
builds.extend(InstallTest._update_builds)
# Remove any duplicate build numbers.
builds = list(frozenset(builds))
for build in builds:
url = '%s%s/%s/mini_installer.exe' % (base_url, build, system)
installer_path = os.path.join(tempdir, 'mini_installer_%s.exe' % build)
InstallTest._installer_paths[build] = installer_path
InstallTest._Download(url, installer_path)
InstallTest._chrome_driver = os.path.join(tempdir, 'chromedriver.exe')
url = '%s%s/%s/%s/chromedriver.exe' % (base_url, build, system,
'chrome-win32.test')
InstallTest._Download(url, InstallTest._chrome_driver)