| 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 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 return _adbDevice.forceStop(chromePackage).then((_) { | 530 return _adbDevice.forceStop(chromePackage).then((_) { |
| 531 return _adbDevice.killAll().then((_) => true); | 531 return _adbDevice.killAll().then((_) => true); |
| 532 }); | 532 }); |
| 533 } | 533 } |
| 534 return new Future.value(true); | 534 return new Future.value(true); |
| 535 } | 535 } |
| 536 | 536 |
| 537 String toString() => "chromeOnAndroid"; | 537 String toString() => "chromeOnAndroid"; |
| 538 } | 538 } |
| 539 | 539 |
| 540 |
| 541 class ContentShellOnAndroid extends Browser { |
| 542 static const String viewAction = 'android.intent.action.VIEW'; |
| 543 static const String contentShellPackage = 'org.chromium.content_shell_apk'; |
| 544 |
| 545 AdbDevice _adbDevice; |
| 546 |
| 547 ContentShellOnAndroid(this._adbDevice); |
| 548 |
| 549 Future<bool> start(String url) { |
| 550 var contentShellIntent = new Intent( |
| 551 viewAction, contentShellPackage, '.ContentShellActivity', url); |
| 552 |
| 553 return _adbDevice.waitForBootCompleted().then((_) { |
| 554 return _adbDevice.forceStop(contentShellIntent.package); |
| 555 }).then((_) { |
| 556 return _adbDevice.killAll(); |
| 557 }).then((_) { |
| 558 return _adbDevice.adbRoot(); |
| 559 }).then((_) { |
| 560 return _adbDevice.setProp("DART_FORWARDING_PRINT", "1"); |
| 561 }).then((_) { |
| 562 return _adbDevice.startActivity(contentShellIntent).then((_) => true); |
| 563 }); |
| 564 } |
| 565 |
| 566 Future<bool> close() { |
| 567 if (_adbDevice != null) { |
| 568 return _adbDevice.forceStop(contentShellPackage).then((_) { |
| 569 return _adbDevice.killAll().then((_) => true); |
| 570 }); |
| 571 } |
| 572 return new Future.value(true); |
| 573 } |
| 574 |
| 575 String toString() => "ContentShellOnAndroid"; |
| 576 } |
| 577 |
| 578 |
| 540 class Firefox extends Browser { | 579 class Firefox extends Browser { |
| 541 static const String enablePopUp = | 580 static const String enablePopUp = |
| 542 'user_pref("dom.disable_open_during_load", false);'; | 581 'user_pref("dom.disable_open_during_load", false);'; |
| 543 static const String disableDefaultCheck = | 582 static const String disableDefaultCheck = |
| 544 'user_pref("browser.shell.checkDefaultBrowser", false);'; | 583 'user_pref("browser.shell.checkDefaultBrowser", false);'; |
| 545 static const String disableScriptTimeLimit = | 584 static const String disableScriptTimeLimit = |
| 546 'user_pref("dom.max_script_run_time", 0);'; | 585 'user_pref("dom.max_script_run_time", 0);'; |
| 547 | 586 |
| 548 static String _binary = _getBinary(); | 587 static String _binary = _getBinary(); |
| 549 | 588 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 this.localIp, | 730 this.localIp, |
| 692 this.browserName, | 731 this.browserName, |
| 693 this.maxNumBrowsers, | 732 this.maxNumBrowsers, |
| 694 {bool this.checkedMode: false}); | 733 {bool this.checkedMode: false}); |
| 695 | 734 |
| 696 Future<bool> start() { | 735 Future<bool> start() { |
| 697 // If [browserName] doesn't support opening new windows, we use new iframes | 736 // If [browserName] doesn't support opening new windows, we use new iframes |
| 698 // instead. | 737 // instead. |
| 699 bool useIframe = | 738 bool useIframe = |
| 700 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); | 739 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); |
| 701 testingServer = new BrowserTestingServer(localIp, useIframe); | 740 testingServer = new BrowserTestingServer( |
| 741 globalConfiguration, localIp, useIframe); |
| 702 return testingServer.start().then((_) { | 742 return testingServer.start().then((_) { |
| 703 testingServer.testDoneCallBack = handleResults; | 743 testingServer.testDoneCallBack = handleResults; |
| 704 testingServer.testStartedCallBack = handleStarted; | 744 testingServer.testStartedCallBack = handleStarted; |
| 705 testingServer.nextTestCallBack = getNextTest; | 745 testingServer.nextTestCallBack = getNextTest; |
| 706 return getBrowsers().then((browsers) { | 746 return getBrowsers().then((browsers) { |
| 707 var futures = []; | 747 var futures = []; |
| 708 for (var browser in browsers) { | 748 for (var browser in browsers) { |
| 709 var url = testingServer.getDriverUrl(browser.id); | 749 var url = testingServer.getDriverUrl(browser.id); |
| 710 var future = browser.start(url).then((success) { | 750 var future = browser.start(url).then((success) { |
| 711 if (success) { | 751 if (success) { |
| 712 browserStatus[browser.id] = new BrowserTestingStatus(browser); | 752 browserStatus[browser.id] = new BrowserTestingStatus(browser); |
| 713 } | 753 } |
| 714 return success; | 754 return success; |
| 715 }); | 755 }); |
| 716 futures.add(future); | 756 futures.add(future); |
| 717 } | 757 } |
| 718 return Future.wait(futures).then((values) { | 758 return Future.wait(futures).then((values) { |
| 719 return !values.contains(false); | 759 return !values.contains(false); |
| 720 }); | 760 }); |
| 721 }); | 761 }); |
| 722 }); | 762 }); |
| 723 } | 763 } |
| 724 | 764 |
| 725 Future<List<Browser>> getBrowsers() { | 765 Future<List<Browser>> getBrowsers() { |
| 726 // TODO(kustermann): This is a hackisch way to accomplish it and should | 766 // TODO(kustermann): This is a hackisch way to accomplish it and should |
| 727 // be encapsulated | 767 // be encapsulated |
| 728 var browsersCompleter = new Completer(); | 768 var browsersCompleter = new Completer(); |
| 729 if (browserName == 'chromeOnAndroid') { | 769 var androidBrowserCreationMapping = { |
| 770 'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device), |
| 771 'ContentShellOnAndroid' : (AdbDevice device) => |
| 772 new ContentShellOnAndroid(device), |
| 773 }; |
| 774 if (androidBrowserCreationMapping.containsKey(browserName)) { |
| 730 AdbHelper.listDevices().then((deviceIds) { | 775 AdbHelper.listDevices().then((deviceIds) { |
| 731 if (deviceIds.length > 0) { | 776 if (deviceIds.length > 0) { |
| 732 var browsers = []; | 777 var browsers = []; |
| 733 for (int i = 0; i < deviceIds.length; i++) { | 778 for (int i = 0; i < deviceIds.length; i++) { |
| 734 var id = "BROWSER$i"; | 779 var id = "BROWSER$i"; |
| 735 var device = new AdbDevice(deviceIds[i]); | 780 var device = new AdbDevice(deviceIds[i]); |
| 736 adbDeviceMapping[id] = device; | 781 adbDeviceMapping[id] = device; |
| 737 var browser = new AndroidChrome(device); | 782 var browser = androidBrowserCreationMapping[browserName](device); |
| 738 browsers.add(browser); | 783 browsers.add(browser); |
| 739 // We store this in case we need to kill the browser. | 784 // We store this in case we need to kill the browser. |
| 740 browser.id = id; | 785 browser.id = id; |
| 741 } | 786 } |
| 742 browsersCompleter.complete(browsers); | 787 browsersCompleter.complete(browsers); |
| 743 } else { | 788 } else { |
| 744 throw new StateError("No android devices found."); | 789 throw new StateError("No android devices found."); |
| 745 } | 790 } |
| 746 }); | 791 }); |
| 747 } else { | 792 } else { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 didTimeout: true); | 885 didTimeout: true); |
| 841 status.currentTest.doneCallback(browserTestOutput); | 886 status.currentTest.doneCallback(browserTestOutput); |
| 842 status.currentTest = null; | 887 status.currentTest = null; |
| 843 | 888 |
| 844 // We don't want to start a new browser if we are terminating. | 889 // We don't want to start a new browser if we are terminating. |
| 845 if (underTermination) return; | 890 if (underTermination) return; |
| 846 var browser; | 891 var browser; |
| 847 var new_id = id; | 892 var new_id = id; |
| 848 if (browserName == 'chromeOnAndroid') { | 893 if (browserName == 'chromeOnAndroid') { |
| 849 browser = new AndroidChrome(adbDeviceMapping[id]); | 894 browser = new AndroidChrome(adbDeviceMapping[id]); |
| 895 } else if (browserName == 'ContentShellOnAndroid') { |
| 896 browser = new ContentShellOnAndroid(adbDeviceMapping[id]); |
| 850 } else { | 897 } else { |
| 851 browserStatus.remove(id); | 898 browserStatus.remove(id); |
| 852 browser = getInstance(); | 899 browser = getInstance(); |
| 853 new_id = "BROWSER$browserIdCount"; | 900 new_id = "BROWSER$browserIdCount"; |
| 854 browserIdCount++; | 901 browserIdCount++; |
| 855 browserStatus[new_id] = new BrowserTestingStatus(browser); | 902 browserStatus[new_id] = new BrowserTestingStatus(browser); |
| 856 } | 903 } |
| 857 browser.id = new_id; | 904 browser.id = new_id; |
| 858 browser.start(testingServer.getDriverUrl(new_id)).then((success) { | 905 browser.start(testingServer.getDriverUrl(new_id)).then((success) { |
| 859 // We may have started terminating in the mean time. | 906 // We may have started terminating in the mean time. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 | 1003 |
| 957 Browser getInstance() { | 1004 Browser getInstance() { |
| 958 var browser = | 1005 var browser = |
| 959 new Browser.byName(browserName, globalConfiguration, checkedMode); | 1006 new Browser.byName(browserName, globalConfiguration, checkedMode); |
| 960 browser.logger = logger; | 1007 browser.logger = logger; |
| 961 return browser; | 1008 return browser; |
| 962 } | 1009 } |
| 963 } | 1010 } |
| 964 | 1011 |
| 965 class BrowserTestingServer { | 1012 class BrowserTestingServer { |
| 1013 final Map globalConfiguration; |
| 966 /// Interface of the testing server: | 1014 /// Interface of the testing server: |
| 967 /// | 1015 /// |
| 968 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 1016 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| 969 /// and run tests ... | 1017 /// and run tests ... |
| 970 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" | 1018 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" |
| 971 /// where url is the test to run, and id is the id of the test. | 1019 /// where url is the test to run, and id is the id of the test. |
| 972 /// If there are currently no available tests the waitSignal is send | 1020 /// If there are currently no available tests the waitSignal is send |
| 973 /// back. If we are in the process of terminating the terminateSignal | 1021 /// back. If we are in the process of terminating the terminateSignal |
| 974 /// is send back and the browser will stop requesting new tasks. | 1022 /// is send back and the browser will stop requesting new tasks. |
| 975 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed | 1023 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed |
| (...skipping 11 matching lines...) Expand all Loading... |
| 987 var testCount = 0; | 1035 var testCount = 0; |
| 988 var httpServer; | 1036 var httpServer; |
| 989 var errorReportingServer; | 1037 var errorReportingServer; |
| 990 bool underTermination = false; | 1038 bool underTermination = false; |
| 991 bool useIframe = false; | 1039 bool useIframe = false; |
| 992 | 1040 |
| 993 Function testDoneCallBack; | 1041 Function testDoneCallBack; |
| 994 Function testStartedCallBack; | 1042 Function testStartedCallBack; |
| 995 Function nextTestCallBack; | 1043 Function nextTestCallBack; |
| 996 | 1044 |
| 997 BrowserTestingServer(this.localIp, this.useIframe); | 1045 BrowserTestingServer(this.globalConfiguration, this.localIp, this.useIframe); |
| 998 | 1046 |
| 999 Future start() { | 1047 Future start() { |
| 1000 return HttpServer.bind(localIp, 0).then((createdServer) { | 1048 int port = globalConfiguration['test_driver_port']; |
| 1049 return HttpServer.bind(localIp, port).then((createdServer) { |
| 1001 httpServer = createdServer; | 1050 httpServer = createdServer; |
| 1002 void handler(HttpRequest request) { | 1051 void handler(HttpRequest request) { |
| 1003 // Don't allow caching of resources from the browser controller, i.e., | 1052 // Don't allow caching of resources from the browser controller, i.e., |
| 1004 // we don't want the browser to cache the result of getNextTest. | 1053 // we don't want the browser to cache the result of getNextTest. |
| 1005 request.response.headers.set("Cache-Control", | 1054 request.response.headers.set("Cache-Control", |
| 1006 "no-cache, no-store, must-revalidate"); | 1055 "no-cache, no-store, must-revalidate"); |
| 1007 if (request.uri.path.startsWith(reportPath)) { | 1056 if (request.uri.path.startsWith(reportPath)) { |
| 1008 var browserId = request.uri.path.substring(reportPath.length + 1); | 1057 var browserId = request.uri.path.substring(reportPath.length + 1); |
| 1009 var testId = | 1058 var testId = |
| 1010 int.parse(request.uri.queryParameters["id"].split("=")[1]); | 1059 int.parse(request.uri.queryParameters["id"].split("=")[1]); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1041 }); | 1090 }); |
| 1042 } | 1091 } |
| 1043 void errorHandler(e) { | 1092 void errorHandler(e) { |
| 1044 if (!underTermination) print("Error occured in httpserver: $e"); | 1093 if (!underTermination) print("Error occured in httpserver: $e"); |
| 1045 }; | 1094 }; |
| 1046 | 1095 |
| 1047 httpServer.listen(handler, onError: errorHandler); | 1096 httpServer.listen(handler, onError: errorHandler); |
| 1048 | 1097 |
| 1049 // Set up the error reporting server that enables us to send back | 1098 // Set up the error reporting server that enables us to send back |
| 1050 // errors from the browser. | 1099 // errors from the browser. |
| 1051 return HttpServer.bind(localIp, 0).then((createdReportServer) { | 1100 port = globalConfiguration['test_driver_error_port']; |
| 1101 return HttpServer.bind(localIp, port).then((createdReportServer) { |
| 1052 errorReportingServer = createdReportServer; | 1102 errorReportingServer = createdReportServer; |
| 1053 void errorReportingHandler(HttpRequest request) { | 1103 void errorReportingHandler(HttpRequest request) { |
| 1054 StringBuffer buffer = new StringBuffer(); | 1104 StringBuffer buffer = new StringBuffer(); |
| 1055 request.transform(UTF8.decoder).listen((data) { | 1105 request.transform(UTF8.decoder).listen((data) { |
| 1056 buffer.write(data); | 1106 buffer.write(data); |
| 1057 }, onDone: () { | 1107 }, onDone: () { |
| 1058 String back = buffer.toString(); | 1108 String back = buffer.toString(); |
| 1059 request.response.headers.set("Access-Control-Allow-Origin", "*"); | 1109 request.response.headers.set("Access-Control-Allow-Origin", "*"); |
| 1060 request.response.done.catchError((error) { | 1110 request.response.done.catchError((error) { |
| 1061 DebugLogger.error("Error getting error from browser" | 1111 DebugLogger.error("Error getting error from browser" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 Dart test driver, number of tests: <div id="number"></div><br> | 1325 Dart test driver, number of tests: <div id="number"></div><br> |
| 1276 Currently executing: <div id="currently_executing"></div><br> | 1326 Currently executing: <div id="currently_executing"></div><br> |
| 1277 Unhandled error: <div id="unhandled_error"></div> | 1327 Unhandled error: <div id="unhandled_error"></div> |
| 1278 <iframe id="embedded_iframe"></iframe> | 1328 <iframe id="embedded_iframe"></iframe> |
| 1279 </body> | 1329 </body> |
| 1280 </html> | 1330 </html> |
| 1281 """; | 1331 """; |
| 1282 return driverContent; | 1332 return driverContent; |
| 1283 } | 1333 } |
| 1284 } | 1334 } |
| OLD | NEW |