Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/polymer/components/web-animations-js/tools/python/run-tests.py

Issue 592603004: Revert "Polymer elements added to third_party/polymer." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/python
2 #
3 # -*- coding: utf-8 -*-
4 # vim: set ts=4 sw=4 et sts=4 ai:
5
6 import atexit
7 import base64
8 import cStringIO as StringIO
9 import getpass
10 import httplib
11 import json as simplejson
12 import os
13 import platform
14 import pprint
15 import re
16 import socket
17 import sys
18 import time
19 import urllib2
20 import zipfile
21
22 import argparse
23 parser = argparse.ArgumentParser()
24
25 parser.add_argument(
26 "-b", "--browser", type=str, required=True,
27 choices=['Firefox', 'Chrome', 'Ie', 'PhantomJS', 'Remote'],
28 help="Which WebDriver to use.")
29
30 parser.add_argument(
31 "-f", "--flag", action='append', default=[],
32 help="Command line flags to pass to the browser, "
33 "currently only available for Chrome. "
34 "Each flag must be a separate --flag invoccation.")
35
36 parser.add_argument(
37 "-x", "--virtual", action='store_true', default=False,
38 help="Use a virtual screen system such as Xvfb, Xephyr or Xvnc.")
39
40 parser.add_argument(
41 "-d", "--dontexit", action='store_true', default=False,
42 help="At end of testing, don't exit.")
43
44 parser.add_argument(
45 "-v", "--verbose", action='store_true', default=False,
46 help="Output more information.")
47
48 parser.add_argument(
49 "-u", "--upload", action='store_true', default=False,
50 help="Upload images to picture sharing site (http://postimage.org/),"
51 " only really useful for testbots.")
52
53 # Only used by the Remote browser option.
54 parser.add_argument(
55 "--remote-executor", type=str,
56 help="Location of the Remote executor.")
57
58 parser.add_argument(
59 "--remote-caps", action='append',
60 help="Location of capabilities to request on Remote executor.",
61 default=[])
62
63 parser.add_argument(
64 "-s", "--sauce", action='store_true', default=False,
65 help="Use the SauceLab's Selenium farm rather then locally starting"
66 " selenium. SAUCE_USERNAME and SAUCE_ACCESS_KEY must be set in"
67 " environment.")
68
69 # Subunit / testrepository support
70 parser.add_argument(
71 "--subunit", action='store_true', default=False,
72 help="Output raw subunit binary data.")
73
74 parser.add_argument(
75 "--list", action='store_true', default=False,
76 help="List tests which are available.")
77
78 parser.add_argument(
79 "--load-list", type=argparse.FileType('r'),
80 help="List of tests to run.")
81
82 args = parser.parse_args()
83
84 if args.verbose and args.subunit:
85 raise SystemExit("--verbose and --subunit are not compatible.")
86
87 # Make sure the repository is setup and the dependencies exist
88 # -----------------------------------------------------------------------------
89
90 import subprocess
91
92 caps = {}
93 if not args.sauce:
94 # Get any selenium drivers we might need
95 if args.browser == "Chrome":
96 # Get ChromeDriver if it's not in the path...
97 # https://code.google.com/p/chromedriver/downloads/list
98 chromedriver_bin = "chromedriver"
99 chromedriver_url_tmpl = "http://chromedriver.storage.googleapis.com/2.6/ chromedriver_%s%s.zip" # noqa
100
101 if platform.system() == "Linux":
102 if platform.processor() == "x86_64":
103 # 64 bit binary needed
104 chromedriver_url = chromedriver_url_tmpl % ("linux", "64")
105 else:
106 # 32 bit binary needed
107 chromedriver_url = chromedriver_url_tmpl % ("linux", "32")
108
109 elif platform.system() == "Darwin":
110 chromedriver_url = chromedriver_url_tmpl % ("mac", "32")
111 elif platform.system() == "win32":
112 chromedriver_url = chromedriver_url_tmpl % ("win", "32")
113 chromedriver_url = "chromedriver.exe"
114
115 try:
116 if subprocess.call(chromedriver_bin) != 0:
117 raise OSError("Return code?")
118 except OSError:
119 chromedriver_local = os.path.join("tools", chromedriver_bin)
120
121 if not os.path.exists(chromedriver_local):
122 datafile = StringIO.StringIO(
123 urllib2.urlopen(chromedriver_url).read())
124 contents = zipfile.ZipFile(datafile, 'r')
125 contents.extract(chromedriver_bin, "tools")
126
127 chromedriver = os.path.realpath(chromedriver_local)
128 os.chmod(chromedriver, 0755)
129 else:
130 chromedriver = "chromedriver"
131
132 elif args.browser == "Firefox":
133 pass
134
135 elif args.browser == "PhantomJS":
136 phantomjs_bin = None
137 if platform.system() == "Linux":
138 phantomjs_bin = "phantomjs"
139 if platform.processor() == "x86_64":
140 # 64 bit binary needed
141 phantomjs_url = "https://phantomjs.googlecode.com/files/phantomj s-1.9.0-linux-x86_64.tar.bz2" # noqa
142 else:
143 # 32 bit binary needed
144 phantomjs_url = "https://phantomjs.googlecode.com/files/phantomj s-1.9.0-linux-i686.tar.bz2" # noqa
145
146 phantomjs_local = os.path.join("tools", phantomjs_bin)
147 if not os.path.exists(phantomjs_local):
148 datafile = StringIO.StringIO(
149 urllib2.urlopen(phantomjs_url).read())
150 contents = tarfile.TarFile.open(fileobj=datafile, mode='r:bz2')
151 file("tools/"+phantomjs_bin, "w").write(
152 contents.extractfile(
153 "phantomjs-1.9.0-linux-x86_64/bin/"+phantomjs_bin
154 ).read())
155
156 phantomjs = os.path.realpath(phantomjs_local)
157 os.chmod(phantomjs, 0755)
158 else:
159 if platform.system() == "Darwin":
160 phantomjs_url = "https://phantomjs.googlecode.com/files/phantomj s-1.9.0-macosx.zip" # noqa
161 phantomjs_bin = "phantomjs"
162
163 elif platform.system() == "win32":
164 chromedriver_bin = "https://phantomjs.googlecode.com/files/phant omjs-1.9.0-windows.zip" # noqa
165 phantomjs_url = "phantomjs.exe"
166
167 phantomjs_local = os.path.join("tools", phantomjs_bin)
168 if not os.path.exists(phantomjs_local):
169 datafile = StringIO.StringIO(
170 urllib2.urlopen(phantomjs_url).read())
171 contents = zipfile.ZipFile(datafile, 'r')
172 contents.extract(phantomjs_bin, "tools")
173
174 phantomjs = os.path.realpath(phantomjs_local)
175 os.chmod(phantomjs, 0755)
176 else:
177 assert os.environ['SAUCE_USERNAME']
178 assert os.environ['SAUCE_ACCESS_KEY']
179 sauce_username = os.environ['SAUCE_USERNAME']
180 sauce_access_key = os.environ['SAUCE_ACCESS_KEY']
181
182 # Download the Sauce Connect script
183 sauce_connect_url = "http://saucelabs.com/downloads/Sauce-Connect-latest.zip " # noqa
184 sauce_connect_bin = "Sauce-Connect.jar"
185 sauce_connect_local = os.path.join("tools", sauce_connect_bin)
186 if not os.path.exists(sauce_connect_local):
187 datafile = StringIO.StringIO(urllib2.urlopen(sauce_connect_url).read())
188 contents = zipfile.ZipFile(datafile, 'r')
189 contents.extract(sauce_connect_bin, "tools")
190
191 if 'TRAVIS_JOB_NUMBER' in os.environ:
192 tunnel_id = os.environ['TRAVIS_JOB_NUMBER']
193 else:
194 tunnel_id = "%s:%s" % (socket.gethostname(), os.getpid())
195 args.remote_caps.append('tunnel-identifier=%s' % tunnel_id)
196
197 # Kill the tunnel when we die
198 def kill_tunnel(sauce_tunnel):
199 if sauce_tunnel.returncode is None:
200 sauce_tunnel.terminate()
201
202 timeout = time.time()
203 while sauce_tunnel.poll() is None:
204 if time.time() - timeout < 30:
205 time.sleep(1)
206 else:
207 sauce_tunnel.kill()
208
209 readyfile = "."+tunnel_id
210 sauce_tunnel = None
211 try:
212 sauce_log = file("sauce_tunnel.log", "w")
213 sauce_tunnel = subprocess.Popen(
214 ["java", "-jar", sauce_connect_local,
215 "--readyfile", readyfile,
216 "--tunnel-identifier", tunnel_id,
217 sauce_username, sauce_access_key],
218 stdout=sauce_log, stderr=sauce_log)
219
220 atexit.register(kill_tunnel, sauce_tunnel)
221
222 # Wait for the tunnel to come up
223 while not os.path.exists(readyfile):
224 time.sleep(0.5)
225
226 except:
227 if sauce_tunnel:
228 kill_tunnel(sauce_tunnel)
229 raise
230
231 args.remote_executor = "http://%s:%s@localhost:4445/wd/hub" % (
232 sauce_username, sauce_access_key)
233
234 custom_data = {}
235 git_info = subprocess.Popen(
236 ["git", "describe", "--all", "--long"], stdout=subprocess.PIPE
237 ).communicate()[0]
238 custom_data["git-info"] = git_info
239
240 git_commit = subprocess.Popen(
241 ["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE
242 ).communicate()[0]
243 custom_data["git-commit"] = git_commit
244
245 caps['tags'] = []
246 if 'TRAVIS_BUILD_NUMBER' in os.environ:
247 # Send travis information upstream
248 caps['build'] = "%s %s" % (
249 os.environ['TRAVIS_REPO_SLUG'],
250 os.environ['TRAVIS_BUILD_NUMBER'],
251 )
252 caps['name'] = "Travis run for %s" % os.environ['TRAVIS_REPO_SLUG']
253
254 caps['tags'].append(
255 "repo=%s" % os.environ['TRAVIS_REPO_SLUG'])
256 caps['tags'].append(
257 "branch=%s" % os.environ['TRAVIS_BRANCH'])
258
259 travis_env = [
260 'TRAVIS_BRANCH',
261 'TRAVIS_BUILD_ID',
262 'TRAVIS_BUILD_NUMBER',
263 'TRAVIS_COMMIT',
264 'TRAVIS_COMMIT_RANGE',
265 'TRAVIS_JOB_ID',
266 'TRAVIS_JOB_NUMBER',
267 'TRAVIS_PULL_REQUEST',
268 'TRAVIS_REPO_SLUG',
269 ]
270
271 for env in travis_env:
272 tag = env[len('TRAVIS_'):].lower()
273 value = os.environ.get(env, None)
274 if not value:
275 continue
276 custom_data[tag] = value
277
278 custom_data["github-url"] = (
279 "https://github.com/%s/tree/%s" % (
280 os.environ['TRAVIS_REPO_SLUG'], git_commit))
281 custom_data["travis-url"] = (
282 "https://travis-ci.org/%s/builds/%s" % (
283 os.environ['TRAVIS_REPO_SLUG'],
284 os.environ['TRAVIS_BUILD_ID']))
285 else:
286 # Collect information about who/what is running the test
287 caps['name'] = "Manual run for %s" % getpass.getuser()
288 caps['build'] = git_info
289
290 caps['tags'].append('user=%s' % getpass.getuser())
291 caps['tags'].append('host=%s' % socket.gethostname())
292
293 # -----------------------------------------------------------------------------
294
295 import subunit
296 import testtools
297
298 if args.list:
299 data = file("test/testcases.js").read()
300 for test in re.compile("(?<=').+(?=')").findall(data):
301 print test[:-5]
302 sys.exit(-1)
303
304 if args.load_list:
305 tests = list(set(x.split(':')[0].strip()+'.html'
306 for x in args.load_list.readlines()))
307 else:
308 tests = []
309
310 # Collect summary of all the individual test runs
311 summary = testtools.StreamSummary()
312
313 # Output information to stdout
314 if not args.subunit:
315 # Output test failures
316 result_streams = [testtools.TextTestResult(sys.stdout)]
317 if args.verbose:
318 import unittest
319 # Output individual test progress
320 result_streams.insert(0,
321 unittest.TextTestResult(
322 unittest.runner._WritelnDecorator(sys.stdout), False, 2))
323 # Human readable test output
324 pertest = testtools.StreamToExtendedDecorator(
325 testtools.MultiTestResult(*result_streams))
326 else:
327 from subunit.v2 import StreamResultToBytes
328 pertest = StreamResultToBytes(sys.stdout)
329
330 if args.list:
331 output = subunit.CopyStreamResult([summary, pertest])
332 output.startTestRun()
333 for test in re.compile("(?<=').+(?=')").findall(
334 file("test/testcases.js").read()):
335 output.status(test_status='exists', test_id=test[:-5])
336
337 output.stopTestRun()
338 sys.exit(-1)
339
340 output = subunit.CopyStreamResult([summary, pertest])
341 output.startTestRun()
342
343 # Start up a local HTTP server which serves the files to the browser and
344 # collects the test results.
345 # -----------------------------------------------------------------------------
346 import SimpleHTTPServer
347 import SocketServer
348 import threading
349 import cgi
350 import re
351
352 import itertools
353 import mimetools
354 import mimetypes
355
356
357 class MultiPartForm(object):
358 """Accumulate the data to be used when posting a form."""
359
360 def __init__(self):
361 self.form_fields = []
362 self.files = []
363 self.boundary = mimetools.choose_boundary()
364 return
365
366 def get_content_type(self):
367 return 'multipart/form-data; boundary=%s' % self.boundary
368
369 def add_field(self, name, value):
370 """Add a simple field to the form data."""
371 self.form_fields.append((name, value))
372 return
373
374 def add_file(self, fieldname, filename, fileHandle, mimetype=None):
375 """Add a file to be uploaded."""
376 body = fileHandle.read()
377 if mimetype is None:
378 mimetype = (
379 mimetypes.guess_type(filename)[0] or
380 'application/octet-stream')
381 self.files.append((fieldname, filename, mimetype, body))
382 return
383
384 def __str__(self):
385 """Return a string representing the form data, with attached files."""
386 # Build a list of lists, each containing "lines" of the
387 # request. Each part is separated by a boundary string.
388 # Once the list is built, return a string where each
389 # line is separated by '\r\n'.
390 parts = []
391 part_boundary = '--' + self.boundary
392
393 # Add the form fields
394 parts.extend([
395 part_boundary,
396 'Content-Disposition: form-data; name="%s"' % name,
397 '',
398 value,
399 ] for name, value in self.form_fields)
400
401 # Add the files to upload
402 parts.extend([
403 part_boundary,
404 'Content-Disposition: file; name="%s"; filename="%s"' % (
405 field_name, filename),
406 'Content-Type: %s' % content_type,
407 '',
408 body,
409 ] for field_name, filename, content_type, body in self.files)
410
411 # Flatten the list and add closing boundary marker,
412 # then return CR+LF separated data
413 flattened = list(str(b) for b in itertools.chain(*parts))
414 flattened.append('--' + self.boundary + '--')
415 flattened.append('')
416 return '\r\n'.join(flattened)
417
418
419 critical_failure = False
420
421
422 class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
423 STATUS = {0: 'success', 1: 'fail', 2: 'fail', 3: 'skip'}
424
425 # Make the HTTP requests be quiet
426 def log_message(self, format, *a):
427 if args.verbose:
428 SimpleHTTPServer.SimpleHTTPRequestHandler.log_message(
429 self, format, *a)
430
431 def do_POST(self):
432 global critical_failure
433 already_failed = critical_failure
434
435 form = cgi.FieldStorage(
436 fp=self.rfile,
437 headers=self.headers,
438 environ={
439 'REQUEST_METHOD': 'POST',
440 'CONTENT_TYPE': self.headers['Content-Type'],
441 })
442
443 overall_status = 0
444 test_id = None
445 try:
446 json_data = form.getvalue('data')
447 data = simplejson.loads(json_data)
448 except ValueError, e:
449 critical_failure = True
450
451 test_id = "CRITICAL-FAILURE"
452
453 msg = "Unable to decode JSON object (%s)\n%s" % (e, json_data)
454 overall_status = 1
455 output.status(
456 test_id="CRITICAL-FAILURE",
457 test_status='fail',
458 test_tags=[args.browser],
459 file_name='traceback',
460 file_bytes=msg,
461 mime_type='text/plain; charset=UTF-8',
462 eof=True)
463 else:
464 test_id = data['testName'][:-5]
465 for result in data['results']:
466 info = dict(result)
467 info.pop('_structured_clone', None)
468
469 if not isinstance(result['message'], (str, unicode)):
470 msg = str(result['message'])
471 else:
472 msg = result['message']
473
474 overall_status += result['status']
475 output.status(
476 test_id="%s:%s" % (test_id, result['name']),
477 test_status=self.STATUS[result['status']],
478 test_tags=[args.browser],
479 file_name='traceback',
480 file_bytes=msg,
481 mime_type='text/plain; charset=UTF-8',
482 eof=True)
483
484 if args.verbose and 'debug' in data and overall_status > 0:
485 output.status(
486 test_id="%s:debug-log" % (test_id),
487 test_status='fail',
488 test_tags=[args.browser],
489 file_name='traceback',
490 file_bytes=data['debug'],
491 mime_type='text/plain; charset=UTF-8',
492 eof=True)
493
494 # Take a screenshot of result if a failure occurred.
495 if overall_status > 0 and (args.virtual or args.browser == "Remote"):
496 time.sleep(1)
497
498 try:
499 screenshot = test_id + '.png'
500 if args.virtual:
501 disp.grab().save(screenshot)
502 elif args.browser == "Remote":
503 global browser
504 browser.save_screenshot(screenshot)
505
506 # On android we want to do a
507 # adb run /system/bin/screencap -p /sdcard/FILENAME.png
508 # adb cp FILENAME.png ....
509
510 if args.upload and not already_failed:
511 form = MultiPartForm()
512 form.add_field('adult', 'no')
513 form.add_field('optsize', '0')
514 form.add_file(
515 'upload[]', screenshot, fileHandle=open(screenshot, 'rb' ))
516
517 request = urllib2.Request("http://postimage.org/")
518 body = str(form)
519 request.add_header('Content-type', form.get_content_type())
520 request.add_header('Content-length', len(body))
521 request.add_data(body)
522
523 result = urllib2.urlopen(request).read()
524 print "Screenshot at:", re.findall("""<td><textarea wrap='of f' onmouseover='this.focus\(\)' onfocus='this.select\(\)' id="code_1" scrolling= "no">([^<]*)</textarea></td>""", result) # noqa
525 except Exception, e:
526 print e
527
528 response = "OK"
529 self.send_response(200)
530 self.send_header("Content-type", "text/plain")
531 self.send_header("Content-length", len(response))
532 self.end_headers()
533 self.wfile.write(response)
534 self.wfile.close()
535
536 if args.sauce:
537 port = 55001
538 else:
539 port = 0 # Bind to any port on localhost
540
541 while True:
542 try:
543 httpd = SocketServer.TCPServer(
544 ("127.0.0.1", port),
545 ServerHandler)
546 break
547 except socket.error as e:
548 print e
549 time.sleep(5)
550
551 port = httpd.socket.getsockname()[-1]
552 print "Serving at", port
553
554 httpd_thread = threading.Thread(target=httpd.serve_forever)
555 httpd_thread.daemon = True
556 httpd_thread.start()
557
558
559 # Start up a virtual display, useful for testing on headless servers.
560 # -----------------------------------------------------------------------------
561
562 VIRTUAL_SIZE = (1024, 2000)
563
564 # PhantomJS doesn't need a display
565 disp = None
566 if args.virtual and args.browser != "PhantomJS":
567 from pyvirtualdisplay.smartdisplay import SmartDisplay
568
569 try:
570 disp = SmartDisplay(
571 visible=0, bgcolor='black', size=VIRTUAL_SIZE).start()
572 atexit.register(disp.stop)
573 except:
574 if disp:
575 disp.stop()
576 raise
577
578
579 # Start up the web browser and run the tests.
580 # ----------------------------------------------------------------------------
581
582 from selenium import webdriver
583 from selenium.common import exceptions as selenium_exceptions
584 from selenium.webdriver.common.keys import Keys as selenium_keys
585
586 driver_arguments = {}
587 if args.browser == "Chrome":
588 import tempfile
589 import shutil
590
591 # We reference shutil to make sure it isn't garbaged collected before we
592 # use it.
593 def directory_cleanup(directory, shutil=shutil):
594 try:
595 shutil.rmtree(directory)
596 except OSError, e:
597 pass
598
599 try:
600 user_data_dir = tempfile.mkdtemp()
601 atexit.register(directory_cleanup, user_data_dir)
602 except:
603 directory_cleanup(user_data_dir)
604 raise
605
606 driver_arguments['chrome_options'] = webdriver.ChromeOptions()
607 # Make printable
608 webdriver.ChromeOptions.__repr__ = lambda self: str(self.__dict__)
609 chrome_flags = [
610 '--user-data-dir=%s' % user_data_dir,
611 '--enable-logging',
612 '--start-maximized',
613 '--disable-default-apps',
614 '--disable-extensions',
615 '--disable-plugins',
616 ]
617 chrome_flags += args.flag
618 # Travis-CI uses OpenVZ containers which are incompatible with the sandbox
619 # technology.
620 # See https://code.google.com/p/chromium/issues/detail?id=31077 for more
621 # information.
622 if 'TRAVIS' in os.environ:
623 chrome_flags += [
624 '--no-sandbox',
625 '--disable-setuid-sandbox',
626 '--allow-sandbox-debugging',
627 ]
628 for flag in chrome_flags:
629 driver_arguments['chrome_options'].add_argument(flag)
630
631 #driver_arguments['chrome_options'].binary_location = (
632 # '/usr/bin/google-chrome')
633 driver_arguments['executable_path'] = chromedriver
634
635
636 elif args.browser == "Firefox":
637 driver_arguments['firefox_profile'] = webdriver.FirefoxProfile()
638 # Firefox will often pop-up a dialog saying "script is taking too long" or
639 # similar. So we can notice this problem we use "accept" rather then the
640 # default "dismiss".
641 webdriver.DesiredCapabilities.FIREFOX[
642 "unexpectedAlertBehaviour"] = "accept"
643
644 elif args.browser == "PhantomJS":
645 driver_arguments['executable_path'] = phantomjs
646 driver_arguments['service_args'] = ['--remote-debugger-port=9000']
647
648 elif args.browser == "Remote":
649 driver_arguments['command_executor'] = args.remote_executor
650
651 for arg in args.remote_caps:
652 if not arg.strip():
653 continue
654
655 if arg.find('=') < 0:
656 caps.update(getattr(
657 webdriver.DesiredCapabilities, arg.strip().upper()))
658 else:
659 bits = arg.split('=')
660 base = caps
661 for arg in bits[:-2]:
662 if arg not in base:
663 base[arg] = {}
664 base = base[arg]
665 base[bits[-2]] = bits[-1]
666 driver_arguments['desired_capabilities'] = caps
667
668 major_failure = False
669 browser = None
670 session_id = None
671 try:
672 try:
673 if args.verbose:
674 print driver_arguments
675 browser = getattr(webdriver, args.browser)(**driver_arguments)
676 session_id = browser.session_id
677 atexit.register(browser.quit)
678 except:
679 if browser:
680 browser.quit()
681 raise
682
683 # Load an empty page so the body element is always visible
684 browser.get('data:text/html;charset=utf-8,<!DOCTYPE html><html><body>EMPTY</ body></html>') # noqa
685 if args.virtual and args.browser == "Firefox":
686 # Calling browser.maximize_window() doesn't work as we don't have a
687 # window manager, so instead we for the size/position.
688 browser.set_window_position(0, 0)
689 browser.set_window_size(*VIRTUAL_SIZE)
690 # Also lets go into full screen mode to get rid of the "Chrome" around
691 # the edges.
692 e = browser.find_element_by_tag_name('body')
693 e.send_keys(selenium_keys.F11)
694
695 url = 'http://localhost:%i/test/test-runner.html?%s' % (
696 port, "|".join(tests))
697 browser.get(url)
698
699 def close_other_windows(browser, url):
700 for win in browser.window_handles:
701 browser.switch_to_window(win)
702 if browser.current_url != url:
703 browser.close()
704 browser.switch_to_window(browser.window_handles[0])
705
706 while True:
707 # Sometimes other windows are accidently opened (such as an extension
708 # popup), close them.
709 if len(browser.window_handles) > 1:
710 close_other_windows(browser, url)
711
712 try:
713 v = browser.execute_script('return window.finished')
714 if v:
715 break
716
717 try:
718 progress = browser.execute_script('return window.getTestRunnerPr ogress()')
719 status = '%s/%s (%s%%)' % (progress['completed'], progress['tota l'],
720 100 * progress['completed'] // progress['total'])
721 except selenium_exceptions.WebDriverException, e:
722 status = e
723
724 print 'Running tests...', status
725 sys.stdout.flush()
726 time.sleep(1)
727
728 # Deal with unexpected alerts, sometimes they are dismissed by
729 # alternative means so we have to deal with that case too.
730 except selenium_exceptions.UnexpectedAlertPresentException, e:
731 try:
732 alert = browser.switch_to_alert()
733 sys.stderr.write("""\
734 WARNING: Unexpected alert found!
735 ---------------------------------------------------------------------
736 %s
737 ---------------------------------------------------------------------
738 """ % alert.text)
739 alert.dismiss()
740 except selenium_exceptions.NoAlertPresentException, e:
741 sys.stderr.write(
742 "WARNING: Unexpected alert"
743 " which dissappeared on it's own!\n"
744 )
745 sys.stderr.flush()
746
747 except Exception, e:
748 import traceback
749 sys.stderr.write(traceback.format_exc())
750 major_failure = True
751
752 finally:
753 output.stopTestRun()
754
755 if args.browser == "Chrome":
756 log_path = os.path.join(user_data_dir, "chrome_debug.log")
757 if os.path.exists(log_path):
758 shutil.copy(log_path, ".")
759 else:
760 print "Unable to find Chrome log file:", log_path
761
762 if summary.testsRun == 0:
763 print
764 print "FAIL: No tests run!"
765
766 sys.stdout.flush()
767 sys.stderr.flush()
768
769 while args.dontexit and browser.window_handles:
770 print "Waiting for you to close the browser...."
771 sys.stdout.flush()
772 sys.stderr.flush()
773 time.sleep(1)
774
775 sys.stdout.flush()
776 sys.stderr.flush()
777
778 # Annotate the success / failure to sauce labs
779 if args.sauce and session_id:
780 base64string = base64.encodestring(
781 '%s:%s' % (sauce_username, sauce_access_key))[:-1]
782
783 custom_data["failures"] = summary.failures
784 custom_data["errors"] = summary.errors
785 custom_data["tests"] = summary.testsRun
786 custom_data["skipped"] = summary.skipped
787
788 body_content = simplejson.dumps({
789 "passed": summary.wasSuccessful(),
790 "custom-data": custom_data,
791 })
792 connection = httplib.HTTPConnection("saucelabs.com")
793 connection.request(
794 'PUT', '/rest/v1/%s/jobs/%s' % (sauce_username, session_id),
795 body_content,
796 headers={"Authorization": "Basic %s" % base64string})
797 result = connection.getresponse()
798 print "Sauce labs updated:", result.status == 200
799
800 import hmac
801 from hashlib import md5
802 key = hmac.new(
803 str("%s:%s" % (sauce_username, session_id)),
804 str(sauce_access_key),
805 md5).hexdigest()
806 url = "https://saucelabs.com/jobs/%s?auth=%s" % (
807 browser.session_id, key)
808 print "Sauce lab output at:", url
809
810 if summary.wasSuccessful() and summary.testsRun > 0 and not major_failure:
811 sys.exit(0)
812 else:
813 sys.exit(1)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698