| 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. It uses Selenium WebDriver when possible for running the tests. It | 9 the result. It uses Selenium WebDriver when possible for running the tests. It |
| 10 uses Selenium RC for Safari. | 10 uses Selenium RC for Safari. |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 """Provide the user an informative error message if we attempt to connect to | 134 """Provide the user an informative error message if we attempt to connect to |
| 135 the Selenium remote control server, but cannot access it. Then exit the | 135 the Selenium remote control server, but cannot access it. Then exit the |
| 136 program.""" | 136 program.""" |
| 137 print ('ERROR: Could not connect to Selenium RC server. Are you running' | 137 print ('ERROR: Could not connect to Selenium RC server. Are you running' |
| 138 ' java -jar tools/testing/selenium-server-standalone-*.jar? If not, ' | 138 ' java -jar tools/testing/selenium-server-standalone-*.jar? If not, ' |
| 139 'start it before running this test.') | 139 'start it before running this test.') |
| 140 sys.exit(1) | 140 sys.exit(1) |
| 141 | 141 |
| 142 def start_browser(browser, executable_path, html_out): | 142 def start_browser(browser, executable_path, html_out): |
| 143 if browser == 'chrome': | 143 if browser == 'chrome': |
| 144 script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 145 crx = os.path.join(script_dir, 'extensions', 'chrome', |
| 146 'ConsoleCollector.crx') |
| 147 options = selenium.webdriver.chrome.options.Options() |
| 148 options.add_extension(crx) |
| 144 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to | 149 # Note: you need ChromeDriver *in your path* to run Chrome, in addition to |
| 145 # installing Chrome. Also note that the build bot runs have a different path | 150 # installing Chrome. Also note that the build bot runs have a different path |
| 146 # from a normal user -- check the build logs. | 151 # from a normal user -- check the build logs. |
| 147 return selenium.webdriver.Chrome() | 152 return selenium.webdriver.Chrome(chrome_options=options) |
| 148 elif browser == 'dartium': | 153 elif browser == 'dartium': |
| 149 script_dir = os.path.dirname(os.path.abspath(__file__)) | 154 script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 150 dartium_dir = os.path.join(script_dir, '..', '..', 'client', 'tests', | 155 dartium_dir = os.path.join(script_dir, '..', '..', 'client', 'tests', |
| 151 'dartium') | 156 'dartium') |
| 157 crx = os.path.join(script_dir, 'extensions', 'chrome', |
| 158 'ConsoleCollector.crx') |
| 152 options = selenium.webdriver.chrome.options.Options() | 159 options = selenium.webdriver.chrome.options.Options() |
| 160 options.add_extension(crx) |
| 153 # enable ShadowDOM and style scoped for Dartium | 161 # enable ShadowDOM and style scoped for Dartium |
| 154 options.add_argument('--enable-shadow-dom') | 162 options.add_argument('--enable-shadow-dom') |
| 155 options.add_argument('--enable-style-scoped') | 163 options.add_argument('--enable-style-scoped') |
| 156 if executable_path is not None: | 164 if executable_path is not None: |
| 157 options.binary_location = executable_path | 165 options.binary_location = executable_path |
| 158 elif platform.system() == 'Windows': | 166 elif platform.system() == 'Windows': |
| 159 options.binary_location = os.path.join(dartium_dir, 'chrome.exe') | 167 options.binary_location = os.path.join(dartium_dir, 'chrome.exe') |
| 160 elif platform.system() == 'Darwin': | 168 elif platform.system() == 'Darwin': |
| 161 options.binary_location = os.path.join(dartium_dir, 'Chromium.app', | 169 options.binary_location = os.path.join(dartium_dir, 'Chromium.app', |
| 162 'Contents', 'MacOS', 'Chromium') | 170 'Contents', 'MacOS', 'Chromium') |
| 163 else: | 171 else: |
| 164 options.binary_location = os.path.join(dartium_dir, 'chrome') | 172 options.binary_location = os.path.join(dartium_dir, 'chrome') |
| 165 return selenium.webdriver.Chrome(chrome_options=options) | 173 return selenium.webdriver.Chrome(chrome_options=options) |
| 166 elif browser == 'ff': | 174 elif browser == 'ff': |
| 167 script_dir = os.path.dirname(os.path.abspath(__file__)) | 175 script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 168 profile = selenium.webdriver.firefox.firefox_profile.FirefoxProfile() | 176 profile = selenium.webdriver.firefox.firefox_profile.FirefoxProfile() |
| 169 profile.set_preference('dom.max_script_run_time', 0) | 177 profile.set_preference('dom.max_script_run_time', 0) |
| 170 profile.set_preference('dom.max_chrome_script_run_time', 0) | 178 profile.set_preference('dom.max_chrome_script_run_time', 0) |
| 171 profile.set_preference('app.update.auto', True) | 179 profile.set_preference('app.update.auto', True) |
| 172 profile.set_preference('app.update.enabled', True) | 180 profile.set_preference('app.update.enabled', True) |
| 173 xpi = os.path.join(script_dir, 'extensions', 'firefox',
'ConsoleCollector.xpi') | 181 xpi = os.path.join(script_dir, 'extensions', 'firefox', |
| 182 'ConsoleCollector.xpi') |
| 174 profile.add_extension(xpi); | 183 profile.add_extension(xpi); |
| 175 return selenium.webdriver.Firefox(firefox_profile=profile) | 184 return selenium.webdriver.Firefox(firefox_profile=profile) |
| 176 elif browser == 'ie' and platform.system() == 'Windows': | 185 elif browser == 'ie' and platform.system() == 'Windows': |
| 177 return selenium.webdriver.Ie() | 186 return selenium.webdriver.Ie() |
| 178 elif browser == 'safari' and platform.system() == 'Darwin': | 187 elif browser == 'safari' and platform.system() == 'Darwin': |
| 179 # TODO(efortuna): Ensure our preferences (no pop-up blocking) file is the | 188 # TODO(efortuna): Ensure our preferences (no pop-up blocking) file is the |
| 180 # same (Safari auto-deletes when it has too many "crashes," or in our case, | 189 # same (Safari auto-deletes when it has too many "crashes," or in our case, |
| 181 # timeouts). Come up with a less hacky way to do this. | 190 # timeouts). Come up with a less hacky way to do this. |
| 182 backup_safari_prefs = os.path.dirname(__file__) + '/com.apple.Safari.plist' | 191 backup_safari_prefs = os.path.dirname(__file__) + '/com.apple.Safari.plist' |
| 183 if os.path.exists(backup_safari_prefs): | 192 if os.path.exists(backup_safari_prefs): |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 print 'Content-Type: text/plain\nPASS' | 249 print 'Content-Type: text/plain\nPASS' |
| 241 return 0 | 250 return 0 |
| 242 else: | 251 else: |
| 243 #The hacky way to get document.getElementById('body').innerHTML for this | 252 #The hacky way to get document.getElementById('body').innerHTML for this |
| 244 # webpage, without the JavaScript. | 253 # webpage, without the JavaScript. |
| 245 #TODO(efortuna): Access these elements in a nicer way using DOM parser. | 254 #TODO(efortuna): Access these elements in a nicer way using DOM parser. |
| 246 index = source.find('<body>') | 255 index = source.find('<body>') |
| 247 index += len('<body>') | 256 index += len('<body>') |
| 248 end_index = source.find('</body') | 257 end_index = source.find('</body') |
| 249 print unicode(source[index : end_index]).encode("utf-8") | 258 print unicode(source[index : end_index]).encode("utf-8") |
| 259 logs = [] |
| 250 if type(browser) is selenium.webdriver.firefox.webdriver.WebDriver: | 260 if type(browser) is selenium.webdriver.firefox.webdriver.WebDriver: |
| 251 logs = browser.execute_script("return window.ConsoleCollector.read()"); | 261 logs = browser.execute_script("return window.ConsoleCollector.read()"); |
| 252 for msg in logs: | 262 elif type(browser) is selenium.webdriver.chrome.webdriver.WebDriver: |
| 253 print('%s:%s:%s:%s %s' %( | 263 browser.set_script_timeout(100) |
| 254 msg['source'], msg['line'], msg['column'], | 264 logs = browser.execute_async_script( |
| 255 msg['category'], msg['message'])) | 265 "getMessages(arguments[arguments.length-1])"); |
| 266 for msg in logs: |
| 267 print('%s:%s:%s %s' %( |
| 268 msg['source'], msg['line'], msg['category'], msg['message'])) |
| 256 return 1 | 269 return 1 |
| 257 | 270 |
| 258 | 271 |
| 259 def run_batch_tests(): | 272 def run_batch_tests(): |
| 260 ''' | 273 ''' |
| 261 Runs a batch of in-browser tests in the same browser process. Batching | 274 Runs a batch of in-browser tests in the same browser process. Batching |
| 262 gives faster throughput and makes tests less subject to browser starting | 275 gives faster throughput and makes tests less subject to browser starting |
| 263 flakiness, issues with too many browser processes running, etc. | 276 flakiness, issues with too many browser processes running, etc. |
| 264 | 277 |
| 265 When running this function, stdin/stdout is used to communicate with the test | 278 When running this function, stdin/stdout is used to communicate with the test |
| (...skipping 15 matching lines...) Expand all Loading... |
| 281 current_browser_name = None | 294 current_browser_name = None |
| 282 | 295 |
| 283 # TODO(jmesserly): It'd be nice to shutdown gracefully in the event of a | 296 # TODO(jmesserly): It'd be nice to shutdown gracefully in the event of a |
| 284 # SIGTERM. Unfortunately dart:io cannot send SIGTERM, see dartbug.com/1756. | 297 # SIGTERM. Unfortunately dart:io cannot send SIGTERM, see dartbug.com/1756. |
| 285 signal.signal(signal.SIGTERM, lambda number, frame: close_browser(browser)) | 298 signal.signal(signal.SIGTERM, lambda number, frame: close_browser(browser)) |
| 286 | 299 |
| 287 try: | 300 try: |
| 288 while True: | 301 while True: |
| 289 line = sys.stdin.readline() | 302 line = sys.stdin.readline() |
| 290 if line == '--terminate\n': | 303 if line == '--terminate\n': |
| 291 print("Terminating selenium driver") | |
| 292 break | 304 break |
| 293 | 305 |
| 294 (html_out, browser_name, executable_path, | 306 (html_out, browser_name, executable_path, |
| 295 timeout, mode) = parse_args(line.split()) | 307 timeout, mode) = parse_args(line.split()) |
| 296 | 308 |
| 297 # Sanity checks that test.dart is passing flags we can handle. | 309 # Sanity checks that test.dart is passing flags we can handle. |
| 298 if mode != 'correctness': | 310 if mode != 'correctness': |
| 299 print 'Batch test runner not compatible with perf testing' | 311 print 'Batch test runner not compatible with perf testing' |
| 300 return 1 | 312 return 1 |
| 301 if browser and current_browser_name != browser_name: | 313 if browser and current_browser_name != browser_name: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 318 # >>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT} | 330 # >>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT} |
| 319 status = report_results(mode, source, browser) | 331 status = report_results(mode, source, browser) |
| 320 if status == 0: | 332 if status == 0: |
| 321 print '>>> TEST PASS' | 333 print '>>> TEST PASS' |
| 322 elif source == TIMEOUT_ERROR_MSG: | 334 elif source == TIMEOUT_ERROR_MSG: |
| 323 print '>>> TEST TIMEOUT' | 335 print '>>> TEST TIMEOUT' |
| 324 else: | 336 else: |
| 325 print '>>> TEST FAIL' | 337 print '>>> TEST FAIL' |
| 326 sys.stdout.flush() | 338 sys.stdout.flush() |
| 327 finally: | 339 finally: |
| 328 print("Closing browser"); | |
| 329 close_browser(browser) | 340 close_browser(browser) |
| 330 | 341 |
| 331 | 342 |
| 332 def main(args): | 343 def main(args): |
| 333 # Run in batch mode if the --batch flag is passed. | 344 # Run in batch mode if the --batch flag is passed. |
| 334 # TODO(jmesserly): reconcile with the existing args parsing | 345 # TODO(jmesserly): reconcile with the existing args parsing |
| 335 if '--batch' in args: | 346 if '--batch' in args: |
| 336 return run_batch_tests() | 347 return run_batch_tests() |
| 337 | 348 |
| 338 # Run a single test | 349 # Run a single test |
| 339 html_out, browser_name, executable_path, timeout, mode = parse_args() | 350 html_out, browser_name, executable_path, timeout, mode = parse_args() |
| 340 browser = start_browser(browser_name, executable_path, html_out) | 351 browser = start_browser(browser_name, executable_path, html_out) |
| 341 | 352 |
| 342 try: | 353 try: |
| 343 output = run_test_in_browser(browser, html_out, timeout, mode) | 354 output = run_test_in_browser(browser, html_out, timeout, mode) |
| 344 return report_results(mode, output, browser) | 355 return report_results(mode, output, browser) |
| 345 finally: | 356 finally: |
| 346 close_browser(browser) | 357 close_browser(browser) |
| 347 | 358 |
| 348 if __name__ == "__main__": | 359 if __name__ == "__main__": |
| 349 sys.exit(main(sys.argv)) | 360 sys.exit(main(sys.argv)) |
| OLD | NEW |