| 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; | |
| 5 | 4 |
| 6 import "dart:async"; | 5 import 'dart:async'; |
| 7 import "dart:convert" show UTF8, JSON; | 6 import 'dart:convert'; |
| 8 import "dart:core"; | 7 import 'dart:core'; |
| 9 import "dart:io"; | 8 import 'dart:io'; |
| 10 import "dart:math" show min; | 9 import 'dart:math'; |
| 11 | 10 |
| 12 import 'android.dart'; | 11 import 'android.dart'; |
| 13 import 'http_server.dart'; | 12 import 'configuration.dart'; |
| 14 import 'path.dart'; | 13 import 'path.dart'; |
| 14 import 'reset_safari.dart'; |
| 15 import 'utils.dart'; | 15 import 'utils.dart'; |
| 16 | 16 |
| 17 import 'reset_safari.dart' show killAndResetSafari; | |
| 18 | |
| 19 typedef void BrowserDoneCallback(BrowserTestOutput output); | 17 typedef void BrowserDoneCallback(BrowserTestOutput output); |
| 20 typedef void TestChangedCallback(String browserId, String output, int testId); | 18 typedef void TestChangedCallback(String browserId, String output, int testId); |
| 21 typedef BrowserTest NextTestCallback(String browserId); | 19 typedef BrowserTest NextTestCallback(String browserId); |
| 22 | 20 |
| 23 class BrowserOutput { | 21 class BrowserOutput { |
| 24 final StringBuffer stdout = new StringBuffer(); | 22 final StringBuffer stdout = new StringBuffer(); |
| 25 final StringBuffer stderr = new StringBuffer(); | 23 final StringBuffer stderr = new StringBuffer(); |
| 26 final StringBuffer eventLog = new StringBuffer(); | 24 final StringBuffer eventLog = new StringBuffer(); |
| 27 } | 25 } |
| 28 | 26 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 | 64 |
| 67 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ | 65 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ |
| 68 bool debugPrint = false; | 66 bool debugPrint = false; |
| 69 | 67 |
| 70 // This future returns when the process exits. It is also the return value | 68 // This future returns when the process exits. It is also the return value |
| 71 // of close() | 69 // of close() |
| 72 Future done; | 70 Future done; |
| 73 | 71 |
| 74 Browser(); | 72 Browser(); |
| 75 | 73 |
| 76 factory Browser.byName(String name, String executablePath, | 74 factory Browser.byRuntime(Runtime runtime, String executablePath, |
| 77 [bool checkedMode = false]) { | 75 [bool checkedMode = false]) { |
| 78 Browser browser; | 76 Browser browser; |
| 79 if (name == 'firefox') { | 77 switch (runtime) { |
| 80 browser = new Firefox(); | 78 case Runtime.firefox: |
| 81 } else if (name == 'chrome') { | 79 browser = new Firefox(); |
| 82 browser = new Chrome(); | 80 break; |
| 83 } else if (name == 'dartium') { | 81 case Runtime.chrome: |
| 84 browser = new Dartium(checkedMode); | 82 browser = new Chrome(); |
| 85 } else if (name == 'safari') { | 83 break; |
| 86 browser = new Safari(); | 84 case Runtime.dartium: |
| 87 } else if (name == 'safarimobilesim') { | 85 browser = new Dartium(checkedMode); |
| 88 browser = new SafariMobileSimulator(); | 86 break; |
| 89 } else if (name.startsWith('ie')) { | 87 case Runtime.safari: |
| 90 browser = new IE(); | 88 browser = new Safari(); |
| 91 } else { | 89 break; |
| 92 throw "Non supported browser"; | 90 case Runtime.safariMobileSim: |
| 91 browser = new SafariMobileSimulator(); |
| 92 break; |
| 93 case Runtime.ie9: |
| 94 case Runtime.ie10: |
| 95 case Runtime.ie11: |
| 96 browser = new IE(); |
| 97 break; |
| 98 default: |
| 99 throw "unreachable"; |
| 93 } | 100 } |
| 101 |
| 94 browser._binary = executablePath; | 102 browser._binary = executablePath; |
| 95 return browser; | 103 return browser; |
| 96 } | 104 } |
| 97 | 105 |
| 98 static const List<String> SUPPORTED_BROWSERS = const [ | 106 static const List<String> SUPPORTED_BROWSERS = const [ |
| 99 'safari', | 107 'safari', |
| 100 'ff', | 108 'ff', |
| 101 'firefox', | 109 'firefox', |
| 102 'chrome', | 110 'chrome', |
| 103 'ie9', | 111 'ie9', |
| 104 'ie10', | 112 'ie10', |
| 105 'ie11', | 113 'ie11', |
| 106 'dartium' | 114 'dartium' |
| 107 ]; | 115 ]; |
| 108 | 116 |
| 109 static const List<String> BROWSERS_WITH_WINDOW_SUPPORT = const [ | |
| 110 'ie11', | |
| 111 'ie10' | |
| 112 ]; | |
| 113 | |
| 114 /// If [browserName] doesn't support Window.open, we use iframes instead. | |
| 115 static bool requiresIframe(String browserName) { | |
| 116 return !BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); | |
| 117 } | |
| 118 | |
| 119 static bool requiresFocus(String browserName) { | 117 static bool requiresFocus(String browserName) { |
| 120 return browserName == "safari"; | 118 return browserName == "safari"; |
| 121 } | 119 } |
| 122 | 120 |
| 123 // TODO(kustermann): add standard support for chrome on android | 121 // TODO(kustermann): add standard support for chrome on android |
| 124 static bool supportedBrowser(String name) { | 122 static bool supportedBrowser(String name) { |
| 125 return SUPPORTED_BROWSERS.contains(name); | 123 return SUPPORTED_BROWSERS.contains(name); |
| 126 } | 124 } |
| 127 | 125 |
| 128 void _logEvent(String event) { | 126 void _logEvent(String event) { |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 /// driver page to the browsers, serves tests, and receives results and | 936 /// driver page to the browsers, serves tests, and receives results and |
| 939 /// requests back from the browsers. | 937 /// requests back from the browsers. |
| 940 class BrowserTestRunner { | 938 class BrowserTestRunner { |
| 941 static const int MAX_NEXT_TEST_TIMEOUTS = 10; | 939 static const int MAX_NEXT_TEST_TIMEOUTS = 10; |
| 942 static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 120); | 940 static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 120); |
| 943 static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60); | 941 static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60); |
| 944 | 942 |
| 945 /// If the queue was recently empty, don't start another browser. | 943 /// If the queue was recently empty, don't start another browser. |
| 946 static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1); | 944 static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1); |
| 947 | 945 |
| 948 final Map<String, dynamic> configuration; | 946 final Configuration configuration; |
| 949 final BrowserTestingServer testingServer; | 947 final BrowserTestingServer testingServer; |
| 950 | 948 |
| 951 final String localIp; | 949 final String localIp; |
| 952 final String browserName; | |
| 953 int maxNumBrowsers; | 950 int maxNumBrowsers; |
| 954 final bool checkedMode; | |
| 955 int numBrowsers = 0; | 951 int numBrowsers = 0; |
| 956 // Used to send back logs from the browser (start, stop etc) | 952 // Used to send back logs from the browser (start, stop etc) |
| 957 Function logger; | 953 Function logger; |
| 958 | 954 |
| 959 int browserIdCounter = 1; | 955 int browserIdCounter = 1; |
| 960 | 956 |
| 961 bool testingServerStarted = false; | 957 bool testingServerStarted = false; |
| 962 bool underTermination = false; | 958 bool underTermination = false; |
| 963 int numBrowserGetTestTimeouts = 0; | 959 int numBrowserGetTestTimeouts = 0; |
| 964 DateTime lastEmptyTestQueueTime = new DateTime.now(); | 960 DateTime lastEmptyTestQueueTime = new DateTime.now(); |
| 965 String _currentStartingBrowserId; | 961 String _currentStartingBrowserId; |
| 966 List<BrowserTest> testQueue = new List<BrowserTest>(); | 962 List<BrowserTest> testQueue = []; |
| 967 Map<String, BrowserStatus> browserStatus = new Map<String, BrowserStatus>(); | 963 Map<String, BrowserStatus> browserStatus = {}; |
| 968 | 964 |
| 969 var adbDeviceMapping = new Map<String, AdbDevice>(); | 965 Map<String, AdbDevice> adbDeviceMapping = {}; |
| 970 List<AdbDevice> idleAdbDevices; | 966 List<AdbDevice> idleAdbDevices; |
| 971 | 967 |
| 972 // This cache is used to guarantee that we never see double reporting. | 968 // This cache is used to guarantee that we never see double reporting. |
| 973 // If we do we need to provide developers with this information. | 969 // If we do we need to provide developers with this information. |
| 974 // We don't add urls to the cache until we have run it. | 970 // We don't add urls to the cache until we have run it. |
| 975 Map<int, String> testCache = new Map<int, String>(); | 971 Map<int, String> testCache = {}; |
| 976 | 972 |
| 977 Map<int, String> doubleReportingOutputs = new Map<int, String>(); | 973 Map<int, String> doubleReportingOutputs = {}; |
| 978 List<String> timedOut = []; | 974 List<String> timedOut = []; |
| 979 | 975 |
| 980 // We will start a new browser when the test queue hasn't been empty | 976 // We will start a new browser when the test queue hasn't been empty |
| 981 // recently, we have fewer than maxNumBrowsers browsers, and there is | 977 // recently, we have fewer than maxNumBrowsers browsers, and there is |
| 982 // no other browser instance currently starting up. | 978 // no other browser instance currently starting up. |
| 983 bool get queueWasEmptyRecently { | 979 bool get queueWasEmptyRecently { |
| 984 return testQueue.isEmpty || | 980 return testQueue.isEmpty || |
| 985 new DateTime.now().difference(lastEmptyTestQueueTime) < | 981 new DateTime.now().difference(lastEmptyTestQueueTime) < |
| 986 MIN_NONEMPTY_QUEUE_TIME; | 982 MIN_NONEMPTY_QUEUE_TIME; |
| 987 } | 983 } |
| 988 | 984 |
| 989 // While a browser is starting, but has not requested its first test, its | 985 // While a browser is starting, but has not requested its first test, its |
| 990 // browserId is stored in _currentStartingBrowserId. | 986 // browserId is stored in _currentStartingBrowserId. |
| 991 // When no browser is currently starting, _currentStartingBrowserId is null. | 987 // When no browser is currently starting, _currentStartingBrowserId is null. |
| 992 bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null; | 988 bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null; |
| 993 void markCurrentlyStarting(String id) { | 989 void markCurrentlyStarting(String id) { |
| 994 _currentStartingBrowserId = id; | 990 _currentStartingBrowserId = id; |
| 995 } | 991 } |
| 996 | 992 |
| 997 void markNotCurrentlyStarting(String id) { | 993 void markNotCurrentlyStarting(String id) { |
| 998 if (_currentStartingBrowserId == id) _currentStartingBrowserId = null; | 994 if (_currentStartingBrowserId == id) _currentStartingBrowserId = null; |
| 999 } | 995 } |
| 1000 | 996 |
| 1001 BrowserTestRunner(Map<String, dynamic> configuration, String localIp, | 997 BrowserTestRunner( |
| 1002 String browserName, this.maxNumBrowsers) | 998 Configuration configuration, String localIp, this.maxNumBrowsers) |
| 1003 : configuration = configuration, | 999 : configuration = configuration, |
| 1004 localIp = localIp, | 1000 localIp = localIp, |
| 1005 browserName = (browserName == 'ff') ? 'firefox' : browserName, | 1001 testingServer = new BrowserTestingServer(configuration, localIp, |
| 1006 checkedMode = configuration['checked'] as bool, | 1002 Browser.requiresFocus(configuration.runtime.name)) { |
| 1007 testingServer = new BrowserTestingServer( | |
| 1008 configuration, | |
| 1009 localIp, | |
| 1010 Browser.requiresIframe(browserName), | |
| 1011 Browser.requiresFocus(browserName)) { | |
| 1012 testingServer.testRunner = this; | 1003 testingServer.testRunner = this; |
| 1013 } | 1004 } |
| 1014 | 1005 |
| 1015 Future start() async { | 1006 Future start() async { |
| 1016 await testingServer.start(); | 1007 await testingServer.start(); |
| 1017 testingServer | 1008 testingServer |
| 1018 ..testDoneCallBack = handleResults | 1009 ..testDoneCallBack = handleResults |
| 1019 ..testStatusUpdateCallBack = handleStatusUpdate | 1010 ..testStatusUpdateCallBack = handleStatusUpdate |
| 1020 ..testStartedCallBack = handleStarted | 1011 ..testStartedCallBack = handleStarted |
| 1021 ..nextTestCallBack = getNextTest; | 1012 ..nextTestCallBack = getNextTest; |
| 1022 if (browserName == 'chromeOnAndroid') { | 1013 if (configuration.runtime == Runtime.chromeOnAndroid) { |
| 1023 var idbNames = await AdbHelper.listDevices(); | 1014 var idbNames = await AdbHelper.listDevices(); |
| 1024 idleAdbDevices = new List.from(idbNames.map((id) => new AdbDevice(id))); | 1015 idleAdbDevices = new List.from(idbNames.map((id) => new AdbDevice(id))); |
| 1025 maxNumBrowsers = min(maxNumBrowsers, idleAdbDevices.length); | 1016 maxNumBrowsers = min(maxNumBrowsers, idleAdbDevices.length); |
| 1026 } | 1017 } |
| 1027 testingServerStarted = true; | 1018 testingServerStarted = true; |
| 1028 requestBrowser(); | 1019 requestBrowser(); |
| 1029 } | 1020 } |
| 1030 | 1021 |
| 1031 /// requestBrowser() is called whenever we might want to start an additional | 1022 /// requestBrowser() is called whenever we might want to start an additional |
| 1032 /// browser instance. | 1023 /// browser instance. |
| 1033 /// It is called when starting the BrowserTestRunner, and whenever a browser | 1024 /// It is called when starting the BrowserTestRunner, and whenever a browser |
| 1034 /// is killed, whenever a new test is enqueued, or whenever a browser | 1025 /// is killed, whenever a new test is enqueued, or whenever a browser |
| 1035 /// finishes a test. | 1026 /// finishes a test. |
| 1036 /// So we are guaranteed that this will always eventually be called, as long | 1027 /// So we are guaranteed that this will always eventually be called, as long |
| 1037 /// as the test queue isn't empty. | 1028 /// as the test queue isn't empty. |
| 1038 void requestBrowser() { | 1029 void requestBrowser() { |
| 1039 if (!testingServerStarted) return; | 1030 if (!testingServerStarted) return; |
| 1040 if (underTermination) return; | 1031 if (underTermination) return; |
| 1041 if (numBrowsers == maxNumBrowsers) return; | 1032 if (numBrowsers == maxNumBrowsers) return; |
| 1042 if (aBrowserIsCurrentlyStarting) return; | 1033 if (aBrowserIsCurrentlyStarting) return; |
| 1043 if (numBrowsers > 0 && queueWasEmptyRecently) return; | 1034 if (numBrowsers > 0 && queueWasEmptyRecently) return; |
| 1044 createBrowser(); | 1035 createBrowser(); |
| 1045 } | 1036 } |
| 1046 | 1037 |
| 1047 String getNextBrowserId() => "BROWSER${browserIdCounter++}"; | 1038 String getNextBrowserId() => "BROWSER${browserIdCounter++}"; |
| 1048 | 1039 |
| 1049 void createBrowser() { | 1040 void createBrowser() { |
| 1050 final String id = getNextBrowserId(); | 1041 var id = getNextBrowserId(); |
| 1051 final String url = testingServer.getDriverUrl(id); | 1042 var url = testingServer.getDriverUrl(id); |
| 1043 |
| 1052 Browser browser; | 1044 Browser browser; |
| 1053 if (browserName == 'chromeOnAndroid') { | 1045 if (configuration.runtime == Runtime.chromeOnAndroid) { |
| 1054 AdbDevice device = idleAdbDevices.removeLast(); | 1046 AdbDevice device = idleAdbDevices.removeLast(); |
| 1055 adbDeviceMapping[id] = device; | 1047 adbDeviceMapping[id] = device; |
| 1056 browser = new AndroidChrome(device); | 1048 browser = new AndroidChrome(device); |
| 1057 } else { | 1049 } else { |
| 1058 String path = Locations.getBrowserLocation(browserName, configuration); | 1050 var path = configuration.browserLocation; |
| 1059 browser = new Browser.byName(browserName, path, checkedMode); | 1051 browser = new Browser.byRuntime( |
| 1052 configuration.runtime, path, configuration.isChecked); |
| 1060 browser.logger = logger; | 1053 browser.logger = logger; |
| 1061 } | 1054 } |
| 1055 |
| 1062 browser.id = id; | 1056 browser.id = id; |
| 1063 markCurrentlyStarting(id); | 1057 markCurrentlyStarting(id); |
| 1064 final status = new BrowserStatus(browser); | 1058 var status = new BrowserStatus(browser); |
| 1065 browserStatus[id] = status; | 1059 browserStatus[id] = status; |
| 1066 numBrowsers++; | 1060 numBrowsers++; |
| 1067 status.nextTestTimeout = createNextTestTimer(status); | 1061 status.nextTestTimeout = createNextTestTimer(status); |
| 1068 browser.start(url); | 1062 browser.start(url); |
| 1069 } | 1063 } |
| 1070 | 1064 |
| 1071 void handleResults(String browserId, String output, int testId) { | 1065 void handleResults(String browserId, String output, int testId) { |
| 1072 var status = browserStatus[browserId]; | 1066 var status = browserStatus[browserId]; |
| 1073 if (testCache.containsKey(testId)) { | 1067 if (testCache.containsKey(testId)) { |
| 1074 doubleReportingOutputs[testId] = output; | 1068 doubleReportingOutputs[testId] = output; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 | 1175 |
| 1182 // We don't want to start a new browser if we are terminating. | 1176 // We don't want to start a new browser if we are terminating. |
| 1183 if (underTermination) return; | 1177 if (underTermination) return; |
| 1184 removeBrowser(id); | 1178 removeBrowser(id); |
| 1185 requestBrowser(); | 1179 requestBrowser(); |
| 1186 } | 1180 } |
| 1187 | 1181 |
| 1188 /// Remove a browser that has closed from our data structures that track | 1182 /// Remove a browser that has closed from our data structures that track |
| 1189 /// open browsers. Check if we want to replace it with a new browser. | 1183 /// open browsers. Check if we want to replace it with a new browser. |
| 1190 void removeBrowser(String id) { | 1184 void removeBrowser(String id) { |
| 1191 if (browserName == 'chromeOnAndroid') { | 1185 if (configuration.runtime == Runtime.chromeOnAndroid) { |
| 1192 idleAdbDevices.add(adbDeviceMapping.remove(id)); | 1186 idleAdbDevices.add(adbDeviceMapping.remove(id)); |
| 1193 } | 1187 } |
| 1194 markNotCurrentlyStarting(id); | 1188 markNotCurrentlyStarting(id); |
| 1195 browserStatus.remove(id); | 1189 browserStatus.remove(id); |
| 1196 --numBrowsers; | 1190 --numBrowsers; |
| 1197 } | 1191 } |
| 1198 | 1192 |
| 1199 BrowserTest getNextTest(String browserId) { | 1193 BrowserTest getNextTest(String browserId) { |
| 1200 markNotCurrentlyStarting(browserId); | 1194 markNotCurrentlyStarting(browserId); |
| 1201 var status = browserStatus[browserId]; | 1195 var status = browserStatus[browserId]; |
| 1202 if (status == null) return null; | 1196 if (status == null) return null; |
| 1203 if (status.nextTestTimeout != null) { | 1197 if (status.nextTestTimeout != null) { |
| 1204 status.nextTestTimeout.cancel(); | 1198 status.nextTestTimeout.cancel(); |
| 1205 status.nextTestTimeout = null; | 1199 status.nextTestTimeout = null; |
| 1206 } | 1200 } |
| 1207 if (testQueue.isEmpty) return null; | 1201 if (testQueue.isEmpty) return null; |
| 1208 | 1202 |
| 1209 // We are currently terminating this browser, don't start a new test. | 1203 // We are currently terminating this browser, don't start a new test. |
| 1210 if (status.timeout) return null; | 1204 if (status.timeout) return null; |
| 1211 | 1205 |
| 1212 // Restart Internet Explorer if it has been | 1206 // Restart Internet Explorer if it has been |
| 1213 // running for longer than RESTART_BROWSER_INTERVAL. The tests have | 1207 // running for longer than RESTART_BROWSER_INTERVAL. The tests have |
| 1214 // had flaky timeouts, and this may help. | 1208 // had flaky timeouts, and this may help. |
| 1215 if ((browserName == 'ie10' || browserName == 'ie11') && | 1209 if ((configuration.runtime == Runtime.ie10 || |
| 1210 configuration.runtime == Runtime.ie11) && |
| 1216 status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) { | 1211 status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) { |
| 1217 var id = status.browser.id; | 1212 var id = status.browser.id; |
| 1218 // Reset stopwatch so we don't trigger again before restarting. | 1213 // Reset stopwatch so we don't trigger again before restarting. |
| 1219 status.timeout = true; | 1214 status.timeout = true; |
| 1220 status.browser.close().then((_) { | 1215 status.browser.close().then((_) { |
| 1221 // We don't want to start a new browser if we are terminating. | 1216 // We don't want to start a new browser if we are terminating. |
| 1222 if (underTermination) return; | 1217 if (underTermination) return; |
| 1223 removeBrowser(id); | 1218 removeBrowser(id); |
| 1224 requestBrowser(); | 1219 requestBrowser(); |
| 1225 }); | 1220 }); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 for (var browser in browsers) { | 1330 for (var browser in browsers) { |
| 1336 await browser.close(); | 1331 await browser.close(); |
| 1337 } | 1332 } |
| 1338 | 1333 |
| 1339 testingServer.errorReportingServer.close(); | 1334 testingServer.errorReportingServer.close(); |
| 1340 printDoubleReportingTests(); | 1335 printDoubleReportingTests(); |
| 1341 } | 1336 } |
| 1342 } | 1337 } |
| 1343 | 1338 |
| 1344 class BrowserTestingServer { | 1339 class BrowserTestingServer { |
| 1345 final Map configuration; | 1340 final Configuration configuration; |
| 1346 | 1341 |
| 1347 /// Interface of the testing server: | 1342 /// Interface of the testing server: |
| 1348 /// | 1343 /// |
| 1349 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 1344 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| 1350 /// and run tests ... | 1345 /// and run tests ... |
| 1351 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" | 1346 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" |
| 1352 /// where url is the test to run, and id is the id of the test. | 1347 /// where url is the test to run, and id is the id of the test. |
| 1353 /// If there are currently no available tests the waitSignal is send | 1348 /// If there are currently no available tests the waitSignal is send |
| 1354 /// back. If we are in the process of terminating the terminateSignal | 1349 /// back. If we are in the process of terminating the terminateSignal |
| 1355 /// is send back and the browser will stop requesting new tasks. | 1350 /// is send back and the browser will stop requesting new tasks. |
| 1356 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed | 1351 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed |
| 1357 /// test | 1352 /// test |
| 1358 | 1353 |
| 1359 final String localIp; | 1354 final String localIp; |
| 1360 final bool useIframe; | |
| 1361 final bool requiresFocus; | 1355 final bool requiresFocus; |
| 1362 BrowserTestRunner testRunner; | 1356 BrowserTestRunner testRunner; |
| 1363 | 1357 |
| 1364 static const String driverPath = "/driver"; | 1358 static const String driverPath = "/driver"; |
| 1365 static const String nextTestPath = "/next_test"; | 1359 static const String nextTestPath = "/next_test"; |
| 1366 static const String reportPath = "/report"; | 1360 static const String reportPath = "/report"; |
| 1367 static const String statusUpdatePath = "/status_update"; | 1361 static const String statusUpdatePath = "/status_update"; |
| 1368 static const String startedPath = "/started"; | 1362 static const String startedPath = "/started"; |
| 1369 static const String waitSignal = "WAIT"; | 1363 static const String waitSignal = "WAIT"; |
| 1370 static const String terminateSignal = "TERMINATE"; | 1364 static const String terminateSignal = "TERMINATE"; |
| 1371 | 1365 |
| 1372 var testCount = 0; | 1366 var testCount = 0; |
| 1373 HttpServer errorReportingServer; | 1367 HttpServer errorReportingServer; |
| 1374 bool underTermination = false; | 1368 bool underTermination = false; |
| 1375 | 1369 |
| 1376 TestChangedCallback testDoneCallBack; | 1370 TestChangedCallback testDoneCallBack; |
| 1377 TestChangedCallback testStatusUpdateCallBack; | 1371 TestChangedCallback testStatusUpdateCallBack; |
| 1378 TestChangedCallback testStartedCallBack; | 1372 TestChangedCallback testStartedCallBack; |
| 1379 NextTestCallback nextTestCallBack; | 1373 NextTestCallback nextTestCallBack; |
| 1380 | 1374 |
| 1381 BrowserTestingServer( | 1375 BrowserTestingServer(this.configuration, this.localIp, this.requiresFocus); |
| 1382 this.configuration, this.localIp, this.useIframe, this.requiresFocus); | |
| 1383 | 1376 |
| 1384 Future start() { | 1377 Future start() { |
| 1385 var testDriverErrorPort = configuration['test_driver_error_port'] as int; | |
| 1386 return HttpServer | 1378 return HttpServer |
| 1387 .bind(localIp, testDriverErrorPort) | 1379 .bind(localIp, configuration.testDriverErrorPort) |
| 1388 .then(setupErrorServer) | 1380 .then(setupErrorServer) |
| 1389 .then(setupDispatchingServer); | 1381 .then(setupDispatchingServer); |
| 1390 } | 1382 } |
| 1391 | 1383 |
| 1392 void setupErrorServer(HttpServer server) { | 1384 void setupErrorServer(HttpServer server) { |
| 1393 errorReportingServer = server; | 1385 errorReportingServer = server; |
| 1394 void errorReportingHandler(HttpRequest request) { | 1386 void errorReportingHandler(HttpRequest request) { |
| 1395 StringBuffer buffer = new StringBuffer(); | 1387 StringBuffer buffer = new StringBuffer(); |
| 1396 request.transform(UTF8.decoder).listen((data) { | 1388 request.transform(UTF8.decoder).listen((data) { |
| 1397 buffer.write(data); | 1389 buffer.write(data); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1411 } | 1403 } |
| 1412 | 1404 |
| 1413 void errorHandler(e) { | 1405 void errorHandler(e) { |
| 1414 if (!underTermination) print("Error occured in httpserver: $e"); | 1406 if (!underTermination) print("Error occured in httpserver: $e"); |
| 1415 } | 1407 } |
| 1416 | 1408 |
| 1417 errorReportingServer.listen(errorReportingHandler, onError: errorHandler); | 1409 errorReportingServer.listen(errorReportingHandler, onError: errorHandler); |
| 1418 } | 1410 } |
| 1419 | 1411 |
| 1420 void setupDispatchingServer(_) { | 1412 void setupDispatchingServer(_) { |
| 1421 var server = (configuration['_servers_'] as TestingServers).server; | 1413 var server = configuration.servers.server; |
| 1422 void noCache(HttpRequest request) { | 1414 void noCache(HttpRequest request) { |
| 1423 request.response.headers | 1415 request.response.headers |
| 1424 .set("Cache-Control", "no-cache, no-store, must-revalidate"); | 1416 .set("Cache-Control", "no-cache, no-store, must-revalidate"); |
| 1425 } | 1417 } |
| 1426 | 1418 |
| 1427 int testId(HttpRequest request) => | 1419 int testId(HttpRequest request) => |
| 1428 int.parse(request.uri.queryParameters["id"]); | 1420 int.parse(request.uri.queryParameters["id"]); |
| 1429 String browserId(HttpRequest request, String prefix) => | 1421 String browserId(HttpRequest request, String prefix) => |
| 1430 request.uri.path.substring(prefix.length + 1); | 1422 request.uri.path.substring(prefix.length + 1); |
| 1431 | 1423 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1527 return nextTest == null ? waitSignal : nextTest.toJSON(); | 1519 return nextTest == null ? waitSignal : nextTest.toJSON(); |
| 1528 } | 1520 } |
| 1529 | 1521 |
| 1530 String getDriverUrl(String browserId) { | 1522 String getDriverUrl(String browserId) { |
| 1531 if (errorReportingServer == null) { | 1523 if (errorReportingServer == null) { |
| 1532 print("Bad browser testing server, you are not started yet. Can't " | 1524 print("Bad browser testing server, you are not started yet. Can't " |
| 1533 "produce driver url"); | 1525 "produce driver url"); |
| 1534 exit(1); | 1526 exit(1); |
| 1535 // This should never happen - exit immediately; | 1527 // This should never happen - exit immediately; |
| 1536 } | 1528 } |
| 1537 var port = (configuration['_servers_'] as TestingServers).port; | 1529 |
| 1538 return "http://$localIp:$port/driver/$browserId"; | 1530 return "http://$localIp:${configuration.servers.port}/driver/$browserId"; |
| 1539 } | 1531 } |
| 1540 | 1532 |
| 1541 Future<String> getDriverPage(String browserId) async { | 1533 Future<String> getDriverPage(String browserId) async { |
| 1542 await testRunner.browserStatus[browserId].browser.onDriverPageRequested(); | 1534 await testRunner.browserStatus[browserId].browser.onDriverPageRequested(); |
| 1543 var errorReportingUrl = | 1535 var errorReportingUrl = |
| 1544 "http://$localIp:${errorReportingServer.port}/$browserId"; | 1536 "http://$localIp:${errorReportingServer.port}/$browserId"; |
| 1545 String driverContent = """ | 1537 String driverContent = """ |
| 1546 <!DOCTYPE html><html> | 1538 <!DOCTYPE html><html> |
| 1547 <head> | 1539 <head> |
| 1548 <title>Driving page</title> | 1540 <title>Driving page</title> |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1578 var test_completed = true; | 1570 var test_completed = true; |
| 1579 // Has the test in the current iframe reported that it is started? | 1571 // Has the test in the current iframe reported that it is started? |
| 1580 var test_started = false; | 1572 var test_started = false; |
| 1581 var testing_window; | 1573 var testing_window; |
| 1582 | 1574 |
| 1583 var embedded_iframe_div = document.getElementById('embedded_iframe_div'); | 1575 var embedded_iframe_div = document.getElementById('embedded_iframe_div'); |
| 1584 var embedded_iframe = document.getElementById('embedded_iframe'); | 1576 var embedded_iframe = document.getElementById('embedded_iframe'); |
| 1585 var number_div = document.getElementById('number'); | 1577 var number_div = document.getElementById('number'); |
| 1586 var executing_div = document.getElementById('currently_executing'); | 1578 var executing_div = document.getElementById('currently_executing'); |
| 1587 var error_div = document.getElementById('unhandled_error'); | 1579 var error_div = document.getElementById('unhandled_error'); |
| 1588 var use_iframe = ${useIframe}; | 1580 var use_iframe = ${configuration.runtime.requiresIFrame}; |
| 1589 var start = new Date(); | 1581 var start = new Date(); |
| 1590 | 1582 |
| 1591 // Object that holds the state of an HTML test | 1583 // Object that holds the state of an HTML test |
| 1592 var html_test; | 1584 var html_test; |
| 1593 | 1585 |
| 1594 function newTaskHandler() { | 1586 function newTaskHandler() { |
| 1595 if (this.readyState == this.DONE) { | 1587 if (this.readyState == this.DONE) { |
| 1596 if (this.status == 200) { | 1588 if (this.status == 200) { |
| 1597 if (this.responseText == '$waitSignal') { | 1589 if (this.responseText == '$waitSignal') { |
| 1598 setTimeout(getNextTask, 500); | 1590 setTimeout(getNextTask, 500); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 'exit code: ${result.exitCode}\n' | 1940 'exit code: ${result.exitCode}\n' |
| 1949 'stdout: ${result.stdout}\n' | 1941 'stdout: ${result.stdout}\n' |
| 1950 'stderr: ${result.stderr}'); | 1942 'stderr: ${result.stderr}'); |
| 1951 } else { | 1943 } else { |
| 1952 print('[$message] Successfully uploaded screenshot to $storageUrl'); | 1944 print('[$message] Successfully uploaded screenshot to $storageUrl'); |
| 1953 } | 1945 } |
| 1954 new File(screenshotFile).deleteSync(); | 1946 new File(screenshotFile).deleteSync(); |
| 1955 } | 1947 } |
| 1956 print('--------------------------------------------------------------------'); | 1948 print('--------------------------------------------------------------------'); |
| 1957 } | 1949 } |
| OLD | NEW |