| Index: third_party/polymer/components/web-animations-js/tools/python/run-tests.py
|
| diff --git a/third_party/polymer/components/web-animations-js/tools/python/run-tests.py b/third_party/polymer/components/web-animations-js/tools/python/run-tests.py
|
| deleted file mode 100755
|
| index d87bef92b81b37d04605b923f82cef4248094f70..0000000000000000000000000000000000000000
|
| --- a/third_party/polymer/components/web-animations-js/tools/python/run-tests.py
|
| +++ /dev/null
|
| @@ -1,813 +0,0 @@
|
| -#!/usr/bin/python
|
| -#
|
| -# -*- coding: utf-8 -*-
|
| -# vim: set ts=4 sw=4 et sts=4 ai:
|
| -
|
| -import atexit
|
| -import base64
|
| -import cStringIO as StringIO
|
| -import getpass
|
| -import httplib
|
| -import json as simplejson
|
| -import os
|
| -import platform
|
| -import pprint
|
| -import re
|
| -import socket
|
| -import sys
|
| -import time
|
| -import urllib2
|
| -import zipfile
|
| -
|
| -import argparse
|
| -parser = argparse.ArgumentParser()
|
| -
|
| -parser.add_argument(
|
| - "-b", "--browser", type=str, required=True,
|
| - choices=['Firefox', 'Chrome', 'Ie', 'PhantomJS', 'Remote'],
|
| - help="Which WebDriver to use.")
|
| -
|
| -parser.add_argument(
|
| - "-f", "--flag", action='append', default=[],
|
| - help="Command line flags to pass to the browser, "
|
| - "currently only available for Chrome. "
|
| - "Each flag must be a separate --flag invoccation.")
|
| -
|
| -parser.add_argument(
|
| - "-x", "--virtual", action='store_true', default=False,
|
| - help="Use a virtual screen system such as Xvfb, Xephyr or Xvnc.")
|
| -
|
| -parser.add_argument(
|
| - "-d", "--dontexit", action='store_true', default=False,
|
| - help="At end of testing, don't exit.")
|
| -
|
| -parser.add_argument(
|
| - "-v", "--verbose", action='store_true', default=False,
|
| - help="Output more information.")
|
| -
|
| -parser.add_argument(
|
| - "-u", "--upload", action='store_true', default=False,
|
| - help="Upload images to picture sharing site (http://postimage.org/),"
|
| - " only really useful for testbots.")
|
| -
|
| -# Only used by the Remote browser option.
|
| -parser.add_argument(
|
| - "--remote-executor", type=str,
|
| - help="Location of the Remote executor.")
|
| -
|
| -parser.add_argument(
|
| - "--remote-caps", action='append',
|
| - help="Location of capabilities to request on Remote executor.",
|
| - default=[])
|
| -
|
| -parser.add_argument(
|
| - "-s", "--sauce", action='store_true', default=False,
|
| - help="Use the SauceLab's Selenium farm rather then locally starting"
|
| - " selenium. SAUCE_USERNAME and SAUCE_ACCESS_KEY must be set in"
|
| - " environment.")
|
| -
|
| -# Subunit / testrepository support
|
| -parser.add_argument(
|
| - "--subunit", action='store_true', default=False,
|
| - help="Output raw subunit binary data.")
|
| -
|
| -parser.add_argument(
|
| - "--list", action='store_true', default=False,
|
| - help="List tests which are available.")
|
| -
|
| -parser.add_argument(
|
| - "--load-list", type=argparse.FileType('r'),
|
| - help="List of tests to run.")
|
| -
|
| -args = parser.parse_args()
|
| -
|
| -if args.verbose and args.subunit:
|
| - raise SystemExit("--verbose and --subunit are not compatible.")
|
| -
|
| -# Make sure the repository is setup and the dependencies exist
|
| -# -----------------------------------------------------------------------------
|
| -
|
| -import subprocess
|
| -
|
| -caps = {}
|
| -if not args.sauce:
|
| - # Get any selenium drivers we might need
|
| - if args.browser == "Chrome":
|
| - # Get ChromeDriver if it's not in the path...
|
| - # https://code.google.com/p/chromedriver/downloads/list
|
| - chromedriver_bin = "chromedriver"
|
| - chromedriver_url_tmpl = "http://chromedriver.storage.googleapis.com/2.6/chromedriver_%s%s.zip" # noqa
|
| -
|
| - if platform.system() == "Linux":
|
| - if platform.processor() == "x86_64":
|
| - # 64 bit binary needed
|
| - chromedriver_url = chromedriver_url_tmpl % ("linux", "64")
|
| - else:
|
| - # 32 bit binary needed
|
| - chromedriver_url = chromedriver_url_tmpl % ("linux", "32")
|
| -
|
| - elif platform.system() == "Darwin":
|
| - chromedriver_url = chromedriver_url_tmpl % ("mac", "32")
|
| - elif platform.system() == "win32":
|
| - chromedriver_url = chromedriver_url_tmpl % ("win", "32")
|
| - chromedriver_url = "chromedriver.exe"
|
| -
|
| - try:
|
| - if subprocess.call(chromedriver_bin) != 0:
|
| - raise OSError("Return code?")
|
| - except OSError:
|
| - chromedriver_local = os.path.join("tools", chromedriver_bin)
|
| -
|
| - if not os.path.exists(chromedriver_local):
|
| - datafile = StringIO.StringIO(
|
| - urllib2.urlopen(chromedriver_url).read())
|
| - contents = zipfile.ZipFile(datafile, 'r')
|
| - contents.extract(chromedriver_bin, "tools")
|
| -
|
| - chromedriver = os.path.realpath(chromedriver_local)
|
| - os.chmod(chromedriver, 0755)
|
| - else:
|
| - chromedriver = "chromedriver"
|
| -
|
| - elif args.browser == "Firefox":
|
| - pass
|
| -
|
| - elif args.browser == "PhantomJS":
|
| - phantomjs_bin = None
|
| - if platform.system() == "Linux":
|
| - phantomjs_bin = "phantomjs"
|
| - if platform.processor() == "x86_64":
|
| - # 64 bit binary needed
|
| - phantomjs_url = "https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-x86_64.tar.bz2" # noqa
|
| - else:
|
| - # 32 bit binary needed
|
| - phantomjs_url = "https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-i686.tar.bz2" # noqa
|
| -
|
| - phantomjs_local = os.path.join("tools", phantomjs_bin)
|
| - if not os.path.exists(phantomjs_local):
|
| - datafile = StringIO.StringIO(
|
| - urllib2.urlopen(phantomjs_url).read())
|
| - contents = tarfile.TarFile.open(fileobj=datafile, mode='r:bz2')
|
| - file("tools/"+phantomjs_bin, "w").write(
|
| - contents.extractfile(
|
| - "phantomjs-1.9.0-linux-x86_64/bin/"+phantomjs_bin
|
| - ).read())
|
| -
|
| - phantomjs = os.path.realpath(phantomjs_local)
|
| - os.chmod(phantomjs, 0755)
|
| - else:
|
| - if platform.system() == "Darwin":
|
| - phantomjs_url = "https://phantomjs.googlecode.com/files/phantomjs-1.9.0-macosx.zip" # noqa
|
| - phantomjs_bin = "phantomjs"
|
| -
|
| - elif platform.system() == "win32":
|
| - chromedriver_bin = "https://phantomjs.googlecode.com/files/phantomjs-1.9.0-windows.zip" # noqa
|
| - phantomjs_url = "phantomjs.exe"
|
| -
|
| - phantomjs_local = os.path.join("tools", phantomjs_bin)
|
| - if not os.path.exists(phantomjs_local):
|
| - datafile = StringIO.StringIO(
|
| - urllib2.urlopen(phantomjs_url).read())
|
| - contents = zipfile.ZipFile(datafile, 'r')
|
| - contents.extract(phantomjs_bin, "tools")
|
| -
|
| - phantomjs = os.path.realpath(phantomjs_local)
|
| - os.chmod(phantomjs, 0755)
|
| -else:
|
| - assert os.environ['SAUCE_USERNAME']
|
| - assert os.environ['SAUCE_ACCESS_KEY']
|
| - sauce_username = os.environ['SAUCE_USERNAME']
|
| - sauce_access_key = os.environ['SAUCE_ACCESS_KEY']
|
| -
|
| - # Download the Sauce Connect script
|
| - sauce_connect_url = "http://saucelabs.com/downloads/Sauce-Connect-latest.zip" # noqa
|
| - sauce_connect_bin = "Sauce-Connect.jar"
|
| - sauce_connect_local = os.path.join("tools", sauce_connect_bin)
|
| - if not os.path.exists(sauce_connect_local):
|
| - datafile = StringIO.StringIO(urllib2.urlopen(sauce_connect_url).read())
|
| - contents = zipfile.ZipFile(datafile, 'r')
|
| - contents.extract(sauce_connect_bin, "tools")
|
| -
|
| - if 'TRAVIS_JOB_NUMBER' in os.environ:
|
| - tunnel_id = os.environ['TRAVIS_JOB_NUMBER']
|
| - else:
|
| - tunnel_id = "%s:%s" % (socket.gethostname(), os.getpid())
|
| - args.remote_caps.append('tunnel-identifier=%s' % tunnel_id)
|
| -
|
| - # Kill the tunnel when we die
|
| - def kill_tunnel(sauce_tunnel):
|
| - if sauce_tunnel.returncode is None:
|
| - sauce_tunnel.terminate()
|
| -
|
| - timeout = time.time()
|
| - while sauce_tunnel.poll() is None:
|
| - if time.time() - timeout < 30:
|
| - time.sleep(1)
|
| - else:
|
| - sauce_tunnel.kill()
|
| -
|
| - readyfile = "."+tunnel_id
|
| - sauce_tunnel = None
|
| - try:
|
| - sauce_log = file("sauce_tunnel.log", "w")
|
| - sauce_tunnel = subprocess.Popen(
|
| - ["java", "-jar", sauce_connect_local,
|
| - "--readyfile", readyfile,
|
| - "--tunnel-identifier", tunnel_id,
|
| - sauce_username, sauce_access_key],
|
| - stdout=sauce_log, stderr=sauce_log)
|
| -
|
| - atexit.register(kill_tunnel, sauce_tunnel)
|
| -
|
| - # Wait for the tunnel to come up
|
| - while not os.path.exists(readyfile):
|
| - time.sleep(0.5)
|
| -
|
| - except:
|
| - if sauce_tunnel:
|
| - kill_tunnel(sauce_tunnel)
|
| - raise
|
| -
|
| - args.remote_executor = "http://%s:%s@localhost:4445/wd/hub" % (
|
| - sauce_username, sauce_access_key)
|
| -
|
| - custom_data = {}
|
| - git_info = subprocess.Popen(
|
| - ["git", "describe", "--all", "--long"], stdout=subprocess.PIPE
|
| - ).communicate()[0]
|
| - custom_data["git-info"] = git_info
|
| -
|
| - git_commit = subprocess.Popen(
|
| - ["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE
|
| - ).communicate()[0]
|
| - custom_data["git-commit"] = git_commit
|
| -
|
| - caps['tags'] = []
|
| - if 'TRAVIS_BUILD_NUMBER' in os.environ:
|
| - # Send travis information upstream
|
| - caps['build'] = "%s %s" % (
|
| - os.environ['TRAVIS_REPO_SLUG'],
|
| - os.environ['TRAVIS_BUILD_NUMBER'],
|
| - )
|
| - caps['name'] = "Travis run for %s" % os.environ['TRAVIS_REPO_SLUG']
|
| -
|
| - caps['tags'].append(
|
| - "repo=%s" % os.environ['TRAVIS_REPO_SLUG'])
|
| - caps['tags'].append(
|
| - "branch=%s" % os.environ['TRAVIS_BRANCH'])
|
| -
|
| - travis_env = [
|
| - 'TRAVIS_BRANCH',
|
| - 'TRAVIS_BUILD_ID',
|
| - 'TRAVIS_BUILD_NUMBER',
|
| - 'TRAVIS_COMMIT',
|
| - 'TRAVIS_COMMIT_RANGE',
|
| - 'TRAVIS_JOB_ID',
|
| - 'TRAVIS_JOB_NUMBER',
|
| - 'TRAVIS_PULL_REQUEST',
|
| - 'TRAVIS_REPO_SLUG',
|
| - ]
|
| -
|
| - for env in travis_env:
|
| - tag = env[len('TRAVIS_'):].lower()
|
| - value = os.environ.get(env, None)
|
| - if not value:
|
| - continue
|
| - custom_data[tag] = value
|
| -
|
| - custom_data["github-url"] = (
|
| - "https://github.com/%s/tree/%s" % (
|
| - os.environ['TRAVIS_REPO_SLUG'], git_commit))
|
| - custom_data["travis-url"] = (
|
| - "https://travis-ci.org/%s/builds/%s" % (
|
| - os.environ['TRAVIS_REPO_SLUG'],
|
| - os.environ['TRAVIS_BUILD_ID']))
|
| - else:
|
| - # Collect information about who/what is running the test
|
| - caps['name'] = "Manual run for %s" % getpass.getuser()
|
| - caps['build'] = git_info
|
| -
|
| - caps['tags'].append('user=%s' % getpass.getuser())
|
| - caps['tags'].append('host=%s' % socket.gethostname())
|
| -
|
| -# -----------------------------------------------------------------------------
|
| -
|
| -import subunit
|
| -import testtools
|
| -
|
| -if args.list:
|
| - data = file("test/testcases.js").read()
|
| - for test in re.compile("(?<=').+(?=')").findall(data):
|
| - print test[:-5]
|
| - sys.exit(-1)
|
| -
|
| -if args.load_list:
|
| - tests = list(set(x.split(':')[0].strip()+'.html'
|
| - for x in args.load_list.readlines()))
|
| -else:
|
| - tests = []
|
| -
|
| -# Collect summary of all the individual test runs
|
| -summary = testtools.StreamSummary()
|
| -
|
| -# Output information to stdout
|
| -if not args.subunit:
|
| - # Output test failures
|
| - result_streams = [testtools.TextTestResult(sys.stdout)]
|
| - if args.verbose:
|
| - import unittest
|
| - # Output individual test progress
|
| - result_streams.insert(0,
|
| - unittest.TextTestResult(
|
| - unittest.runner._WritelnDecorator(sys.stdout), False, 2))
|
| - # Human readable test output
|
| - pertest = testtools.StreamToExtendedDecorator(
|
| - testtools.MultiTestResult(*result_streams))
|
| -else:
|
| - from subunit.v2 import StreamResultToBytes
|
| - pertest = StreamResultToBytes(sys.stdout)
|
| -
|
| - if args.list:
|
| - output = subunit.CopyStreamResult([summary, pertest])
|
| - output.startTestRun()
|
| - for test in re.compile("(?<=').+(?=')").findall(
|
| - file("test/testcases.js").read()):
|
| - output.status(test_status='exists', test_id=test[:-5])
|
| -
|
| - output.stopTestRun()
|
| - sys.exit(-1)
|
| -
|
| -output = subunit.CopyStreamResult([summary, pertest])
|
| -output.startTestRun()
|
| -
|
| -# Start up a local HTTP server which serves the files to the browser and
|
| -# collects the test results.
|
| -# -----------------------------------------------------------------------------
|
| -import SimpleHTTPServer
|
| -import SocketServer
|
| -import threading
|
| -import cgi
|
| -import re
|
| -
|
| -import itertools
|
| -import mimetools
|
| -import mimetypes
|
| -
|
| -
|
| -class MultiPartForm(object):
|
| - """Accumulate the data to be used when posting a form."""
|
| -
|
| - def __init__(self):
|
| - self.form_fields = []
|
| - self.files = []
|
| - self.boundary = mimetools.choose_boundary()
|
| - return
|
| -
|
| - def get_content_type(self):
|
| - return 'multipart/form-data; boundary=%s' % self.boundary
|
| -
|
| - def add_field(self, name, value):
|
| - """Add a simple field to the form data."""
|
| - self.form_fields.append((name, value))
|
| - return
|
| -
|
| - def add_file(self, fieldname, filename, fileHandle, mimetype=None):
|
| - """Add a file to be uploaded."""
|
| - body = fileHandle.read()
|
| - if mimetype is None:
|
| - mimetype = (
|
| - mimetypes.guess_type(filename)[0] or
|
| - 'application/octet-stream')
|
| - self.files.append((fieldname, filename, mimetype, body))
|
| - return
|
| -
|
| - def __str__(self):
|
| - """Return a string representing the form data, with attached files."""
|
| - # Build a list of lists, each containing "lines" of the
|
| - # request. Each part is separated by a boundary string.
|
| - # Once the list is built, return a string where each
|
| - # line is separated by '\r\n'.
|
| - parts = []
|
| - part_boundary = '--' + self.boundary
|
| -
|
| - # Add the form fields
|
| - parts.extend([
|
| - part_boundary,
|
| - 'Content-Disposition: form-data; name="%s"' % name,
|
| - '',
|
| - value,
|
| - ] for name, value in self.form_fields)
|
| -
|
| - # Add the files to upload
|
| - parts.extend([
|
| - part_boundary,
|
| - 'Content-Disposition: file; name="%s"; filename="%s"' % (
|
| - field_name, filename),
|
| - 'Content-Type: %s' % content_type,
|
| - '',
|
| - body,
|
| - ] for field_name, filename, content_type, body in self.files)
|
| -
|
| - # Flatten the list and add closing boundary marker,
|
| - # then return CR+LF separated data
|
| - flattened = list(str(b) for b in itertools.chain(*parts))
|
| - flattened.append('--' + self.boundary + '--')
|
| - flattened.append('')
|
| - return '\r\n'.join(flattened)
|
| -
|
| -
|
| -critical_failure = False
|
| -
|
| -
|
| -class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
| - STATUS = {0: 'success', 1: 'fail', 2: 'fail', 3: 'skip'}
|
| -
|
| - # Make the HTTP requests be quiet
|
| - def log_message(self, format, *a):
|
| - if args.verbose:
|
| - SimpleHTTPServer.SimpleHTTPRequestHandler.log_message(
|
| - self, format, *a)
|
| -
|
| - def do_POST(self):
|
| - global critical_failure
|
| - already_failed = critical_failure
|
| -
|
| - form = cgi.FieldStorage(
|
| - fp=self.rfile,
|
| - headers=self.headers,
|
| - environ={
|
| - 'REQUEST_METHOD': 'POST',
|
| - 'CONTENT_TYPE': self.headers['Content-Type'],
|
| - })
|
| -
|
| - overall_status = 0
|
| - test_id = None
|
| - try:
|
| - json_data = form.getvalue('data')
|
| - data = simplejson.loads(json_data)
|
| - except ValueError, e:
|
| - critical_failure = True
|
| -
|
| - test_id = "CRITICAL-FAILURE"
|
| -
|
| - msg = "Unable to decode JSON object (%s)\n%s" % (e, json_data)
|
| - overall_status = 1
|
| - output.status(
|
| - test_id="CRITICAL-FAILURE",
|
| - test_status='fail',
|
| - test_tags=[args.browser],
|
| - file_name='traceback',
|
| - file_bytes=msg,
|
| - mime_type='text/plain; charset=UTF-8',
|
| - eof=True)
|
| - else:
|
| - test_id = data['testName'][:-5]
|
| - for result in data['results']:
|
| - info = dict(result)
|
| - info.pop('_structured_clone', None)
|
| -
|
| - if not isinstance(result['message'], (str, unicode)):
|
| - msg = str(result['message'])
|
| - else:
|
| - msg = result['message']
|
| -
|
| - overall_status += result['status']
|
| - output.status(
|
| - test_id="%s:%s" % (test_id, result['name']),
|
| - test_status=self.STATUS[result['status']],
|
| - test_tags=[args.browser],
|
| - file_name='traceback',
|
| - file_bytes=msg,
|
| - mime_type='text/plain; charset=UTF-8',
|
| - eof=True)
|
| -
|
| - if args.verbose and 'debug' in data and overall_status > 0:
|
| - output.status(
|
| - test_id="%s:debug-log" % (test_id),
|
| - test_status='fail',
|
| - test_tags=[args.browser],
|
| - file_name='traceback',
|
| - file_bytes=data['debug'],
|
| - mime_type='text/plain; charset=UTF-8',
|
| - eof=True)
|
| -
|
| - # Take a screenshot of result if a failure occurred.
|
| - if overall_status > 0 and (args.virtual or args.browser == "Remote"):
|
| - time.sleep(1)
|
| -
|
| - try:
|
| - screenshot = test_id + '.png'
|
| - if args.virtual:
|
| - disp.grab().save(screenshot)
|
| - elif args.browser == "Remote":
|
| - global browser
|
| - browser.save_screenshot(screenshot)
|
| -
|
| - # On android we want to do a
|
| - # adb run /system/bin/screencap -p /sdcard/FILENAME.png
|
| - # adb cp FILENAME.png ....
|
| -
|
| - if args.upload and not already_failed:
|
| - form = MultiPartForm()
|
| - form.add_field('adult', 'no')
|
| - form.add_field('optsize', '0')
|
| - form.add_file(
|
| - 'upload[]', screenshot, fileHandle=open(screenshot, 'rb'))
|
| -
|
| - request = urllib2.Request("http://postimage.org/")
|
| - body = str(form)
|
| - request.add_header('Content-type', form.get_content_type())
|
| - request.add_header('Content-length', len(body))
|
| - request.add_data(body)
|
| -
|
| - result = urllib2.urlopen(request).read()
|
| - print "Screenshot at:", re.findall("""<td><textarea wrap='off' onmouseover='this.focus\(\)' onfocus='this.select\(\)' id="code_1" scrolling="no">([^<]*)</textarea></td>""", result) # noqa
|
| - except Exception, e:
|
| - print e
|
| -
|
| - response = "OK"
|
| - self.send_response(200)
|
| - self.send_header("Content-type", "text/plain")
|
| - self.send_header("Content-length", len(response))
|
| - self.end_headers()
|
| - self.wfile.write(response)
|
| - self.wfile.close()
|
| -
|
| -if args.sauce:
|
| - port = 55001
|
| -else:
|
| - port = 0 # Bind to any port on localhost
|
| -
|
| -while True:
|
| - try:
|
| - httpd = SocketServer.TCPServer(
|
| - ("127.0.0.1", port),
|
| - ServerHandler)
|
| - break
|
| - except socket.error as e:
|
| - print e
|
| - time.sleep(5)
|
| -
|
| -port = httpd.socket.getsockname()[-1]
|
| -print "Serving at", port
|
| -
|
| -httpd_thread = threading.Thread(target=httpd.serve_forever)
|
| -httpd_thread.daemon = True
|
| -httpd_thread.start()
|
| -
|
| -
|
| -# Start up a virtual display, useful for testing on headless servers.
|
| -# -----------------------------------------------------------------------------
|
| -
|
| -VIRTUAL_SIZE = (1024, 2000)
|
| -
|
| -# PhantomJS doesn't need a display
|
| -disp = None
|
| -if args.virtual and args.browser != "PhantomJS":
|
| - from pyvirtualdisplay.smartdisplay import SmartDisplay
|
| -
|
| - try:
|
| - disp = SmartDisplay(
|
| - visible=0, bgcolor='black', size=VIRTUAL_SIZE).start()
|
| - atexit.register(disp.stop)
|
| - except:
|
| - if disp:
|
| - disp.stop()
|
| - raise
|
| -
|
| -
|
| -# Start up the web browser and run the tests.
|
| -# ----------------------------------------------------------------------------
|
| -
|
| -from selenium import webdriver
|
| -from selenium.common import exceptions as selenium_exceptions
|
| -from selenium.webdriver.common.keys import Keys as selenium_keys
|
| -
|
| -driver_arguments = {}
|
| -if args.browser == "Chrome":
|
| - import tempfile
|
| - import shutil
|
| -
|
| - # We reference shutil to make sure it isn't garbaged collected before we
|
| - # use it.
|
| - def directory_cleanup(directory, shutil=shutil):
|
| - try:
|
| - shutil.rmtree(directory)
|
| - except OSError, e:
|
| - pass
|
| -
|
| - try:
|
| - user_data_dir = tempfile.mkdtemp()
|
| - atexit.register(directory_cleanup, user_data_dir)
|
| - except:
|
| - directory_cleanup(user_data_dir)
|
| - raise
|
| -
|
| - driver_arguments['chrome_options'] = webdriver.ChromeOptions()
|
| - # Make printable
|
| - webdriver.ChromeOptions.__repr__ = lambda self: str(self.__dict__)
|
| - chrome_flags = [
|
| - '--user-data-dir=%s' % user_data_dir,
|
| - '--enable-logging',
|
| - '--start-maximized',
|
| - '--disable-default-apps',
|
| - '--disable-extensions',
|
| - '--disable-plugins',
|
| - ]
|
| - chrome_flags += args.flag
|
| - # Travis-CI uses OpenVZ containers which are incompatible with the sandbox
|
| - # technology.
|
| - # See https://code.google.com/p/chromium/issues/detail?id=31077 for more
|
| - # information.
|
| - if 'TRAVIS' in os.environ:
|
| - chrome_flags += [
|
| - '--no-sandbox',
|
| - '--disable-setuid-sandbox',
|
| - '--allow-sandbox-debugging',
|
| - ]
|
| - for flag in chrome_flags:
|
| - driver_arguments['chrome_options'].add_argument(flag)
|
| -
|
| - #driver_arguments['chrome_options'].binary_location = (
|
| - # '/usr/bin/google-chrome')
|
| - driver_arguments['executable_path'] = chromedriver
|
| -
|
| -
|
| -elif args.browser == "Firefox":
|
| - driver_arguments['firefox_profile'] = webdriver.FirefoxProfile()
|
| - # Firefox will often pop-up a dialog saying "script is taking too long" or
|
| - # similar. So we can notice this problem we use "accept" rather then the
|
| - # default "dismiss".
|
| - webdriver.DesiredCapabilities.FIREFOX[
|
| - "unexpectedAlertBehaviour"] = "accept"
|
| -
|
| -elif args.browser == "PhantomJS":
|
| - driver_arguments['executable_path'] = phantomjs
|
| - driver_arguments['service_args'] = ['--remote-debugger-port=9000']
|
| -
|
| -elif args.browser == "Remote":
|
| - driver_arguments['command_executor'] = args.remote_executor
|
| -
|
| - for arg in args.remote_caps:
|
| - if not arg.strip():
|
| - continue
|
| -
|
| - if arg.find('=') < 0:
|
| - caps.update(getattr(
|
| - webdriver.DesiredCapabilities, arg.strip().upper()))
|
| - else:
|
| - bits = arg.split('=')
|
| - base = caps
|
| - for arg in bits[:-2]:
|
| - if arg not in base:
|
| - base[arg] = {}
|
| - base = base[arg]
|
| - base[bits[-2]] = bits[-1]
|
| - driver_arguments['desired_capabilities'] = caps
|
| -
|
| -major_failure = False
|
| -browser = None
|
| -session_id = None
|
| -try:
|
| - try:
|
| - if args.verbose:
|
| - print driver_arguments
|
| - browser = getattr(webdriver, args.browser)(**driver_arguments)
|
| - session_id = browser.session_id
|
| - atexit.register(browser.quit)
|
| - except:
|
| - if browser:
|
| - browser.quit()
|
| - raise
|
| -
|
| - # Load an empty page so the body element is always visible
|
| - browser.get('data:text/html;charset=utf-8,<!DOCTYPE html><html><body>EMPTY</body></html>') # noqa
|
| - if args.virtual and args.browser == "Firefox":
|
| - # Calling browser.maximize_window() doesn't work as we don't have a
|
| - # window manager, so instead we for the size/position.
|
| - browser.set_window_position(0, 0)
|
| - browser.set_window_size(*VIRTUAL_SIZE)
|
| - # Also lets go into full screen mode to get rid of the "Chrome" around
|
| - # the edges.
|
| - e = browser.find_element_by_tag_name('body')
|
| - e.send_keys(selenium_keys.F11)
|
| -
|
| - url = 'http://localhost:%i/test/test-runner.html?%s' % (
|
| - port, "|".join(tests))
|
| - browser.get(url)
|
| -
|
| - def close_other_windows(browser, url):
|
| - for win in browser.window_handles:
|
| - browser.switch_to_window(win)
|
| - if browser.current_url != url:
|
| - browser.close()
|
| - browser.switch_to_window(browser.window_handles[0])
|
| -
|
| - while True:
|
| - # Sometimes other windows are accidently opened (such as an extension
|
| - # popup), close them.
|
| - if len(browser.window_handles) > 1:
|
| - close_other_windows(browser, url)
|
| -
|
| - try:
|
| - v = browser.execute_script('return window.finished')
|
| - if v:
|
| - break
|
| -
|
| - try:
|
| - progress = browser.execute_script('return window.getTestRunnerProgress()')
|
| - status = '%s/%s (%s%%)' % (progress['completed'], progress['total'],
|
| - 100 * progress['completed'] // progress['total'])
|
| - except selenium_exceptions.WebDriverException, e:
|
| - status = e
|
| -
|
| - print 'Running tests...', status
|
| - sys.stdout.flush()
|
| - time.sleep(1)
|
| -
|
| - # Deal with unexpected alerts, sometimes they are dismissed by
|
| - # alternative means so we have to deal with that case too.
|
| - except selenium_exceptions.UnexpectedAlertPresentException, e:
|
| - try:
|
| - alert = browser.switch_to_alert()
|
| - sys.stderr.write("""\
|
| -WARNING: Unexpected alert found!
|
| ----------------------------------------------------------------------
|
| -%s
|
| ----------------------------------------------------------------------
|
| -""" % alert.text)
|
| - alert.dismiss()
|
| - except selenium_exceptions.NoAlertPresentException, e:
|
| - sys.stderr.write(
|
| - "WARNING: Unexpected alert"
|
| - " which dissappeared on it's own!\n"
|
| - )
|
| - sys.stderr.flush()
|
| -
|
| -except Exception, e:
|
| - import traceback
|
| - sys.stderr.write(traceback.format_exc())
|
| - major_failure = True
|
| -
|
| -finally:
|
| - output.stopTestRun()
|
| -
|
| - if args.browser == "Chrome":
|
| - log_path = os.path.join(user_data_dir, "chrome_debug.log")
|
| - if os.path.exists(log_path):
|
| - shutil.copy(log_path, ".")
|
| - else:
|
| - print "Unable to find Chrome log file:", log_path
|
| -
|
| -if summary.testsRun == 0:
|
| - print
|
| - print "FAIL: No tests run!"
|
| -
|
| -sys.stdout.flush()
|
| -sys.stderr.flush()
|
| -
|
| -while args.dontexit and browser.window_handles:
|
| - print "Waiting for you to close the browser...."
|
| - sys.stdout.flush()
|
| - sys.stderr.flush()
|
| - time.sleep(1)
|
| -
|
| -sys.stdout.flush()
|
| -sys.stderr.flush()
|
| -
|
| -# Annotate the success / failure to sauce labs
|
| -if args.sauce and session_id:
|
| - base64string = base64.encodestring(
|
| - '%s:%s' % (sauce_username, sauce_access_key))[:-1]
|
| -
|
| - custom_data["failures"] = summary.failures
|
| - custom_data["errors"] = summary.errors
|
| - custom_data["tests"] = summary.testsRun
|
| - custom_data["skipped"] = summary.skipped
|
| -
|
| - body_content = simplejson.dumps({
|
| - "passed": summary.wasSuccessful(),
|
| - "custom-data": custom_data,
|
| - })
|
| - connection = httplib.HTTPConnection("saucelabs.com")
|
| - connection.request(
|
| - 'PUT', '/rest/v1/%s/jobs/%s' % (sauce_username, session_id),
|
| - body_content,
|
| - headers={"Authorization": "Basic %s" % base64string})
|
| - result = connection.getresponse()
|
| - print "Sauce labs updated:", result.status == 200
|
| -
|
| - import hmac
|
| - from hashlib import md5
|
| - key = hmac.new(
|
| - str("%s:%s" % (sauce_username, session_id)),
|
| - str(sauce_access_key),
|
| - md5).hexdigest()
|
| - url = "https://saucelabs.com/jobs/%s?auth=%s" % (
|
| - browser.session_id, key)
|
| - print "Sauce lab output at:", url
|
| -
|
| -if summary.wasSuccessful() and summary.testsRun > 0 and not major_failure:
|
| - sys.exit(0)
|
| -else:
|
| - sys.exit(1)
|
|
|