Chromium Code Reviews| 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 |
| 11 import 'android.dart'; | 11 import 'android.dart'; |
| 12 import 'http_server.dart'; | |
| 12 import 'utils.dart'; | 13 import 'utils.dart'; |
| 13 | 14 |
| 14 class BrowserOutput { | 15 class BrowserOutput { |
| 15 final StringBuffer stdout = new StringBuffer(); | 16 final StringBuffer stdout = new StringBuffer(); |
| 16 final StringBuffer stderr = new StringBuffer(); | 17 final StringBuffer stderr = new StringBuffer(); |
| 17 final StringBuffer eventLog = new StringBuffer(); | 18 final StringBuffer eventLog = new StringBuffer(); |
| 18 } | 19 } |
| 19 | 20 |
| 20 /** Class describing the interface for communicating with browsers. */ | 21 /** Class describing the interface for communicating with browsers. */ |
| 21 abstract class Browser { | 22 abstract class Browser { |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 * Encapsulates all the functionality for running tests in browsers. | 804 * Encapsulates all the functionality for running tests in browsers. |
| 804 * The interface is rather simple. After starting, the runner tests | 805 * The interface is rather simple. After starting, the runner tests |
| 805 * are simply added to the queue and a the supplied callbacks are called | 806 * are simply added to the queue and a the supplied callbacks are called |
| 806 * whenever a test completes. | 807 * whenever a test completes. |
| 807 */ | 808 */ |
| 808 class BrowserTestRunner { | 809 class BrowserTestRunner { |
| 809 static const int MAX_NEXT_TEST_TIMEOUTS = 10; | 810 static const int MAX_NEXT_TEST_TIMEOUTS = 10; |
| 810 static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 60); | 811 static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 60); |
| 811 static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60); | 812 static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60); |
| 812 | 813 |
| 813 final Map globalConfiguration; | 814 final Map configuration; |
|
ricow1
2014/09/05 06:45:11
Please file a bug to remove this
| |
| 814 final bool checkedMode; // needed for dartium | |
| 815 | 815 |
| 816 String localIp; | 816 final String localIp; |
| 817 String browserName; | 817 final String browserName; |
| 818 int maxNumBrowsers; | 818 final int maxNumBrowsers; |
| 819 bool checkedMode; | |
| 819 // Used to send back logs from the browser (start, stop etc) | 820 // Used to send back logs from the browser (start, stop etc) |
| 820 Function logger; | 821 Function logger; |
| 821 int browserIdCount = 0; | 822 int browserIdCount = 0; |
| 822 | 823 |
| 823 bool underTermination = false; | 824 bool underTermination = false; |
| 824 int numBrowserGetTestTimeouts = 0; | 825 int numBrowserGetTestTimeouts = 0; |
| 825 | 826 |
| 826 List<BrowserTest> testQueue = new List<BrowserTest>(); | 827 List<BrowserTest> testQueue = new List<BrowserTest>(); |
| 827 Map<String, BrowserTestingStatus> browserStatus = | 828 Map<String, BrowserTestingStatus> browserStatus = |
| 828 new Map<String, BrowserTestingStatus>(); | 829 new Map<String, BrowserTestingStatus>(); |
| 829 | 830 |
| 830 var adbDeviceMapping = new Map<String, AdbDevice>(); | 831 var adbDeviceMapping = new Map<String, AdbDevice>(); |
| 831 // This cache is used to guarantee that we never see double reporting. | 832 // This cache is used to guarantee that we never see double reporting. |
| 832 // If we do we need to provide developers with this information. | 833 // If we do we need to provide developers with this information. |
| 833 // We don't add urls to the cache until we have run it. | 834 // We don't add urls to the cache until we have run it. |
| 834 Map<int, String> testCache = new Map<int, String>(); | 835 Map<int, String> testCache = new Map<int, String>(); |
| 835 Map<int, String> doubleReportingOutputs = new Map<int, String>(); | 836 Map<int, String> doubleReportingOutputs = new Map<int, String>(); |
| 836 | 837 |
| 837 BrowserTestingServer testingServer; | 838 BrowserTestingServer testingServer; |
| 838 | 839 |
| 839 /** | 840 /** |
| 840 * The TestRunner takes the testingServer in as a constructor parameter in | 841 * The TestRunner takes the testingServer in as a constructor parameter in |
| 841 * case we wish to have a testing server with different behavior (such as the | 842 * case we wish to have a testing server with different behavior (such as the |
| 842 * case for performance testing. | 843 * case for performance testing. |
| 843 */ | 844 */ |
| 844 BrowserTestRunner(this.globalConfiguration, | 845 BrowserTestRunner(this.configuration, |
| 845 this.localIp, | 846 this.localIp, |
| 846 this.browserName, | 847 this.browserName, |
| 847 this.maxNumBrowsers, | 848 this.maxNumBrowsers, |
| 848 {bool this.checkedMode: false, | 849 {BrowserTestingServer this.testingServer}) { |
| 849 BrowserTestingServer this.testingServer}); | 850 checkedMode = configuration['checked']; |
|
ricow1
2014/09/05 06:45:11
indentation
| |
| 851 } | |
| 850 | 852 |
| 851 Future<bool> start() { | 853 Future<bool> start() { |
| 852 // If [browserName] doesn't support opening new windows, we use new iframes | 854 // If [browserName] doesn't support opening new windows, we use new iframes |
| 853 // instead. | 855 // instead. |
| 854 bool useIframe = | 856 bool useIframe = |
| 855 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); | 857 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); |
| 856 if (testingServer == null) { | 858 if (testingServer == null) { |
| 857 testingServer = new BrowserTestingServer( | 859 testingServer = new BrowserTestingServer( |
| 858 globalConfiguration, localIp, useIframe); | 860 configuration, localIp, useIframe); |
| 859 } | 861 } |
| 860 return testingServer.start().then((_) { | 862 return testingServer.start().then((_) { |
| 861 testingServer.testDoneCallBack = handleResults; | 863 testingServer.testDoneCallBack = handleResults; |
| 862 testingServer.testStatusUpdateCallBack = handleStatusUpdate; | 864 testingServer.testStatusUpdateCallBack = handleStatusUpdate; |
| 863 testingServer.testStartedCallBack = handleStarted; | 865 testingServer.testStartedCallBack = handleStarted; |
| 864 testingServer.nextTestCallBack = getNextTest; | 866 testingServer.nextTestCallBack = getNextTest; |
| 865 return getBrowsers().then((browsers) { | 867 return getBrowsers().then((browsers) { |
| 866 var futures = []; | 868 var futures = []; |
| 867 for (var browser in browsers) { | 869 for (var browser in browsers) { |
| 868 var url = testingServer.getDriverUrl(browser.id); | 870 var url = testingServer.getDriverUrl(browser.id); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 887 Future<List<Browser>> getBrowsers() { | 889 Future<List<Browser>> getBrowsers() { |
| 888 // TODO(kustermann): This is a hackisch way to accomplish it and should | 890 // TODO(kustermann): This is a hackisch way to accomplish it and should |
| 889 // be encapsulated | 891 // be encapsulated |
| 890 var browsersCompleter = new Completer(); | 892 var browsersCompleter = new Completer(); |
| 891 var androidBrowserCreationMapping = { | 893 var androidBrowserCreationMapping = { |
| 892 'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device), | 894 'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device), |
| 893 'ContentShellOnAndroid' : (AdbDevice device) => new AndroidBrowser( | 895 'ContentShellOnAndroid' : (AdbDevice device) => new AndroidBrowser( |
| 894 device, | 896 device, |
| 895 contentShellOnAndroidConfig, | 897 contentShellOnAndroidConfig, |
| 896 checkedMode, | 898 checkedMode, |
| 897 globalConfiguration['drt']), | 899 configuration['drt']), |
| 898 'DartiumOnAndroid' : (AdbDevice device) => new AndroidBrowser( | 900 'DartiumOnAndroid' : (AdbDevice device) => new AndroidBrowser( |
| 899 device, | 901 device, |
| 900 dartiumOnAndroidConfig, | 902 dartiumOnAndroidConfig, |
| 901 checkedMode, | 903 checkedMode, |
| 902 globalConfiguration['dartium']), | 904 configuration['dartium']), |
| 903 }; | 905 }; |
| 904 if (androidBrowserCreationMapping.containsKey(browserName)) { | 906 if (androidBrowserCreationMapping.containsKey(browserName)) { |
| 905 AdbHelper.listDevices().then((deviceIds) { | 907 AdbHelper.listDevices().then((deviceIds) { |
| 906 if (deviceIds.length > 0) { | 908 if (deviceIds.length > 0) { |
| 907 var browsers = []; | 909 var browsers = []; |
| 908 for (int i = 0; i < deviceIds.length; i++) { | 910 for (int i = 0; i < deviceIds.length; i++) { |
| 909 var id = "BROWSER$i"; | 911 var id = "BROWSER$i"; |
| 910 var device = new AdbDevice(deviceIds[i]); | 912 var device = new AdbDevice(deviceIds[i]); |
| 911 adbDeviceMapping[id] = device; | 913 adbDeviceMapping[id] = device; |
| 912 var browser = androidBrowserCreationMapping[browserName](device); | 914 var browser = androidBrowserCreationMapping[browserName](device); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1046 | 1048 |
| 1047 void restartBrowser(String id) { | 1049 void restartBrowser(String id) { |
| 1048 var browser; | 1050 var browser; |
| 1049 var new_id = id; | 1051 var new_id = id; |
| 1050 if (browserName == 'chromeOnAndroid') { | 1052 if (browserName == 'chromeOnAndroid') { |
| 1051 browser = new AndroidChrome(adbDeviceMapping[id]); | 1053 browser = new AndroidChrome(adbDeviceMapping[id]); |
| 1052 } else if (browserName == 'ContentShellOnAndroid') { | 1054 } else if (browserName == 'ContentShellOnAndroid') { |
| 1053 browser = new AndroidBrowser(adbDeviceMapping[id], | 1055 browser = new AndroidBrowser(adbDeviceMapping[id], |
| 1054 contentShellOnAndroidConfig, | 1056 contentShellOnAndroidConfig, |
| 1055 checkedMode, | 1057 checkedMode, |
| 1056 globalConfiguration['drt']); | 1058 configuration['drt']); |
| 1057 } else if (browserName == 'DartiumOnAndroid') { | 1059 } else if (browserName == 'DartiumOnAndroid') { |
| 1058 browser = new AndroidBrowser(adbDeviceMapping[id], | 1060 browser = new AndroidBrowser(adbDeviceMapping[id], |
| 1059 dartiumOnAndroidConfig, | 1061 dartiumOnAndroidConfig, |
| 1060 checkedMode, | 1062 checkedMode, |
| 1061 globalConfiguration['dartium']); | 1063 configuration['dartium']); |
| 1062 } else { | 1064 } else { |
| 1063 browserStatus.remove(id); | 1065 browserStatus.remove(id); |
| 1064 browser = getInstance(); | 1066 browser = getInstance(); |
| 1065 new_id = "BROWSER$browserIdCount"; | 1067 new_id = "BROWSER$browserIdCount"; |
| 1066 browserIdCount++; | 1068 browserIdCount++; |
| 1067 } | 1069 } |
| 1068 browser.id = new_id; | 1070 browser.id = new_id; |
| 1069 var status = new BrowserTestingStatus(browser); | 1071 var status = new BrowserTestingStatus(browser); |
| 1070 browserStatus[new_id] = status; | 1072 browserStatus[new_id] = status; |
| 1071 status.nextTestTimeout = createNextTestTimer(status); | 1073 status.nextTestTimeout = createNextTestTimer(status); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1204 underTermination = true; | 1206 underTermination = true; |
| 1205 testingServer.underTermination = true; | 1207 testingServer.underTermination = true; |
| 1206 for (BrowserTestingStatus status in browserStatus.values) { | 1208 for (BrowserTestingStatus status in browserStatus.values) { |
| 1207 futures.add(status.browser.close()); | 1209 futures.add(status.browser.close()); |
| 1208 if (status.nextTestTimeout != null) { | 1210 if (status.nextTestTimeout != null) { |
| 1209 status.nextTestTimeout.cancel(); | 1211 status.nextTestTimeout.cancel(); |
| 1210 status.nextTestTimeout = null; | 1212 status.nextTestTimeout = null; |
| 1211 } | 1213 } |
| 1212 } | 1214 } |
| 1213 return Future.wait(futures).then((values) { | 1215 return Future.wait(futures).then((values) { |
| 1214 testingServer.httpServer.close(); | |
| 1215 testingServer.errorReportingServer.close(); | 1216 testingServer.errorReportingServer.close(); |
| 1216 printDoubleReportingTests(); | 1217 printDoubleReportingTests(); |
| 1217 return !values.contains(false); | 1218 return !values.contains(false); |
| 1218 }); | 1219 }); |
| 1219 } | 1220 } |
| 1220 | 1221 |
| 1221 Browser getInstance() { | 1222 Browser getInstance() { |
| 1222 if (browserName == 'ff') browserName = 'firefox'; | 1223 if (browserName == 'ff') browserName = 'firefox'; |
| 1223 var path = Locations.getBrowserLocation(browserName, globalConfiguration); | 1224 var path = Locations.getBrowserLocation(browserName, configuration); |
| 1224 var browser = new Browser.byName(browserName, path, checkedMode); | 1225 var browser = new Browser.byName(browserName, path, checkedMode); |
| 1225 browser.logger = logger; | 1226 browser.logger = logger; |
| 1226 return browser; | 1227 return browser; |
| 1227 } | 1228 } |
| 1228 } | 1229 } |
| 1229 | 1230 |
| 1230 class BrowserTestingServer { | 1231 class BrowserTestingServer { |
| 1231 final Map globalConfiguration; | 1232 final Map configuration; |
| 1232 /// Interface of the testing server: | 1233 /// Interface of the testing server: |
| 1233 /// | 1234 /// |
| 1234 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 1235 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| 1235 /// and run tests ... | 1236 /// and run tests ... |
| 1236 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" | 1237 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" |
| 1237 /// where url is the test to run, and id is the id of the test. | 1238 /// where url is the test to run, and id is the id of the test. |
| 1238 /// If there are currently no available tests the waitSignal is send | 1239 /// If there are currently no available tests the waitSignal is send |
| 1239 /// back. If we are in the process of terminating the terminateSignal | 1240 /// back. If we are in the process of terminating the terminateSignal |
| 1240 /// is send back and the browser will stop requesting new tasks. | 1241 /// is send back and the browser will stop requesting new tasks. |
| 1241 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed | 1242 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed |
| 1242 /// test | 1243 /// test |
| 1243 | 1244 |
| 1244 final String localIp; | 1245 final String localIp; |
| 1245 | 1246 |
| 1246 static const String driverPath = "/driver"; | 1247 static const String driverPath = "/driver"; |
| 1247 static const String nextTestPath = "/next_test"; | 1248 static const String nextTestPath = "/next_test"; |
| 1248 static const String reportPath = "/report"; | 1249 static const String reportPath = "/report"; |
| 1249 static const String statusUpdatePath = "/status_update"; | 1250 static const String statusUpdatePath = "/status_update"; |
| 1250 static const String startedPath = "/started"; | 1251 static const String startedPath = "/started"; |
| 1251 static const String waitSignal = "WAIT"; | 1252 static const String waitSignal = "WAIT"; |
| 1252 static const String terminateSignal = "TERMINATE"; | 1253 static const String terminateSignal = "TERMINATE"; |
| 1253 | 1254 |
| 1254 var testCount = 0; | 1255 var testCount = 0; |
| 1255 var httpServer; | |
| 1256 var errorReportingServer; | 1256 var errorReportingServer; |
| 1257 bool underTermination = false; | 1257 bool underTermination = false; |
| 1258 bool useIframe = false; | 1258 bool useIframe = false; |
| 1259 | 1259 |
| 1260 Function testDoneCallBack; | 1260 Function testDoneCallBack; |
| 1261 Function testStatusUpdateCallBack; | 1261 Function testStatusUpdateCallBack; |
| 1262 Function testStartedCallBack; | 1262 Function testStartedCallBack; |
| 1263 Function nextTestCallBack; | 1263 Function nextTestCallBack; |
| 1264 | 1264 |
| 1265 BrowserTestingServer(this.globalConfiguration, this.localIp, this.useIframe); | 1265 BrowserTestingServer(this.configuration, this.localIp, this.useIframe); |
| 1266 | 1266 |
| 1267 Future start() { | 1267 Future start() { |
| 1268 var test_driver_port = globalConfiguration['test_driver_port']; | 1268 var test_driver_error_port = configuration['test_driver_error_port']; |
| 1269 var test_driver_error_port = globalConfiguration['test_driver_error_port']; | 1269 return HttpServer.bind(localIp, test_driver_error_port) |
| 1270 return HttpServer.bind(localIp, test_driver_port) | 1270 .then(setupErrorServer) |
| 1271 .then(setupDriverServer) | 1271 .then(setupDispatchingServer); |
| 1272 .then((_) => HttpServer.bind(localIp, test_driver_error_port)) | |
| 1273 .then(setupErrorServer); | |
| 1274 } | |
| 1275 | |
| 1276 void setupDriverServer(HttpServer server) { | |
| 1277 httpServer = server; | |
| 1278 void handler(HttpRequest request) { | |
| 1279 // Don't allow caching of resources from the browser controller, i.e., | |
| 1280 // we don't want the browser to cache the result of getNextTest. | |
| 1281 request.response.headers.set("Cache-Control", | |
| 1282 "no-cache, no-store, must-revalidate"); | |
| 1283 bool isReport = request.uri.path.startsWith(reportPath); | |
| 1284 bool isStatusUpdate = request.uri.path.startsWith(statusUpdatePath); | |
| 1285 if (isReport || isStatusUpdate) { | |
| 1286 var browserId; | |
| 1287 if (isStatusUpdate) { | |
| 1288 browserId = request.uri.path.substring(statusUpdatePath.length + 1); | |
| 1289 } else { | |
| 1290 browserId = request.uri.path.substring(reportPath.length + 1); | |
| 1291 } | |
| 1292 var testId = | |
| 1293 int.parse(request.uri.queryParameters["id"].split("=")[1]); | |
| 1294 handleReport( | |
| 1295 request, browserId, testId, isStatusUpdate: isStatusUpdate); | |
| 1296 // handleReport will asynchroniously fetch the data and will handle | |
| 1297 // the closing of the streams. | |
| 1298 return; | |
| 1299 } | |
| 1300 if (request.uri.path.startsWith(startedPath)) { | |
| 1301 var browserId = request.uri.path.substring(startedPath.length + 1); | |
| 1302 var testId = | |
| 1303 int.parse(request.uri.queryParameters["id"].split("=")[1]); | |
| 1304 handleStarted(request, browserId, testId); | |
| 1305 return; | |
| 1306 } | |
| 1307 var textResponse = ""; | |
| 1308 if (request.uri.path.startsWith(driverPath)) { | |
| 1309 var browserId = request.uri.path.substring(driverPath.length + 1); | |
| 1310 textResponse = getDriverPage(browserId); | |
| 1311 request.response.headers.set('Content-Type', 'text/html'); | |
| 1312 } else if (request.uri.path.startsWith(nextTestPath)) { | |
| 1313 var browserId = request.uri.path.substring(nextTestPath.length + 1); | |
| 1314 textResponse = getNextTest(browserId); | |
| 1315 request.response.headers.set('Content-Type', 'text/plain'); | |
| 1316 } else { | |
| 1317 // /favicon.ico requests | |
| 1318 } | |
| 1319 request.response.write(textResponse); | |
| 1320 request.listen((_) {}, onDone: request.response.close); | |
| 1321 request.response.done.catchError((error) { | |
| 1322 if (!underTermination) { | |
| 1323 print("URI ${request.uri}"); | |
| 1324 print("Textresponse $textResponse"); | |
| 1325 throw "Error returning content to browser: $error"; | |
| 1326 } | |
| 1327 }); | |
| 1328 } | |
| 1329 void errorHandler(e) { | |
| 1330 if (!underTermination) print("Error occured in httpserver: $e"); | |
| 1331 } | |
| 1332 httpServer.listen(handler, onError: errorHandler); | |
| 1333 } | 1272 } |
| 1334 | 1273 |
| 1335 void setupErrorServer(HttpServer server) { | 1274 void setupErrorServer(HttpServer server) { |
| 1336 errorReportingServer = server; | 1275 errorReportingServer = server; |
| 1337 void errorReportingHandler(HttpRequest request) { | 1276 void errorReportingHandler(HttpRequest request) { |
| 1338 StringBuffer buffer = new StringBuffer(); | 1277 StringBuffer buffer = new StringBuffer(); |
| 1339 request.transform(UTF8.decoder).listen((data) { | 1278 request.transform(UTF8.decoder).listen((data) { |
| 1340 buffer.write(data); | 1279 buffer.write(data); |
| 1341 }, onDone: () { | 1280 }, onDone: () { |
| 1342 String back = buffer.toString(); | 1281 String back = buffer.toString(); |
| 1343 request.response.headers.set("Access-Control-Allow-Origin", "*"); | 1282 request.response.headers.set("Access-Control-Allow-Origin", "*"); |
| 1344 request.response.done.catchError((error) { | 1283 request.response.done.catchError((error) { |
| 1345 DebugLogger.error("Error getting error from browser" | 1284 DebugLogger.error("Error getting error from browser" |
| 1346 "on uri ${request.uri.path}: $error"); | 1285 "on uri ${request.uri.path}: $error"); |
| 1347 }); | 1286 }); |
| 1348 request.response.close(); | 1287 request.response.close(); |
| 1349 DebugLogger.error("Error from browser on : " | 1288 DebugLogger.error("Error from browser on : " |
| 1350 "${request.uri.path}, data: $back"); | 1289 "${request.uri.path}, data: $back"); |
| 1351 }, onError: (error) { print(error); }); | 1290 }, onError: (error) { print(error); }); |
| 1352 } | 1291 } |
| 1353 void errorHandler(e) { | 1292 void errorHandler(e) { |
| 1354 if (!underTermination) print("Error occured in httpserver: $e"); | 1293 if (!underTermination) print("Error occured in httpserver: $e"); |
| 1355 } | 1294 } |
| 1356 errorReportingServer.listen(errorReportingHandler, onError: errorHandler); | 1295 errorReportingServer.listen(errorReportingHandler, onError: errorHandler); |
| 1357 } | 1296 } |
| 1358 | 1297 |
| 1298 void setupDispatchingServer(_) { | |
| 1299 DispatchingServer server = configuration['_servers_'].server; | |
|
ricow1
2014/09/05 06:45:11
I think that we should allow for this to not be pa
| |
| 1300 void noCache(request) { | |
| 1301 request.response.headers.set("Cache-Control", | |
| 1302 "no-cache, no-store, must-revalidate"); | |
| 1303 } | |
| 1304 int testId(request) => | |
| 1305 int.parse(request.uri.queryParameters["id"].split("=")[1]); | |
| 1306 String browserId(request, prefix) => | |
| 1307 request.uri.path.substring(prefix.length + 1); | |
| 1308 | |
| 1309 | |
| 1310 server.addHandler(reportPath, (HttpRequest request) { | |
| 1311 noCache(request); | |
| 1312 handleReport(request, browserId(request, reportPath), | |
| 1313 testId(request), isStatusUpdate: false); | |
| 1314 }); | |
| 1315 server.addHandler(statusUpdatePath, (HttpRequest request) { | |
| 1316 noCache(request); | |
| 1317 handleReport(request, browserId(request, statusUpdatePath), | |
| 1318 testId(request), isStatusUpdate: true); | |
| 1319 }); | |
| 1320 server.addHandler(startedPath, (HttpRequest request) { | |
| 1321 noCache(request); | |
| 1322 handleStarted(request, browserId(request, startedPath), | |
| 1323 testId(request)); | |
| 1324 }); | |
| 1325 | |
| 1326 makeSendPageHandler(String prefix) => (HttpRequest request) { | |
| 1327 noCache(request); | |
| 1328 var textResponse = ""; | |
| 1329 if (prefix == driverPath) { | |
| 1330 textResponse = getDriverPage(browserId(request, prefix)); | |
| 1331 request.response.headers.set('Content-Type', 'text/html'); | |
| 1332 } | |
| 1333 if (prefix == nextTestPath) { | |
| 1334 textResponse = getNextTest(browserId(request, prefix)); | |
| 1335 request.response.headers.set('Content-Type', 'text/plain'); | |
| 1336 } | |
| 1337 request.response.write(textResponse); | |
| 1338 request.listen((_) {}, onDone: request.response.close); | |
| 1339 request.response.done.catchError((error) { | |
| 1340 if (!underTermination) { | |
| 1341 print("URI ${request.uri}"); | |
| 1342 print("Textresponse $textResponse"); | |
| 1343 throw "Error returning content to browser: $error"; | |
| 1344 } | |
| 1345 }); | |
| 1346 }; | |
| 1347 server.addHandler(driverPath, makeSendPageHandler(driverPath)); | |
| 1348 server.addHandler(nextTestPath, makeSendPageHandler(nextTestPath)); | |
| 1349 } | |
| 1350 | |
| 1359 void handleReport(HttpRequest request, String browserId, var testId, | 1351 void handleReport(HttpRequest request, String browserId, var testId, |
| 1360 {bool isStatusUpdate}) { | 1352 {bool isStatusUpdate}) { |
| 1361 StringBuffer buffer = new StringBuffer(); | 1353 StringBuffer buffer = new StringBuffer(); |
| 1362 request.transform(UTF8.decoder).listen((data) { | 1354 request.transform(UTF8.decoder).listen((data) { |
| 1363 buffer.write(data); | 1355 buffer.write(data); |
| 1364 }, onDone: () { | 1356 }, onDone: () { |
| 1365 String back = buffer.toString(); | 1357 String back = buffer.toString(); |
| 1366 request.response.close(); | 1358 request.response.close(); |
| 1367 if (isStatusUpdate) { | 1359 if (isStatusUpdate) { |
| 1368 testStatusUpdateCallBack(browserId, back, testId); | 1360 testStatusUpdateCallBack(browserId, back, testId); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1395 return terminateSignal; | 1387 return terminateSignal; |
| 1396 } else if (nextTest == null) { | 1388 } else if (nextTest == null) { |
| 1397 // We don't currently have any tests ready for consumption, wait. | 1389 // We don't currently have any tests ready for consumption, wait. |
| 1398 return waitSignal; | 1390 return waitSignal; |
| 1399 } else { | 1391 } else { |
| 1400 return "${nextTest.url}#id=${nextTest.id}"; | 1392 return "${nextTest.url}#id=${nextTest.id}"; |
| 1401 } | 1393 } |
| 1402 } | 1394 } |
| 1403 | 1395 |
| 1404 String getDriverUrl(String browserId) { | 1396 String getDriverUrl(String browserId) { |
| 1405 if (httpServer == null) { | 1397 if (errorReportingServer == null) { |
| 1406 print("Bad browser testing server, you are not started yet. Can't " | 1398 print("Bad browser testing server, you are not started yet. Can't " |
| 1407 "produce driver url"); | 1399 "produce driver url"); |
| 1408 exit(1); | 1400 exit(1); |
| 1409 // This should never happen - exit immediately; | 1401 // This should never happen - exit immediately; |
| 1410 } | 1402 } |
| 1411 return "http://$localIp:${httpServer.port}/driver/$browserId"; | 1403 var port = configuration['_servers_'].port; |
| 1404 return "http://$localIp:$port/driver/$browserId"; | |
| 1412 } | 1405 } |
| 1413 | 1406 |
| 1414 | 1407 |
| 1415 String getDriverPage(String browserId) { | 1408 String getDriverPage(String browserId) { |
| 1416 var errorReportingUrl = | 1409 var errorReportingUrl = |
| 1417 "http://$localIp:${errorReportingServer.port}/$browserId"; | 1410 "http://$localIp:${errorReportingServer.port}/$browserId"; |
| 1418 String driverContent = """ | 1411 String driverContent = """ |
| 1419 <!DOCTYPE html><html> | 1412 <!DOCTYPE html><html> |
| 1420 <head> | 1413 <head> |
| 1421 <title>Driving page</title> | 1414 <title>Driving page</title> |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1604 Dart test driver, number of tests: <div id="number"></div><br> | 1597 Dart test driver, number of tests: <div id="number"></div><br> |
| 1605 Currently executing: <div id="currently_executing"></div><br> | 1598 Currently executing: <div id="currently_executing"></div><br> |
| 1606 Unhandled error: <div id="unhandled_error"></div> | 1599 Unhandled error: <div id="unhandled_error"></div> |
| 1607 <iframe id="embedded_iframe"></iframe> | 1600 <iframe id="embedded_iframe"></iframe> |
| 1608 </body> | 1601 </body> |
| 1609 </html> | 1602 </html> |
| 1610 """; | 1603 """; |
| 1611 return driverContent; | 1604 return driverContent; |
| 1612 } | 1605 } |
| 1613 } | 1606 } |
| OLD | NEW |