Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
| 5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
| 6 # | 6 # |
| 7 | 7 |
| 8 """Script to actually open a browser and perform the test, and reports back with | 8 """Script to actually open a browser and perform the test, and reports back with |
| 9 the result. | 9 the result. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 import optparse | 12 import optparse |
| 13 import platform | 13 import platform |
| 14 import selenium | 14 import selenium |
| 15 from selenium.webdriver.support.ui import WebDriverWait | 15 from selenium.webdriver.support.ui import WebDriverWait |
| 16 import socket | |
| 16 import sys | 17 import sys |
| 18 import time | |
| 17 | 19 |
| 18 def perf_test_done(driver): | 20 def perf_test_done(driver): |
| 19 """Checks if the performance test has completed.""" | 21 """Checks if the performance test has completed.""" |
| 22 return perf_test_done_helper(driver.page_source) | |
| 23 | |
| 24 def perf_test_done_helper(source): | |
| 25 """Tests to see if our performance test is done by printing a score.""" | |
| 20 #This code is written this way to work around a current instability in the | 26 #This code is written this way to work around a current instability in the |
| 21 # python webdriver bindings if you call driver.get_element_by_id. | 27 # python webdriver bindings if you call driver.get_element_by_id. |
| 22 source = driver.page_source | 28 #TODO(efortuna): Access these elements in a nicer way using DOM parser. |
| 23 string = '<div id="status">' | 29 string = '<div id="status">' |
| 24 index = source.find(string) | 30 index = source.find(string) |
| 25 end_index = source.find('</div>', index+1) | 31 end_index = source.find('</div>', index+1) |
| 26 source = source[index + len(string):end_index] | 32 source = source[index + len(string):end_index] |
| 27 return 'Score:' in source | 33 return 'Score:' in source |
| 28 | 34 |
| 29 def run_test_in_browser(browser, html_out, timeout, is_perf): | 35 def run_test_in_browser(browser, html_out, timeout, is_perf): |
| 30 """Run the desired test in the browser, and wait for the test to complete.""" | 36 """Run the desired test in the browser using Selenium 2.0 WebDriver syntax, |
| 37 and wait for the test to complete. This is the newer syntax, that currently | |
| 38 supports Firefox, Chrome, IE, Opera (and some mobile browsers).""" | |
| 31 browser.get("file://" + html_out) | 39 browser.get("file://" + html_out) |
| 32 source = '' | 40 source = '' |
| 33 try: | 41 try: |
| 34 if is_perf: | 42 if is_perf: |
| 35 # We're running a performance test. | 43 # We're running a performance test. |
| 36 element = WebDriverWait(browser, float(timeout)).until(perf_test_done) | 44 element = WebDriverWait(browser, float(timeout)).until(perf_test_done) |
| 37 else: | 45 else: |
| 38 element = WebDriverWait(browser, float(timeout)).until( | 46 element = WebDriverWait(browser, float(timeout)).until( |
| 39 lambda driver : ('PASS' in driver.page_source) or | 47 lambda driver : ('PASS' in driver.page_source) or |
| 40 ('FAIL' in driver.page_source)) | 48 ('FAIL' in driver.page_source)) |
| 41 source = browser.page_source | 49 source = browser.page_source |
| 42 finally: | 50 finally: |
| 43 # A timeout exception is thrown if nothing happens within the time limit. | 51 # A timeout exception is thrown if nothing happens within the time limit. |
| 44 browser.close() | 52 browser.close() |
| 45 return source | 53 return source |
| 46 | 54 |
| 55 def run_test_in_browser_selenium1(sel, html_out, timeout, is_perf): | |
| 56 """ Run the desired test in the browser using Selenium 1.0 syntax, and wait | |
| 57 for the test to complete. This is used for Safari, since it is not currently | |
| 58 supported on Selenium 2.0.""" | |
| 59 sel.open('file://' + html_out) | |
| 60 source = sel.get_html_source() | |
| 61 end_condition = lambda(source): 'PASS' not in source and 'FAIL' not in source | |
|
Jennifer Messerly
2011/12/13 01:26:30
style nit: I'd make this a function:
def end_condi
| |
| 62 if is_perf: | |
| 63 end_condition = perf_test_done_helper | |
| 64 | |
| 65 elapsed = 0 | |
| 66 while not end_condition(source) and elapsed <= timeout: | |
| 67 sec = .25 | |
| 68 time.sleep(sec) | |
| 69 elapsed += sec | |
| 70 source = sel.get_html_source() | |
| 71 sel.stop() | |
| 72 return source | |
| 73 | |
| 47 def parse_args(): | 74 def parse_args(): |
| 48 parser = optparse.OptionParser() | 75 parser = optparse.OptionParser() |
| 49 parser.add_option('--out', dest='out', | 76 parser.add_option('--out', dest='out', |
| 50 help = 'The path for html output file that we will be writing to', | 77 help = 'The path for html output file that we will running our test from', |
| 51 action = 'store', default = '') | 78 action = 'store', default = '') |
| 52 parser.add_option('--browser', dest='browser', | 79 parser.add_option('--browser', dest='browser', |
| 53 help = 'The browser type (default = chrome)', | 80 help = 'The browser type (default = chrome)', |
| 54 action = 'store', default = 'chrome') | 81 action = 'store', default = 'chrome') |
| 55 parser.add_option('--timeout', dest = 'timeout', | 82 parser.add_option('--timeout', dest = 'timeout', |
| 56 help = 'Amount of time (seconds) to wait before timeout', type = 'int', | 83 help = 'Amount of time (seconds) to wait before timeout', type = 'int', |
| 57 action = 'store', default=10) | 84 action = 'store', default=10) |
| 58 parser.add_option('--perf', dest = 'is_perf', | 85 parser.add_option('--perf', dest = 'is_perf', |
| 59 help = 'Add this flag if we are running a browser performance test', | 86 help = 'Add this flag if we are running a browser performance test', |
| 60 action = 'store_true', default=False) | 87 action = 'store_true', default=False) |
| 61 args, ignored = parser.parse_args() | 88 args, ignored = parser.parse_args() |
| 62 return args.out, args.browser, args.timeout, args.is_perf | 89 return args.out, args.browser, args.timeout, args.is_perf |
| 63 | 90 |
| 64 def Main(): | 91 def Main(): |
| 65 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to | 92 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to |
| 66 # installing Chrome. | 93 # installing Chrome. |
| 67 browser = None | 94 browser = None |
| 68 html_out, browser, timeout, is_perf = parse_args() | 95 html_out, browser, timeout, is_perf = parse_args() |
| 69 | 96 |
| 70 if browser == 'chrome': | 97 if browser == 'chrome': |
| 71 browser = selenium.webdriver.Chrome() | 98 browser = selenium.webdriver.Chrome() |
| 72 elif browser == 'ff': | 99 elif browser == 'ff': |
| 73 browser = selenium.webdriver.Firefox() | 100 # By default WebDriver creates a new anonymous Firefox profile each time it |
| 101 # launches. This can fill up 250 GB in a little over a week! Always specify | |
| 102 # a profile if you're running a bunch (many thousands) of Firefox tests over | |
| 103 # time. | |
| 104 #TODO(efortuna): Don't hard-code this path. Come up with a better solution. | |
|
Jennifer Messerly
2011/12/13 01:26:30
http://code.google.com/p/selenium/wiki/FirefoxDriv
| |
| 105 profile = selenium.webdriver.firefox.firefox_profile.FirefoxProfile( | |
| 106 profile_directory='/Users/fortuna/Library/Application Support/' + | |
| 107 'Firefox/Profiles/wovq7ii0.selenium') | |
| 108 browser = selenium.webdriver.Firefox(firefox_profile=profile) | |
| 74 elif browser == 'ie' and platform.system() == 'Windows': | 109 elif browser == 'ie' and platform.system() == 'Windows': |
| 75 browser = selenium.webdriver.Ie() | 110 browser = selenium.webdriver.Ie() |
| 111 elif browser == 'safari' and platform.system() == 'Darwin': | |
| 112 sel = selenium.selenium('localhost', 4444, "*safari", 'file://' + html_out) | |
| 113 try: | |
| 114 sel.start() | |
| 115 except socket.error: | |
| 116 print 'ERROR: Could not connect to Selenium RC server. Are you running' +\ | |
| 117 ' java -jar selenium-server-standalone-2.15.0.jar? If not, start ' + \ | |
| 118 'it before running this test.' | |
| 119 return 1 | |
| 76 else: | 120 else: |
| 77 raise Exception('Incompatible browser and platform combination.') | 121 raise Exception('Incompatible browser and platform combination.') |
| 78 source = run_test_in_browser(browser, html_out, timeout, is_perf) | 122 source = '' |
| 123 if browser == 'safari': | |
| 124 source = run_test_in_browser_selenium1(sel, html_out, timeout, is_perf) | |
| 125 else: | |
| 126 source = run_test_in_browser(browser, html_out, timeout, is_perf) | |
| 79 | 127 |
| 80 if is_perf: | 128 if is_perf: |
| 81 # We're running a performance test. | 129 # We're running a performance test. |
| 82 print source | 130 print source |
| 83 if 'NaN' in source: | 131 if 'NaN' in source: |
| 84 return 1 | 132 return 1 |
| 85 else: | 133 else: |
| 86 return 0 | 134 return 0 |
| 87 else: | 135 else: |
| 88 # We're running a correctness test. | 136 # We're running a correctness test. |
| 89 if ('PASS' in source): | 137 if ('PASS' in source): |
| 90 print 'Content-Type: text/plain\nPASS' | 138 print 'Content-Type: text/plain\nPASS' |
| 91 return 0 | 139 return 0 |
| 92 else: | 140 else: |
| 93 #The hacky way to get document.getElementById('body').innerHTML for this | 141 #The hacky way to get document.getElementById('body').innerHTML for this |
| 94 # webpage, without the JavaScript. | 142 # webpage, without the JavaScript. |
| 143 #TODO(efortuna): Access these elements in a nicer way using DOM parser. | |
| 95 index = source.find('<body>') | 144 index = source.find('<body>') |
| 96 index += len('<body>') | 145 index += len('<body>') |
| 97 end_index = source.find('<script') | 146 end_index = source.find('<script') |
| 98 print source[index : end_index] | 147 print source[index : end_index] |
| 99 return 1 | 148 return 1 |
| 100 | 149 |
| 101 | 150 |
| 102 if __name__ == "__main__": | 151 if __name__ == "__main__": |
| 103 sys.exit(Main()) | 152 sys.exit(Main()) |
| OLD | NEW |