| 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() |
| 53 browser.quit() |
| 54 return source |
| 55 |
| 56 def run_test_in_browser_selenium1(sel, html_out, timeout, is_perf): |
| 57 """ Run the desired test in the browser using Selenium 1.0 syntax, and wait |
| 58 for the test to complete. This is used for Safari, since it is not currently |
| 59 supported on Selenium 2.0.""" |
| 60 sel.open('file://' + html_out) |
| 61 source = sel.get_html_source() |
| 62 def end_condition(source): |
| 63 return 'PASS' in source and 'FAIL' in source |
| 64 if is_perf: |
| 65 end_condition = perf_test_done_helper |
| 66 |
| 67 elapsed = 0 |
| 68 while (not end_condition(source)) and elapsed <= timeout: |
| 69 sec = .25 |
| 70 time.sleep(sec) |
| 71 elapsed += sec |
| 72 source = sel.get_html_source() |
| 73 sel.stop() |
| 45 return source | 74 return source |
| 46 | 75 |
| 47 def parse_args(): | 76 def parse_args(): |
| 48 parser = optparse.OptionParser() | 77 parser = optparse.OptionParser() |
| 49 parser.add_option('--out', dest='out', | 78 parser.add_option('--out', dest='out', |
| 50 help = 'The path for html output file that we will be writing to', | 79 help = 'The path for html output file that we will running our test from',
|
| 51 action = 'store', default = '') | 80 action = 'store', default = '') |
| 52 parser.add_option('--browser', dest='browser', | 81 parser.add_option('--browser', dest='browser', |
| 53 help = 'The browser type (default = chrome)', | 82 help = 'The browser type (default = chrome)', |
| 54 action = 'store', default = 'chrome') | 83 action = 'store', default = 'chrome') |
| 55 parser.add_option('--timeout', dest = 'timeout', | 84 parser.add_option('--timeout', dest = 'timeout', |
| 56 help = 'Amount of time (seconds) to wait before timeout', type = 'int', | 85 help = 'Amount of time (seconds) to wait before timeout', type = 'int', |
| 57 action = 'store', default=10) | 86 action = 'store', default=10) |
| 58 parser.add_option('--perf', dest = 'is_perf', | 87 parser.add_option('--perf', dest = 'is_perf', |
| 59 help = 'Add this flag if we are running a browser performance test', | 88 help = 'Add this flag if we are running a browser performance test', |
| 60 action = 'store_true', default=False) | 89 action = 'store_true', default=False) |
| 61 args, ignored = parser.parse_args() | 90 args, ignored = parser.parse_args() |
| 62 return args.out, args.browser, args.timeout, args.is_perf | 91 return args.out, args.browser, args.timeout, args.is_perf |
| 63 | 92 |
| 64 def Main(): | 93 def Main(): |
| 65 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to | 94 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to |
| 66 # installing Chrome. | 95 # installing Chrome. |
| 67 browser = None | 96 browser = None |
| 68 html_out, browser, timeout, is_perf = parse_args() | 97 html_out, browser, timeout, is_perf = parse_args() |
| 69 | 98 |
| 70 if browser == 'chrome': | 99 if browser == 'chrome': |
| 71 browser = selenium.webdriver.Chrome() | 100 browser = selenium.webdriver.Chrome() |
| 72 elif browser == 'ff': | 101 elif browser == 'ff': |
| 73 browser = selenium.webdriver.Firefox() | 102 browser = selenium.webdriver.Firefox() |
| 74 elif browser == 'ie' and platform.system() == 'Windows': | 103 elif browser == 'ie' and platform.system() == 'Windows': |
| 75 browser = selenium.webdriver.Ie() | 104 browser = selenium.webdriver.Ie() |
| 105 elif browser == 'safari' and platform.system() == 'Darwin': |
| 106 sel = selenium.selenium('localhost', 4444, "*safari", 'file://' + html_out) |
| 107 try: |
| 108 sel.start() |
| 109 except socket.error: |
| 110 print 'ERROR: Could not connect to Selenium RC server. Are you running' +\ |
| 111 ' java -jar selenium-server-standalone-2.15.0.jar? If not, start ' + \ |
| 112 'it before running this test.' |
| 113 return 1 |
| 76 else: | 114 else: |
| 77 raise Exception('Incompatible browser and platform combination.') | 115 raise Exception('Incompatible browser and platform combination.') |
| 78 source = run_test_in_browser(browser, html_out, timeout, is_perf) | 116 source = '' |
| 117 if browser == 'safari': |
| 118 source = run_test_in_browser_selenium1(sel, html_out, timeout, is_perf) |
| 119 else: |
| 120 source = run_test_in_browser(browser, html_out, timeout, is_perf) |
| 79 | 121 |
| 80 if is_perf: | 122 if is_perf: |
| 81 # We're running a performance test. | 123 # We're running a performance test. |
| 82 print source | 124 print source |
| 83 if 'NaN' in source: | 125 if 'NaN' in source: |
| 84 return 1 | 126 return 1 |
| 85 else: | 127 else: |
| 86 return 0 | 128 return 0 |
| 87 else: | 129 else: |
| 88 # We're running a correctness test. | 130 # We're running a correctness test. |
| 89 if ('PASS' in source): | 131 if ('PASS' in source): |
| 90 print 'Content-Type: text/plain\nPASS' | 132 print 'Content-Type: text/plain\nPASS' |
| 91 return 0 | 133 return 0 |
| 92 else: | 134 else: |
| 93 #The hacky way to get document.getElementById('body').innerHTML for this | 135 #The hacky way to get document.getElementById('body').innerHTML for this |
| 94 # webpage, without the JavaScript. | 136 # webpage, without the JavaScript. |
| 137 #TODO(efortuna): Access these elements in a nicer way using DOM parser. |
| 95 index = source.find('<body>') | 138 index = source.find('<body>') |
| 96 index += len('<body>') | 139 index += len('<body>') |
| 97 end_index = source.find('<script') | 140 end_index = source.find('<script') |
| 98 print source[index : end_index] | 141 print source[index : end_index] |
| 99 return 1 | 142 return 1 |
| 100 | 143 |
| 101 | 144 |
| 102 if __name__ == "__main__": | 145 if __name__ == "__main__": |
| 103 sys.exit(Main()) | 146 sys.exit(Main()) |
| OLD | NEW |