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:core"; | 7 import "dart:core"; |
| 8 import "dart:io"; | 8 import "dart:io"; |
| 9 | 9 |
| 10 import 'android.dart'; | 10 import 'android.dart'; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 * Id of the browser | 41 * Id of the browser |
| 42 */ | 42 */ |
| 43 String id; | 43 String id; |
| 44 | 44 |
| 45 /** Callback that will be executed when the browser has closed */ | 45 /** Callback that will be executed when the browser has closed */ |
| 46 Function onClose; | 46 Function onClose; |
| 47 | 47 |
| 48 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ | 48 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ |
| 49 bool debugPrint = true; | 49 bool debugPrint = true; |
| 50 | 50 |
| 51 // We use this to gracefully handle double calls to close. | |
| 52 bool underTermination = false; | |
| 53 | |
| 51 void _logEvent(String event) { | 54 void _logEvent(String event) { |
| 52 String toLog = "$this ($id) - ${new DateTime.now()}: $event \n"; | 55 String toLog = "$this ($id) - ${new DateTime.now()}: $event \n"; |
| 53 if (debugPrint) print("usageLog: $toLog"); | 56 if (debugPrint) print("usageLog: $toLog"); |
| 54 _usageLog.write(toLog); | 57 _usageLog.write(toLog); |
| 55 } | 58 } |
| 56 | 59 |
| 57 void _addStdout(String output) { | 60 void _addStdout(String output) { |
| 58 if (debugPrint) print("stdout: $output"); | 61 if (debugPrint) print("stdout: $output"); |
| 59 _stdout.write(output); | 62 _stdout.write(output); |
| 60 } | 63 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 _logEvent("The process is already dead, kill signal could not be send"); | 115 _logEvent("The process is already dead, kill signal could not be send"); |
| 113 completer.complete(true); | 116 completer.complete(true); |
| 114 } | 117 } |
| 115 return completer.future; | 118 return completer.future; |
| 116 } | 119 } |
| 117 | 120 |
| 118 | 121 |
| 119 /** Close the browser */ | 122 /** Close the browser */ |
| 120 Future<bool> close() { | 123 Future<bool> close() { |
| 121 _logEvent("Close called on browser"); | 124 _logEvent("Close called on browser"); |
| 125 if (underTermination) { | |
| 126 _logEvent("Browser already under termination."); | |
| 127 return new Future.immediate(true); | |
| 128 } | |
| 129 underTermination = true; | |
| 122 if (process == null) { | 130 if (process == null) { |
| 123 _logEvent("No process open, nothing to kill."); | 131 _logEvent("No process open, nothing to kill."); |
| 124 return new Future.immediate(true); | 132 return new Future.immediate(true); |
| 125 } | 133 } |
| 126 var killFunction = process.kill; | 134 var killFunction = process.kill; |
| 127 // We use a SIGKILL signal if we don't kill the process in the first go. | 135 // We use a SIGKILL signal if we don't kill the process in the first go. |
| 128 var alternativeKillFunction = | 136 var alternativeKillFunction = |
| 129 () { return process.kill(ProcessSignal.SIGKILL);}; | 137 () { return process.kill(ProcessSignal.SIGKILL);}; |
| 130 return _killIt(killFunction, killRetries, alternativeKillFunction); | 138 return _killIt(killFunction, killRetries, alternativeKillFunction); |
| 131 } | 139 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 */ | 179 */ |
| 172 String get stdout => _stdout.toString(); | 180 String get stdout => _stdout.toString(); |
| 173 String get stderr => _stderr.toString(); | 181 String get stderr => _stderr.toString(); |
| 174 String get usageLog => _usageLog.toString(); | 182 String get usageLog => _usageLog.toString(); |
| 175 | 183 |
| 176 String toString(); | 184 String toString(); |
| 177 /** Starts the browser loading the given url */ | 185 /** Starts the browser loading the given url */ |
| 178 Future<bool> start(String url); | 186 Future<bool> start(String url); |
| 179 } | 187 } |
| 180 | 188 |
| 189 class Safari extends Browser { | |
| 190 /** | |
| 191 * The binary used to run safari - changing this can be nececcary for | |
| 192 * testing or using non standard safari installation. | |
| 193 */ | |
| 194 const String binary = "/Applications/Safari.app/Contents/MacOS/Safari"; | |
| 195 | |
| 196 /** | |
| 197 * We get the safari version by parsing a version file | |
| 198 */ | |
| 199 const String versionFile = "/Applications/Safari.app/Contents/version.plist"; | |
| 200 | |
| 201 Future<String> getVersion() { | |
| 202 File f = new File(versionFile); | |
| 203 return f.readAsLines().then((content) { | |
| 204 bool versionOnNextLine = false; | |
|
kustermann
2013/05/28 07:42:39
Small comment about how the file looks like would
ricow1
2013/05/28 08:07:30
Done.
| |
| 205 for (var line in content) { | |
| 206 if (versionOnNextLine) return line; | |
| 207 if (line.contains("CFBundleShortVersionString")) { | |
| 208 versionOnNextLine = true; | |
| 209 } | |
| 210 } | |
| 211 return null; | |
| 212 }); | |
| 213 } | |
| 214 | |
| 215 void _createLaunchHTML(var path, var url) { | |
| 216 var file = new File("${path.toString()}/launch.html"); | |
|
kustermann
2013/05/28 07:42:39
No reason to call 'toString()' explicitly (otherwi
ricow1
2013/05/28 08:07:30
Done.
| |
| 217 var randomFile = file.openSync(FileMode.WRITE); | |
| 218 var content = '<script language="JavaScript">location = "$url"</script>'; | |
| 219 randomFile.writeStringSync(content); | |
| 220 randomFile.close(); | |
| 221 } | |
| 222 | |
| 223 Future<bool> start(String url) { | |
| 224 _logEvent("Starting Safari browser on: $url"); | |
| 225 // Get the version and log that. | |
| 226 return getVersion().then((version) { | |
| 227 _logEvent("Got version: $version"); | |
| 228 var args = ["'$url'"]; | |
| 229 return new Directory('').createTemp().then((userDir) { | |
| 230 _cleanup = () { userDir.delete(recursive: true); }; | |
| 231 _createLaunchHTML(userDir.path, url); | |
| 232 var args = ["${userDir.path}/launch.html"]; | |
| 233 return startBrowser(binary, args); | |
| 234 }); | |
| 235 }).catchError((e) { | |
| 236 _logEvent("Running $binary --version failed with $e"); | |
| 237 return false; | |
| 238 }); | |
| 239 } | |
| 240 | |
| 241 String toString() => "Safari"; | |
| 242 } | |
| 243 | |
| 244 | |
| 181 class Chrome extends Browser { | 245 class Chrome extends Browser { |
| 182 /** | 246 /** |
| 183 * The binary used to run chrome - changing this can be nececcary for | 247 * The binary used to run chrome - changing this can be nececcary for |
| 184 * testing or using non standard chrome installation. | 248 * testing or using non standard chrome installation. |
| 185 */ | 249 */ |
| 186 const String binary = "google-chrome"; | 250 const String binary = "google-chrome"; |
| 187 | 251 |
| 188 Future<bool> start(String url) { | 252 Future<bool> start(String url) { |
| 189 _logEvent("Starting chrome browser on: $url"); | 253 _logEvent("Starting chrome browser on: $url"); |
| 190 // Get the version and log that. | 254 // Get the version and log that. |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 // We could be smarter here, but it does not seems like it is worth it. | 575 // We could be smarter here, but it does not seems like it is worth it. |
| 512 status.timeout = true; | 576 status.timeout = true; |
| 513 timedOut.add(status.currentTest.url); | 577 timedOut.add(status.currentTest.url); |
| 514 var id = status.browser.id; | 578 var id = status.browser.id; |
| 515 status.browser.close().then((closed) { | 579 status.browser.close().then((closed) { |
| 516 if (!closed) { | 580 if (!closed) { |
| 517 // Very bad, we could not kill the browser. | 581 // Very bad, we could not kill the browser. |
| 518 print("could not kill browser $id"); | 582 print("could not kill browser $id"); |
| 519 return; | 583 return; |
| 520 } | 584 } |
| 585 // We don't want to start a new browser if we are terminating. | |
| 586 if (underTermination) return; | |
|
kustermann
2013/05/28 07:42:39
We could also assert/throw here, since we never re
ricow1
2013/05/28 08:07:30
Here is what can happen:
All tests but one are don
| |
| 587 | |
| 521 var browser; | 588 var browser; |
| 522 if (browserName == 'chromeOnAndroid') { | 589 if (browserName == 'chromeOnAndroid') { |
| 523 browser = new AndroidChrome(adbDeviceMapping[id]); | 590 browser = new AndroidChrome(adbDeviceMapping[id]); |
| 524 } else { | 591 } else { |
| 525 browser = getInstance(); | 592 browser = getInstance(); |
| 526 } | 593 } |
| 527 browser.start(testingServer.getDriverUrl(id)).then((success) { | 594 browser.start(testingServer.getDriverUrl(id)).then((success) { |
| 528 // We may have started terminating in the mean time. | 595 // We may have started terminating in the mean time. |
| 529 if (underTermination) { | 596 if (underTermination) { |
| 530 browser.close().then((success) { | 597 browser.close().then((success) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 printDoubleReportingTests(); | 671 printDoubleReportingTests(); |
| 605 return !values.contains(false); | 672 return !values.contains(false); |
| 606 }); | 673 }); |
| 607 } | 674 } |
| 608 | 675 |
| 609 Browser getInstance() { | 676 Browser getInstance() { |
| 610 if (browserName == "chrome") { | 677 if (browserName == "chrome") { |
| 611 return new Chrome(); | 678 return new Chrome(); |
| 612 } else if (browserName == "ff") { | 679 } else if (browserName == "ff") { |
| 613 return new Firefox(); | 680 return new Firefox(); |
| 681 } else if (browserName == "safari") { | |
| 682 return new Safari(); | |
| 614 } else { | 683 } else { |
| 615 throw "Non supported browser for browser controller"; | 684 throw "Non supported browser for browser controller"; |
| 616 } | 685 } |
| 617 } | 686 } |
| 618 } | 687 } |
| 619 | 688 |
| 620 class BrowserTestingServer { | 689 class BrowserTestingServer { |
| 621 /// Interface of the testing server: | 690 /// Interface of the testing server: |
| 622 /// | 691 /// |
| 623 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 692 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 textResponse = getDriverPage(browserId); | 735 textResponse = getDriverPage(browserId); |
| 667 } else if (request.uri.path.startsWith(nextTestPath)) { | 736 } else if (request.uri.path.startsWith(nextTestPath)) { |
| 668 var browserId = request.uri.path.substring(nextTestPath.length + 1); | 737 var browserId = request.uri.path.substring(nextTestPath.length + 1); |
| 669 textResponse = getNextTest(browserId); | 738 textResponse = getNextTest(browserId); |
| 670 } else { | 739 } else { |
| 671 // We silently ignore other requests. | 740 // We silently ignore other requests. |
| 672 } | 741 } |
| 673 request.response.write(textResponse); | 742 request.response.write(textResponse); |
| 674 request.listen((_) {}, onDone: request.response.close); | 743 request.listen((_) {}, onDone: request.response.close); |
| 675 request.response.done.catchError((error) { | 744 request.response.done.catchError((error) { |
| 676 if (!underTermination) { | 745 if (!underTermination) { |
| 677 print("URI ${request.uri}"); | 746 print("URI ${request.uri}"); |
| 678 print("Textresponse $textResponse"); | 747 print("Textresponse $textResponse"); |
| 679 throw("Error returning content to browser: $error"); | 748 throw("Error returning content to browser: $error"); |
|
kustermann
2013/05/28 07:42:39
don't use 'throw()' but rather 'throw ""'
ricow1
2013/05/28 08:07:30
Done.
| |
| 680 } | 749 } |
| 681 }); | 750 }); |
| 682 } | 751 } |
| 683 void errorHandler(e) { | 752 void errorHandler(e) { |
| 684 if (!underTermination) print("Error occured in httpserver: $e"); | 753 if (!underTermination) print("Error occured in httpserver: $e"); |
| 685 }; | 754 }; |
| 686 httpServer.listen(handler, onError: errorHandler); | 755 httpServer.listen(handler, onError: errorHandler); |
| 687 return true; | 756 return true; |
| 688 }); | 757 }); |
| 689 } | 758 } |
| 690 | 759 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 821 </script> | 890 </script> |
| 822 </head> | 891 </head> |
| 823 <body> | 892 <body> |
| 824 Dart test driver, number of tests: <div id="number"></div> | 893 Dart test driver, number of tests: <div id="number"></div> |
| 825 </body> | 894 </body> |
| 826 </html> | 895 </html> |
| 827 """; | 896 """; |
| 828 return driverContent; | 897 return driverContent; |
| 829 } | 898 } |
| 830 } | 899 } |
| OLD | NEW |