| 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 LineSplitter, UTF8; | 7 import "dart:convert" show LineSplitter, UTF8; |
| 8 import "dart:core"; | 8 import "dart:core"; |
| 9 import "dart:io"; | 9 import "dart:io"; |
| 10 | 10 |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 return _adbDevice.forceStop(chromePackage).then((_) { | 524 return _adbDevice.forceStop(chromePackage).then((_) { |
| 525 return _adbDevice.killAll().then((_) => true); | 525 return _adbDevice.killAll().then((_) => true); |
| 526 }); | 526 }); |
| 527 } | 527 } |
| 528 return new Future.value(true); | 528 return new Future.value(true); |
| 529 } | 529 } |
| 530 | 530 |
| 531 String toString() => "chromeOnAndroid"; | 531 String toString() => "chromeOnAndroid"; |
| 532 } | 532 } |
| 533 | 533 |
| 534 |
| 535 class ContentShellOnAndroid extends Browser { |
| 536 static const String viewAction = 'android.intent.action.VIEW'; |
| 537 static const String contentShellPackage = 'org.chromium.content_shell_apk'; |
| 538 |
| 539 AdbDevice _adbDevice; |
| 540 |
| 541 ContentShellOnAndroid(this._adbDevice); |
| 542 |
| 543 Future<bool> start(String url) { |
| 544 var contentShellIntent = new Intent( |
| 545 viewAction, contentShellPackage, '.ContentShellActivity', url); |
| 546 |
| 547 return _adbDevice.waitForBootCompleted().then((_) { |
| 548 return _adbDevice.forceStop(contentShellIntent.package); |
| 549 }).then((_) { |
| 550 return _adbDevice.killAll(); |
| 551 }).then((_) { |
| 552 return _adbDevice.adbRoot(); |
| 553 }).then((_) { |
| 554 return _adbDevice.setProp("DART_FORWARDING_PRINT", "1"); |
| 555 }).then((_) { |
| 556 return _adbDevice.startActivity(contentShellIntent).then((_) => true); |
| 557 }); |
| 558 } |
| 559 |
| 560 Future<bool> close() { |
| 561 if (_adbDevice != null) { |
| 562 return _adbDevice.forceStop(contentShellPackage).then((_) { |
| 563 return _adbDevice.killAll().then((_) => true); |
| 564 }); |
| 565 } |
| 566 return new Future.value(true); |
| 567 } |
| 568 |
| 569 String toString() => "ContentShellOnAndroid"; |
| 570 } |
| 571 |
| 572 |
| 534 class Firefox extends Browser { | 573 class Firefox extends Browser { |
| 535 static const String enablePopUp = | 574 static const String enablePopUp = |
| 536 'user_pref("dom.disable_open_during_load", false);'; | 575 'user_pref("dom.disable_open_during_load", false);'; |
| 537 static const String disableDefaultCheck = | 576 static const String disableDefaultCheck = |
| 538 'user_pref("browser.shell.checkDefaultBrowser", false);'; | 577 'user_pref("browser.shell.checkDefaultBrowser", false);'; |
| 539 static const String disableScriptTimeLimit = | 578 static const String disableScriptTimeLimit = |
| 540 'user_pref("dom.max_script_run_time", 0);'; | 579 'user_pref("dom.max_script_run_time", 0);'; |
| 541 | 580 |
| 542 static String _binary = _getBinary(); | 581 static String _binary = _getBinary(); |
| 543 | 582 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 BrowserTestRunner(this.globalConfiguration, | 722 BrowserTestRunner(this.globalConfiguration, |
| 684 this.localIp, | 723 this.localIp, |
| 685 this.browserName, | 724 this.browserName, |
| 686 this.maxNumBrowsers); | 725 this.maxNumBrowsers); |
| 687 | 726 |
| 688 Future<bool> start() { | 727 Future<bool> start() { |
| 689 // If [browserName] doesn't support opening new windows, we use new iframes | 728 // If [browserName] doesn't support opening new windows, we use new iframes |
| 690 // instead. | 729 // instead. |
| 691 bool useIframe = | 730 bool useIframe = |
| 692 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); | 731 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); |
| 693 testingServer = new BrowserTestingServer(localIp, useIframe); | 732 testingServer = new BrowserTestingServer( |
| 733 globalConfiguration, localIp, useIframe); |
| 694 return testingServer.start().then((_) { | 734 return testingServer.start().then((_) { |
| 695 testingServer.testDoneCallBack = handleResults; | 735 testingServer.testDoneCallBack = handleResults; |
| 696 testingServer.testStartedCallBack = handleStarted; | 736 testingServer.testStartedCallBack = handleStarted; |
| 697 testingServer.nextTestCallBack = getNextTest; | 737 testingServer.nextTestCallBack = getNextTest; |
| 698 return getBrowsers().then((browsers) { | 738 return getBrowsers().then((browsers) { |
| 699 var futures = []; | 739 var futures = []; |
| 700 for (var browser in browsers) { | 740 for (var browser in browsers) { |
| 701 var url = testingServer.getDriverUrl(browser.id); | 741 var url = testingServer.getDriverUrl(browser.id); |
| 702 var future = browser.start(url).then((success) { | 742 var future = browser.start(url).then((success) { |
| 703 if (success) { | 743 if (success) { |
| 704 browserStatus[browser.id] = new BrowserTestingStatus(browser); | 744 browserStatus[browser.id] = new BrowserTestingStatus(browser); |
| 705 } | 745 } |
| 706 return success; | 746 return success; |
| 707 }); | 747 }); |
| 708 futures.add(future); | 748 futures.add(future); |
| 709 } | 749 } |
| 710 return Future.wait(futures).then((values) { | 750 return Future.wait(futures).then((values) { |
| 711 return !values.contains(false); | 751 return !values.contains(false); |
| 712 }); | 752 }); |
| 713 }); | 753 }); |
| 714 }); | 754 }); |
| 715 } | 755 } |
| 716 | 756 |
| 717 Future<List<Browser>> getBrowsers() { | 757 Future<List<Browser>> getBrowsers() { |
| 718 // TODO(kustermann): This is a hackisch way to accomplish it and should | 758 // TODO(kustermann): This is a hackisch way to accomplish it and should |
| 719 // be encapsulated | 759 // be encapsulated |
| 720 var browsersCompleter = new Completer(); | 760 var browsersCompleter = new Completer(); |
| 721 if (browserName == 'chromeOnAndroid') { | 761 var androidBrowserCreationMapping = { |
| 762 'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device), |
| 763 'ContentShellOnAndroid' : (AdbDevice device) => |
| 764 new ContentShellOnAndroid(device), |
| 765 }; |
| 766 if (androidBrowserCreationMapping.containsKey(browserName)) { |
| 722 AdbHelper.listDevices().then((deviceIds) { | 767 AdbHelper.listDevices().then((deviceIds) { |
| 723 if (deviceIds.length > 0) { | 768 if (deviceIds.length > 0) { |
| 724 var browsers = []; | 769 var browsers = []; |
| 725 for (int i = 0; i < deviceIds.length; i++) { | 770 for (int i = 0; i < deviceIds.length; i++) { |
| 726 var id = "BROWSER$i"; | 771 var id = "BROWSER$i"; |
| 727 var device = new AdbDevice(deviceIds[i]); | 772 var device = new AdbDevice(deviceIds[i]); |
| 728 adbDeviceMapping[id] = device; | 773 adbDeviceMapping[id] = device; |
| 729 var browser = new AndroidChrome(device); | 774 var browser = androidBrowserCreationMapping[browserName](device); |
| 730 browsers.add(browser); | 775 browsers.add(browser); |
| 731 // We store this in case we need to kill the browser. | 776 // We store this in case we need to kill the browser. |
| 732 browser.id = id; | 777 browser.id = id; |
| 733 } | 778 } |
| 734 browsersCompleter.complete(browsers); | 779 browsersCompleter.complete(browsers); |
| 735 } else { | 780 } else { |
| 736 throw new StateError("No android devices found."); | 781 throw new StateError("No android devices found."); |
| 737 } | 782 } |
| 738 }); | 783 }); |
| 739 } else { | 784 } else { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 didTimeout: true); | 877 didTimeout: true); |
| 833 status.currentTest.doneCallback(browserTestOutput); | 878 status.currentTest.doneCallback(browserTestOutput); |
| 834 status.currentTest = null; | 879 status.currentTest = null; |
| 835 | 880 |
| 836 // We don't want to start a new browser if we are terminating. | 881 // We don't want to start a new browser if we are terminating. |
| 837 if (underTermination) return; | 882 if (underTermination) return; |
| 838 var browser; | 883 var browser; |
| 839 var new_id = id; | 884 var new_id = id; |
| 840 if (browserName == 'chromeOnAndroid') { | 885 if (browserName == 'chromeOnAndroid') { |
| 841 browser = new AndroidChrome(adbDeviceMapping[id]); | 886 browser = new AndroidChrome(adbDeviceMapping[id]); |
| 887 } else if (browserName == 'ContentShellOnAndroid') { |
| 888 browser = new ContentShellOnAndroid(adbDeviceMapping[id]); |
| 842 } else { | 889 } else { |
| 843 browserStatus.remove(id); | 890 browserStatus.remove(id); |
| 844 browser = getInstance(); | 891 browser = getInstance(); |
| 845 new_id = "BROWSER$browserIdCount"; | 892 new_id = "BROWSER$browserIdCount"; |
| 846 browserIdCount++; | 893 browserIdCount++; |
| 847 browserStatus[new_id] = new BrowserTestingStatus(browser); | 894 browserStatus[new_id] = new BrowserTestingStatus(browser); |
| 848 } | 895 } |
| 849 browser.id = new_id; | 896 browser.id = new_id; |
| 850 browser.start(testingServer.getDriverUrl(new_id)).then((success) { | 897 browser.start(testingServer.getDriverUrl(new_id)).then((success) { |
| 851 // We may have started terminating in the mean time. | 898 // We may have started terminating in the mean time. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 } | 994 } |
| 948 | 995 |
| 949 Browser getInstance() { | 996 Browser getInstance() { |
| 950 var browser = new Browser.byName(browserName, globalConfiguration); | 997 var browser = new Browser.byName(browserName, globalConfiguration); |
| 951 browser.logger = logger; | 998 browser.logger = logger; |
| 952 return browser; | 999 return browser; |
| 953 } | 1000 } |
| 954 } | 1001 } |
| 955 | 1002 |
| 956 class BrowserTestingServer { | 1003 class BrowserTestingServer { |
| 1004 final Map globalConfiguration; |
| 957 /// Interface of the testing server: | 1005 /// Interface of the testing server: |
| 958 /// | 1006 /// |
| 959 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 1007 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| 960 /// and run tests ... | 1008 /// and run tests ... |
| 961 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" | 1009 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" |
| 962 /// where url is the test to run, and id is the id of the test. | 1010 /// where url is the test to run, and id is the id of the test. |
| 963 /// If there are currently no available tests the waitSignal is send | 1011 /// If there are currently no available tests the waitSignal is send |
| 964 /// back. If we are in the process of terminating the terminateSignal | 1012 /// back. If we are in the process of terminating the terminateSignal |
| 965 /// is send back and the browser will stop requesting new tasks. | 1013 /// is send back and the browser will stop requesting new tasks. |
| 966 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed | 1014 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed |
| (...skipping 11 matching lines...) Expand all Loading... |
| 978 var testCount = 0; | 1026 var testCount = 0; |
| 979 var httpServer; | 1027 var httpServer; |
| 980 var errorReportingServer; | 1028 var errorReportingServer; |
| 981 bool underTermination = false; | 1029 bool underTermination = false; |
| 982 bool useIframe = false; | 1030 bool useIframe = false; |
| 983 | 1031 |
| 984 Function testDoneCallBack; | 1032 Function testDoneCallBack; |
| 985 Function testStartedCallBack; | 1033 Function testStartedCallBack; |
| 986 Function nextTestCallBack; | 1034 Function nextTestCallBack; |
| 987 | 1035 |
| 988 BrowserTestingServer(this.localIp, this.useIframe); | 1036 BrowserTestingServer(this.globalConfiguration, this.localIp, this.useIframe); |
| 989 | 1037 |
| 990 Future start() { | 1038 Future start() { |
| 991 return HttpServer.bind(localIp, 0).then((createdServer) { | 1039 int port = globalConfiguration['test_driver_port']; |
| 1040 return HttpServer.bind(localIp, port).then((createdServer) { |
| 992 httpServer = createdServer; | 1041 httpServer = createdServer; |
| 993 void handler(HttpRequest request) { | 1042 void handler(HttpRequest request) { |
| 994 // Don't allow caching of resources from the browser controller, i.e., | 1043 // Don't allow caching of resources from the browser controller, i.e., |
| 995 // we don't want the browser to cache the result of getNextTest. | 1044 // we don't want the browser to cache the result of getNextTest. |
| 996 request.response.headers.set("Cache-Control", | 1045 request.response.headers.set("Cache-Control", |
| 997 "no-cache, no-store, must-revalidate"); | 1046 "no-cache, no-store, must-revalidate"); |
| 998 if (request.uri.path.startsWith(reportPath)) { | 1047 if (request.uri.path.startsWith(reportPath)) { |
| 999 var browserId = request.uri.path.substring(reportPath.length + 1); | 1048 var browserId = request.uri.path.substring(reportPath.length + 1); |
| 1000 var testId = | 1049 var testId = |
| 1001 int.parse(request.uri.queryParameters["id"].split("=")[1]); | 1050 int.parse(request.uri.queryParameters["id"].split("=")[1]); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1032 }); | 1081 }); |
| 1033 } | 1082 } |
| 1034 void errorHandler(e) { | 1083 void errorHandler(e) { |
| 1035 if (!underTermination) print("Error occured in httpserver: $e"); | 1084 if (!underTermination) print("Error occured in httpserver: $e"); |
| 1036 }; | 1085 }; |
| 1037 | 1086 |
| 1038 httpServer.listen(handler, onError: errorHandler); | 1087 httpServer.listen(handler, onError: errorHandler); |
| 1039 | 1088 |
| 1040 // Set up the error reporting server that enables us to send back | 1089 // Set up the error reporting server that enables us to send back |
| 1041 // errors from the browser. | 1090 // errors from the browser. |
| 1042 return HttpServer.bind(localIp, 0).then((createdReportServer) { | 1091 port = globalConfiguration['test_driver_error_port']; |
| 1092 return HttpServer.bind(localIp, port).then((createdReportServer) { |
| 1043 errorReportingServer = createdReportServer; | 1093 errorReportingServer = createdReportServer; |
| 1044 void errorReportingHandler(HttpRequest request) { | 1094 void errorReportingHandler(HttpRequest request) { |
| 1045 StringBuffer buffer = new StringBuffer(); | 1095 StringBuffer buffer = new StringBuffer(); |
| 1046 request.transform(UTF8.decoder).listen((data) { | 1096 request.transform(UTF8.decoder).listen((data) { |
| 1047 buffer.write(data); | 1097 buffer.write(data); |
| 1048 }, onDone: () { | 1098 }, onDone: () { |
| 1049 String back = buffer.toString(); | 1099 String back = buffer.toString(); |
| 1050 request.response.headers.set("Access-Control-Allow-Origin", "*"); | 1100 request.response.headers.set("Access-Control-Allow-Origin", "*"); |
| 1051 request.response.done.catchError((error) { | 1101 request.response.done.catchError((error) { |
| 1052 DebugLogger.error("Error getting error from browser" | 1102 DebugLogger.error("Error getting error from browser" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 Dart test driver, number of tests: <div id="number"></div><br> | 1316 Dart test driver, number of tests: <div id="number"></div><br> |
| 1267 Currently executing: <div id="currently_executing"></div><br> | 1317 Currently executing: <div id="currently_executing"></div><br> |
| 1268 Unhandled error: <div id="unhandled_error"></div> | 1318 Unhandled error: <div id="unhandled_error"></div> |
| 1269 <iframe id="embedded_iframe"></iframe> | 1319 <iframe id="embedded_iframe"></iframe> |
| 1270 </body> | 1320 </body> |
| 1271 </html> | 1321 </html> |
| 1272 """; | 1322 """; |
| 1273 return driverContent; | 1323 return driverContent; |
| 1274 } | 1324 } |
| 1275 } | 1325 } |
| OLD | NEW |