| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library browser; | 4 library browser; |
| 5 | 5 |
| 6 import "dart:async"; | 6 import "dart:async"; |
| 7 import "dart:convert" show UTF8, JSON; | 7 import "dart:convert" show UTF8, JSON; |
| 8 import "dart:core"; | 8 import "dart:core"; |
| 9 import "dart:io"; | 9 import "dart:io"; |
| 10 import "dart:math" show min; | 10 import "dart:math" show min; |
| 11 | 11 |
| 12 import 'android.dart'; | 12 import 'android.dart'; |
| 13 import 'http_server.dart'; | 13 import 'http_server.dart'; |
| 14 import 'path.dart'; | 14 import 'path.dart'; |
| 15 import 'utils.dart'; | 15 import 'utils.dart'; |
| 16 | 16 |
| 17 import 'reset_safari.dart' show | 17 import 'reset_safari.dart' show killAndResetSafari; |
| 18 killAndResetSafari; | |
| 19 | 18 |
| 20 class BrowserOutput { | 19 class BrowserOutput { |
| 21 final StringBuffer stdout = new StringBuffer(); | 20 final StringBuffer stdout = new StringBuffer(); |
| 22 final StringBuffer stderr = new StringBuffer(); | 21 final StringBuffer stderr = new StringBuffer(); |
| 23 final StringBuffer eventLog = new StringBuffer(); | 22 final StringBuffer eventLog = new StringBuffer(); |
| 24 } | 23 } |
| 25 | 24 |
| 26 /** Class describing the interface for communicating with browsers. */ | 25 /** Class describing the interface for communicating with browsers. */ |
| 27 abstract class Browser { | 26 abstract class Browser { |
| 28 BrowserOutput _allBrowserOutput = new BrowserOutput(); | 27 BrowserOutput _allBrowserOutput = new BrowserOutput(); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 if (!Browser.resetBrowserConfiguration) return true; | 304 if (!Browser.resetBrowserConfiguration) return true; |
| 306 | 305 |
| 307 Completer completer = new Completer(); | 306 Completer completer = new Completer(); |
| 308 handleUncaughtError(error, StackTrace stackTrace) { | 307 handleUncaughtError(error, StackTrace stackTrace) { |
| 309 if (!completer.isCompleted) { | 308 if (!completer.isCompleted) { |
| 310 completer.completeError(error, stackTrace); | 309 completer.completeError(error, stackTrace); |
| 311 } else { | 310 } else { |
| 312 throw new AsyncError(error, stackTrace); | 311 throw new AsyncError(error, stackTrace); |
| 313 } | 312 } |
| 314 } | 313 } |
| 314 |
| 315 Zone parent = Zone.current; | 315 Zone parent = Zone.current; |
| 316 ZoneSpecification specification = new ZoneSpecification( | 316 ZoneSpecification specification = new ZoneSpecification( |
| 317 print: (Zone self, ZoneDelegate delegate, Zone zone, String line) { | 317 print: (Zone self, ZoneDelegate delegate, Zone zone, String line) { |
| 318 delegate.run(parent, () { | 318 delegate.run(parent, () { |
| 319 _logEvent(line); | 319 _logEvent(line); |
| 320 }); | 320 }); |
| 321 }); | 321 }); |
| 322 Future zoneWrapper() { | 322 Future zoneWrapper() { |
| 323 Uri safariUri = Uri.base.resolve(safariBundleLocation); | 323 Uri safariUri = Uri.base.resolve(safariBundleLocation); |
| 324 return new Future(() => killAndResetSafari(bundle: safariUri)) | 324 return new Future(() => killAndResetSafari(bundle: safariUri)) |
| 325 .then(completer.complete); | 325 .then(completer.complete); |
| 326 } | 326 } |
| 327 | 327 |
| 328 // We run killAndResetSafari in a Zone as opposed to running an external | 328 // We run killAndResetSafari in a Zone as opposed to running an external |
| 329 // process. The Zone allows us to collect its output, and protect the rest | 329 // process. The Zone allows us to collect its output, and protect the rest |
| 330 // of the test infrastructure against errors in it. | 330 // of the test infrastructure against errors in it. |
| 331 runZoned( | 331 runZoned(zoneWrapper, |
| 332 zoneWrapper, zoneSpecification: specification, | 332 zoneSpecification: specification, onError: handleUncaughtError); |
| 333 onError: handleUncaughtError); | |
| 334 | 333 |
| 335 try { | 334 try { |
| 336 await completer.future; | 335 await completer.future; |
| 337 return true; | 336 return true; |
| 338 } catch (error, st) { | 337 } catch (error, st) { |
| 339 _logEvent("Unable to reset Safari: $error$st"); | 338 _logEvent("Unable to reset Safari: $error$st"); |
| 340 return false; | 339 return false; |
| 341 } | 340 } |
| 342 } | 341 } |
| 343 | 342 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 _cleanup = () { | 405 _cleanup = () { |
| 407 userDir.deleteSync(recursive: true); | 406 userDir.deleteSync(recursive: true); |
| 408 }; | 407 }; |
| 409 try { | 408 try { |
| 410 await _createLaunchHTML(userDir.path, url); | 409 await _createLaunchHTML(userDir.path, url); |
| 411 } catch (error) { | 410 } catch (error) { |
| 412 _logEvent("Error creating launch HTML: $error"); | 411 _logEvent("Error creating launch HTML: $error"); |
| 413 return false; | 412 return false; |
| 414 } | 413 } |
| 415 var args = [ | 414 var args = [ |
| 416 "-d", "-i", "-m", "-s", "-u", _binary, | 415 "-d", |
| 417 "${userDir.path}/launch.html"]; | 416 "-i", |
| 417 "-m", |
| 418 "-s", |
| 419 "-u", |
| 420 _binary, |
| 421 "${userDir.path}/launch.html" |
| 422 ]; |
| 418 try { | 423 try { |
| 419 return startBrowserProcess("/usr/bin/caffeinate", args); | 424 return startBrowserProcess("/usr/bin/caffeinate", args); |
| 420 } catch (error) { | 425 } catch (error) { |
| 421 _logEvent("Error starting browser process: $error"); | 426 _logEvent("Error starting browser process: $error"); |
| 422 return false; | 427 return false; |
| 423 } | 428 } |
| 424 } | 429 } |
| 425 | 430 |
| 426 Future<Null> onDriverPageRequested() async { | 431 Future<Null> onDriverPageRequested() async { |
| 427 await Process.run("/usr/bin/osascript", | 432 await Process.run( |
| 428 ['-e', 'tell application "Safari" to activate']); | 433 "/usr/bin/osascript", ['-e', 'tell application "Safari" to activate']); |
| 429 } | 434 } |
| 430 | 435 |
| 431 String toString() => "Safari"; | 436 String toString() => "Safari"; |
| 432 } | 437 } |
| 433 | 438 |
| 434 class Chrome extends Browser { | 439 class Chrome extends Browser { |
| 435 String _version = "Version not found yet"; | 440 String _version = "Version not found yet"; |
| 436 | 441 |
| 437 Map<String, String> _getEnvironment() => null; | 442 Map<String, String> _getEnvironment() => null; |
| 438 | 443 |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 _logEvent("Failed to firefox get version"); | 797 _logEvent("Failed to firefox get version"); |
| 793 _logEvent("Make sure $_binary is a valid program for running firefox"); | 798 _logEvent("Make sure $_binary is a valid program for running firefox"); |
| 794 return new Future.value(false); | 799 return new Future.value(false); |
| 795 } | 800 } |
| 796 version = versionResult.stdout; | 801 version = versionResult.stdout; |
| 797 _logEvent("Got version: $version"); | 802 _logEvent("Got version: $version"); |
| 798 | 803 |
| 799 return Directory.systemTemp.createTemp().then((userDir) { | 804 return Directory.systemTemp.createTemp().then((userDir) { |
| 800 _createPreferenceFile(userDir.path); | 805 _createPreferenceFile(userDir.path); |
| 801 _cleanup = () { | 806 _cleanup = () { |
| 802 userDir.deleteSync(recursive: true); | 807 try { |
| 808 userDir.deleteSync(recursive: true); |
| 809 } catch (e) { |
| 810 _logEvent( |
| 811 "Error: failed to delete Chrome user-data-dir ${userDir.path}" |
| 812 ", will try again in 40 seconds: $e"); |
| 813 new Timer(new Duration(seconds: 40), () { |
| 814 try { |
| 815 userDir.deleteSync(recursive: true); |
| 816 } catch (e) { |
| 817 _logEvent("Error: failed on second attempt to delete Chrome " |
| 818 "user-data-dir ${userDir.path}: $e"); |
| 819 } |
| 820 }); |
| 821 } |
| 803 }; | 822 }; |
| 804 var args = [ | 823 var args = [ |
| 805 "-profile", | 824 "-profile", |
| 806 "${userDir.path}", | 825 "${userDir.path}", |
| 807 "-no-remote", | 826 "-no-remote", |
| 808 "-new-instance", | 827 "-new-instance", |
| 809 url | 828 url |
| 810 ]; | 829 ]; |
| 811 var environment = new Map<String, String>.from(Platform.environment); | 830 var environment = new Map<String, String>.from(Platform.environment); |
| 812 environment["MOZ_CRASHREPORTER_DISABLE"] = "1"; | 831 environment["MOZ_CRASHREPORTER_DISABLE"] = "1"; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 // When no browser is currently starting, _currentStartingBrowserId is null. | 983 // When no browser is currently starting, _currentStartingBrowserId is null. |
| 965 bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null; | 984 bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null; |
| 966 void markCurrentlyStarting(String id) { | 985 void markCurrentlyStarting(String id) { |
| 967 _currentStartingBrowserId = id; | 986 _currentStartingBrowserId = id; |
| 968 } | 987 } |
| 969 | 988 |
| 970 void markNotCurrentlyStarting(String id) { | 989 void markNotCurrentlyStarting(String id) { |
| 971 if (_currentStartingBrowserId == id) _currentStartingBrowserId = null; | 990 if (_currentStartingBrowserId == id) _currentStartingBrowserId = null; |
| 972 } | 991 } |
| 973 | 992 |
| 974 BrowserTestRunner( | 993 BrowserTestRunner(Map configuration, String localIp, String browserName, |
| 975 Map configuration, | |
| 976 String localIp, | |
| 977 String browserName, | |
| 978 this.maxNumBrowsers) | 994 this.maxNumBrowsers) |
| 979 : configuration = configuration, | 995 : configuration = configuration, |
| 980 localIp = localIp, | 996 localIp = localIp, |
| 981 browserName = (browserName == 'ff') ? 'firefox' : browserName, | 997 browserName = (browserName == 'ff') ? 'firefox' : browserName, |
| 982 checkedMode = configuration['checked'], | 998 checkedMode = configuration['checked'], |
| 983 testingServer = new BrowserTestingServer( | 999 testingServer = new BrowserTestingServer( |
| 984 configuration, localIp, | 1000 configuration, |
| 1001 localIp, |
| 985 Browser.requiresIframe(browserName), | 1002 Browser.requiresIframe(browserName), |
| 986 Browser.requiresFocus(browserName)) { | 1003 Browser.requiresFocus(browserName)) { |
| 987 testingServer.testRunner = this; | 1004 testingServer.testRunner = this; |
| 988 } | 1005 } |
| 989 | 1006 |
| 990 Future start() async { | 1007 Future start() async { |
| 991 await testingServer.start(); | 1008 await testingServer.start(); |
| 992 testingServer | 1009 testingServer |
| 993 ..testDoneCallBack = handleResults | 1010 ..testDoneCallBack = handleResults |
| 994 ..testStatusUpdateCallBack = handleStatusUpdate | 1011 ..testStatusUpdateCallBack = handleStatusUpdate |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 DebugLogger.error("Error getting error from browser" | 1386 DebugLogger.error("Error getting error from browser" |
| 1370 "on uri ${request.uri.path}: $error"); | 1387 "on uri ${request.uri.path}: $error"); |
| 1371 }); | 1388 }); |
| 1372 request.response.close(); | 1389 request.response.close(); |
| 1373 DebugLogger.error("Error from browser on : " | 1390 DebugLogger.error("Error from browser on : " |
| 1374 "${request.uri.path}, data: $back"); | 1391 "${request.uri.path}, data: $back"); |
| 1375 }, onError: (error) { | 1392 }, onError: (error) { |
| 1376 print(error); | 1393 print(error); |
| 1377 }); | 1394 }); |
| 1378 } | 1395 } |
| 1396 |
| 1379 void errorHandler(e) { | 1397 void errorHandler(e) { |
| 1380 if (!underTermination) print("Error occured in httpserver: $e"); | 1398 if (!underTermination) print("Error occured in httpserver: $e"); |
| 1381 } | 1399 } |
| 1400 |
| 1382 errorReportingServer.listen(errorReportingHandler, onError: errorHandler); | 1401 errorReportingServer.listen(errorReportingHandler, onError: errorHandler); |
| 1383 } | 1402 } |
| 1384 | 1403 |
| 1385 void setupDispatchingServer(_) { | 1404 void setupDispatchingServer(_) { |
| 1386 DispatchingServer server = configuration['_servers_'].server; | 1405 DispatchingServer server = configuration['_servers_'].server; |
| 1387 void noCache(request) { | 1406 void noCache(request) { |
| 1388 request.response.headers | 1407 request.response.headers |
| 1389 .set("Cache-Control", "no-cache, no-store, must-revalidate"); | 1408 .set("Cache-Control", "no-cache, no-store, must-revalidate"); |
| 1390 } | 1409 } |
| 1410 |
| 1391 int testId(request) => int.parse(request.uri.queryParameters["id"]); | 1411 int testId(request) => int.parse(request.uri.queryParameters["id"]); |
| 1392 String browserId(request, prefix) => | 1412 String browserId(request, prefix) => |
| 1393 request.uri.path.substring(prefix.length + 1); | 1413 request.uri.path.substring(prefix.length + 1); |
| 1394 | 1414 |
| 1395 server.addHandler(reportPath, (HttpRequest request) { | 1415 server.addHandler(reportPath, (HttpRequest request) { |
| 1396 noCache(request); | 1416 noCache(request); |
| 1397 handleReport(request, browserId(request, reportPath), testId(request), | 1417 handleReport(request, browserId(request, reportPath), testId(request), |
| 1398 isStatusUpdate: false); | 1418 isStatusUpdate: false); |
| 1399 }); | 1419 }); |
| 1400 server.addHandler(statusUpdatePath, (HttpRequest request) { | 1420 server.addHandler(statusUpdatePath, (HttpRequest request) { |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1851 </div> | 1871 </div> |
| 1852 <div id="embedded_iframe_div" class="test box"> | 1872 <div id="embedded_iframe_div" class="test box"> |
| 1853 <iframe id="embedded_iframe"></iframe> | 1873 <iframe id="embedded_iframe"></iframe> |
| 1854 </div> | 1874 </div> |
| 1855 </body> | 1875 </body> |
| 1856 </html> | 1876 </html> |
| 1857 """; | 1877 """; |
| 1858 return driverContent; | 1878 return driverContent; |
| 1859 } | 1879 } |
| 1860 } | 1880 } |
| OLD | NEW |