Index: tools/testing/webdriver_test_setup.py |
=================================================================== |
--- tools/testing/webdriver_test_setup.py (revision 0) |
+++ tools/testing/webdriver_test_setup.py (revision 0) |
@@ -0,0 +1,240 @@ |
+#!/usr/bin/python |
+ |
+# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
+# for details. All rights reserved. Use of this source code is governed by a |
+# BSD-style license that can be found in the LICENSE file. |
+ |
+# Run to install the necessary components to run webdriver on the buildbots or |
+# on your local machine. |
+# Note: The setup steps can be done fairly easily by hand. This script is |
+# intended to simply and reduce the time for setup since there are a fair number |
+# of steps. |
+ |
+# TODO(efortuna): Rewrite this script in Dart when the Process module has a |
+# better high level API. |
+import optparse |
+import os |
+import platform |
+import re |
+import subprocess |
+import sys |
+import urllib |
+import urllib2 |
+ |
+def run_cmd(cmd, stdin=None): |
+ """Run the command on the command line in the shell. We print the output of |
+ the command. |
+ """ |
+ print cmd |
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
+ stdin=subprocess.PIPE, shell=True) |
+ output, not_used = p.communicate(input=stdin) |
+ if output: |
+ print output |
+ |
+def parse_args(): |
+ parser = optparse.OptionParser() |
+ parser.add_option('--firefox', '-f', dest='firefox', help='Install Firefox', |
+ action='store_true', default=False) |
+ parser.add_option('--path', '-p', dest='path', help='Specify location ' + \ |
+ 'on your PATH for where we should install chromedriver (default is in' + \ |
+ 'depot_tools).', metavar='CHROMEDRIVER_LOC', type='str', action='store', |
+ default=None) |
+ parser.add_option('--buildbot', '-b', dest='buildbot', action='store_true', |
+ help='Perform a buildbot selenium setup (buildbots have a different' + \ |
+ 'location for their python executable).', default=False) |
+ args, ignored = parser.parse_args() |
+ return args |
+ |
+def find_depot_tools_location(is_buildbot): |
+ """Depot_tools is our default install location for chromedriver, so we find |
+ its location on the filesystem. |
+ Arguments: |
+ is_buildbot - True if we are running buildbot machine setup (we can't detect |
+ this automatically because this script is not run at build time). |
+ """ |
+ if is_buildbot: |
+ depot_tools = os.path.join('b', 'depot_tools') |
+ if 'win32' in sys.platform or 'cygwin' in sys.platform: |
+ depot_tools = os.path.join('e:', depot_tools) |
+ depot_tools = '/Users/efortuna' |
+ return depot_tools |
+ else: |
+ path = os.environ['PATH'].split(os.pathsep) |
+ for loc in path: |
+ if 'depot_tools' in loc: |
+ return loc |
+ raise Exception("Could not find depot_tools in your path.") |
+ |
+ |
+class GoogleCodeInstaller(object): |
+ """Install code that is being hosted on Google Code.""" |
+ |
+ def __init__(self, project_name, download_location, download_name_func): |
+ """ Create a object that will install code from a Google Code site. |
+ Arguments: |
+ project_name - The GoogleCode project name such as "selenium" or "chromium." |
+ download_location - Where to download the desired file on our filesystem. |
+ download_name_func - A function that takes a dictionary (currently with keys |
+ "os" and "version", but more can be added) that calculates the string |
+ representing the name of the download we want. |
+ """ |
+ self.project_name = project_name |
+ self.download_location = download_location |
+ self.download_name_func = download_name_func |
+ self.download_regex_str = self.download_name_func({'os': self.get_os_str, |
+ 'version': '.+'}) |
+ |
+ def google_code_downloads_page(self): |
+ return 'http://code.google.com/p/%s/downloads/list' % self.project_name |
+ |
+ def google_code_download(self): |
+ return 'http://%s.googlecode.com/files/' % self.project_name |
+ |
+ def find_latest_version(self): |
+ """Find the latest version number of some code available for download on a |
+ Google code page. This was unfortunately done in an ad hoc manner because |
+ Google Code does not seem to have an API for their list of current |
+ downloads(!). |
+ """ |
+ google_code_site = self.google_code_downloads_page() |
+ f = urllib2.urlopen(google_code_site) |
+ latest = '' |
+ for line in f.readlines(): |
+ if re.search(self.download_regex_str, line): |
+ suffix_index = line.find( |
+ self.download_regex_str[self.download_regex_str.rfind('.'):]) |
+ name_end = self.download_regex_str.rfind('.+') |
+ name = self.download_name_func({'os': self.get_os_str, 'version': ''}) |
+ name = name[:name.rfind('.')] |
+ version_str = line[line.find(name) + len(name) : suffix_index] |
+ if latest == '': |
+ latest = '0.' * version_str.count('.') |
+ latest += '0' |
+ nums = version_str.split('.') |
+ latest_nums = latest.split('.') |
+ for (num, latest_num) in zip(nums, latest_nums): |
+ if int(num) > int(latest_num): |
+ latest = version_str |
+ break |
+ if latest == '': |
+ raise Exception("Couldn't find the desired download on " + \ |
+ ' %s.' % google_code_site) |
+ return latest |
+ |
+ def run(self): |
+ """Download and install the Google Code.""" |
+ print 'Installing from %s' % self.project_name |
+ os_str = self.get_os_str |
+ version = self.find_latest_version() |
+ download_name = self.download_name_func({'os': os_str, 'version': version}) |
+ urllib.urlretrieve(self.google_code_download() + '/' + download_name, |
+ os.path.join(self.download_location, download_name)) |
+ if download_name.endswith('.zip'): |
+ run_cmd('unzip -u %s -d %s' % (os.path.join(self.download_location, |
+ download_name), self.download_location)) |
+ os.remove(os.path.join(self.download_location, download_name)) |
+ |
+ @property |
+ def get_os_str(self): |
+ """The strings to indicate what OS a download is for as used on Google Code. |
+ """ |
+ os_str = 'win' |
+ if 'darwin' in sys.platform: |
+ os_str = 'mac' |
+ elif 'linux' in sys.platform: |
+ os_str = 'linux32' |
+ if '64bit' in platform.architecture()[0]: |
+ os_str = 'linux64' |
+ return os_str |
+ |
+ |
+class FirefoxInstaller(object): |
+ """Installs the latest version of Firefox on the machine.""" |
+ |
+ def ff_download_site(self, os_name): |
+ return 'http://releases.mozilla.org/pub/mozilla.org/firefox/releases/' + \ |
+ 'latest/%s/en-US/' % os_name |
+ |
+ def get_os_str(self): |
+ """Returns the string that Mozilla uses to denote which operating system a |
+ Firefox binary is for.""" |
+ os_str = ('win32', '.exe') |
+ if 'darwin' in sys.platform: |
+ os_str = ('mac', '.dmg') |
+ elif 'linux' in sys.platform: |
+ os_str = ('linux-i686', '.tar.bz2') |
+ if '64bit' in platform.architecture()[0]: |
+ os_str = ('linux-x86_64', '.tar.bz2') |
+ return os_str |
+ |
+ def get_download_url(self): |
+ """Parse the html on the page to determine what is the latest download |
+ appropriate for our system.""" |
+ f = urllib2.urlopen(self.ff_download_site(self.get_os_str[0])) |
+ download_name = '' |
+ for line in f.readlines(): |
+ suffix = self.get_os_str[1] |
+ if (suffix + '"') in line: |
+ link_str = '<a href="' |
+ download_name = line[line.find(link_str) + len(link_str) : \ |
+ line.find(suffix) + len(suffix)] |
+ break |
+ return '%s%s' % (self.ff_download_site(self.get_os_str[0]), download_name) |
+ |
+ def run(self): |
+ print 'Installing Firefox' |
+ if 'darwin' in sys.platform: |
+ urllib.urlretrieve(self.get_download_url(), 'firefox.dmg') |
+ run_cmd('hdiutil mount firefox.dmg') |
+ run_cmd('sudo cp -R /Volumes/firefox/Firefox.app /Applications') |
+ run_cmd('hdiutil unmount /Volumes/firefox/') |
+ elif 'win' in sys.platform: |
+ urllib.urlretrieve(self.get_download_url(), 'firefox_install.exe') |
+ run_cmd('firefox_install.exe -ms') |
+ else: |
+ run_cmd('wget -O - %s | tar -C ~ -jxv' % self.get_download_url()) |
+ |
+ |
+class SeleniumBindingsInstaller(object): |
+ """Install the Selenium Webdriver bindings for Python.""" |
+ |
+ SETUPTOOLS_SITE = 'http://python-distribute.org/distribute_setup.py' |
+ PIP_SITE = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py' |
+ def __init__(self, is_buildbot): |
+ self.is_buildbot = is_buildbot |
+ |
+ def run(self): |
+ print 'Installing Selenium Python Bindings' |
+ admin_keyword = '' |
+ python_cmd = 'python' |
+ if 'win32' not in sys.platform and 'cygwin' not in sys.platform: |
+ admin_keyword = 'sudo' |
+ else: |
+ # The python installation is "special" on Windows buildbots. |
+ if is_buildbot: |
+ python_cmd = os.path.join(find_depot_tools_location(is_buildbot), |
+ 'python-bin', 'python') |
+ page = urllib2.urlopen(self.SETUPTOOLS_SITE) |
+ run_cmd('%s %s' % (admin_keyword, python_cmd), page.read()) |
+ page = urllib2.urlopen(self.PIP_SITE) |
+ run_cmd('%s %s' % (admin_keyword, python_cmd), page.read()) |
+ run_cmd('%s pip install -U selenium' % admin_keyword) |
+ |
+def main(): |
+ args = parse_args() |
+ SeleniumBindingsInstaller(args.buildbot).run() |
+ chromedriver_loc = find_depot_tools_location(args.buildbot) |
+ if args.path: |
+ chromedriver_loc = args.path |
+ GoogleCodeInstaller('chromium', chromedriver_loc, |
+ lambda x: 'chromedriver_%(os)s_%(version)s.zip' % x).run() |
+ if 'darwin' in sys.platform: |
+ GoogleCodeInstaller('selenium', os.path.dirname(os.path.abspath(__file__)), |
+ lambda x: 'selenium-server-standalone-%(version)s.jar' % x).run() |
+ |
+ if args.firefox: |
+ FirefoxInstaller().run() |
+ |
+if __name__ == '__main__': |
+ main() |
Property changes on: tools/testing/webdriver_test_setup.py |
___________________________________________________________________ |
Added: svn:executable |
+ * |