| 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'; |
| 11 import 'utils.dart'; | 11 import 'utils.dart'; |
| 12 | 12 |
| 13 /** Class describing the interface for communicating with browsers. */ | 13 /** Class describing the interface for communicating with browsers. */ |
| 14 abstract class Browser { | 14 abstract class Browser { |
| 15 StringBuffer _stdout = new StringBuffer(); | 15 StringBuffer _stdout = new StringBuffer(); |
| 16 StringBuffer _stderr = new StringBuffer(); | 16 StringBuffer _stderr = new StringBuffer(); |
| 17 StringBuffer _usageLog = new StringBuffer(); | 17 StringBuffer _usageLog = new StringBuffer(); |
| 18 // This function is called when the process is closed. | 18 // This function is called when the process is closed. |
| 19 // This is extracted to an external function so that we can do additional | 19 Completer _processClosedCompleter = new Completer(); |
| 20 // functionality when the process closes (cleanup and call onExit) | 20 // This is called after the process is closed, after _processClosedCompleter |
| 21 Function _processClosed; | 21 // has been called, but before onExit. Subclasses can use this to cleanup |
| 22 // This is called after the process is closed, after _processClosed has | |
| 23 // been called, but before onExit. Subclasses can use this to cleanup | |
| 24 // any browser specific resources (temp directories, profiles, etc) | 22 // any browser specific resources (temp directories, profiles, etc) |
| 23 // The function is expected to do it's work synchronously. |
| 25 Function _cleanup; | 24 Function _cleanup; |
| 26 | 25 |
| 27 /** The version of the browser - normally set when starting a browser */ | 26 /** The version of the browser - normally set when starting a browser */ |
| 28 String version = ""; | 27 String version = ""; |
| 29 /** | 28 /** |
| 30 * The underlying process - don't mess directly with this if you don't | 29 * The underlying process - don't mess directly with this if you don't |
| 31 * know what you are doing (this is an interactive process that needs | 30 * know what you are doing (this is an interactive process that needs |
| 32 * special threatment to not leak). | 31 * special threatment to not leak). |
| 33 */ | 32 */ |
| 34 Process process; | 33 Process process; |
| 35 | 34 |
| 36 Function logger; | 35 Function logger; |
| 37 | 36 |
| 38 /** | 37 /** |
| 39 * Id of the browser | 38 * Id of the browser |
| 40 */ | 39 */ |
| 41 String id; | 40 String id; |
| 42 | 41 |
| 43 /** Callback that will be executed when the browser has closed */ | |
| 44 Function onClose; | |
| 45 | |
| 46 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ | 42 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ |
| 47 bool debugPrint = false; | 43 bool debugPrint = false; |
| 48 | 44 |
| 49 // This future will be lazily set when calling close() and will complete once | 45 // This future will be lazily set when calling close() and will complete once |
| 50 // the process did exit. | 46 // the process did exit. |
| 51 Future browserTerminationFuture; | 47 Future browserTerminationFuture; |
| 52 | 48 |
| 53 Browser(); | 49 Browser(); |
| 54 | 50 |
| 55 factory Browser.byName(String name) { | 51 factory Browser.byName(String name) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 _stderr.write(output); | 88 _stderr.write(output); |
| 93 } | 89 } |
| 94 | 90 |
| 95 Future close() { | 91 Future close() { |
| 96 _logEvent("Close called on browser"); | 92 _logEvent("Close called on browser"); |
| 97 if (browserTerminationFuture == null) { | 93 if (browserTerminationFuture == null) { |
| 98 var completer = new Completer(); | 94 var completer = new Completer(); |
| 99 browserTerminationFuture = completer.future; | 95 browserTerminationFuture = completer.future; |
| 100 | 96 |
| 101 if (process != null) { | 97 if (process != null) { |
| 102 // Make sure we intercept onExit calls and complete. | 98 _processClosedCompleter.future.then((_) { |
| 103 _processClosed = () { | |
| 104 _processClosed = null; | |
| 105 process = null; | 99 process = null; |
| 106 completer.complete(true); | 100 completer.complete(true); |
| 107 }; | 101 if (_cleanup != null) { |
| 102 _cleanup(); |
| 103 } |
| 104 }); |
| 108 | 105 |
| 109 if (process.kill(ProcessSignal.SIGKILL)) { | 106 if (process.kill(ProcessSignal.SIGKILL)) { |
| 110 _logEvent("Successfully sent kill signal to process."); | 107 _logEvent("Successfully sent kill signal to process."); |
| 111 } else { | 108 } else { |
| 112 _logEvent("Sending kill signal failed."); | 109 _logEvent("Sending kill signal failed."); |
| 113 } | 110 } |
| 114 } else { | 111 } else { |
| 115 _logEvent("The process is already dead."); | 112 _logEvent("The process is already dead."); |
| 116 completer.complete(true); | 113 completer.complete(true); |
| 117 } | 114 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 145 // This should _never_ happen, but we really want this in the log | 142 // This should _never_ happen, but we really want this in the log |
| 146 // if it actually does due to dart:io or vm bug. | 143 // if it actually does due to dart:io or vm bug. |
| 147 _logEvent("An error occured in the process stderr handling: $error"); | 144 _logEvent("An error occured in the process stderr handling: $error"); |
| 148 }, onDone: () { | 145 }, onDone: () { |
| 149 stderrDone.complete(true); | 146 stderrDone.complete(true); |
| 150 }); | 147 }); |
| 151 | 148 |
| 152 process.exitCode.then((exitCode) { | 149 process.exitCode.then((exitCode) { |
| 153 _logEvent("Browser closed with exitcode $exitCode"); | 150 _logEvent("Browser closed with exitcode $exitCode"); |
| 154 Future.wait([stdoutDone.future, stderrDone.future]).then((_) { | 151 Future.wait([stdoutDone.future, stderrDone.future]).then((_) { |
| 155 if (_processClosed != null) _processClosed(); | 152 _processClosedCompleter.complete(exitCode); |
| 156 if (_cleanup != null) _cleanup(); | |
| 157 if (onClose != null) onClose(exitCode); | |
| 158 }); | 153 }); |
| 159 }); | 154 }); |
| 160 return true; | 155 return true; |
| 161 }).catchError((error) { | 156 }).catchError((error) { |
| 162 _logEvent("Running $command $arguments failed with $error"); | 157 _logEvent("Running $command $arguments failed with $error"); |
| 163 return false; | 158 return false; |
| 164 }); | 159 }); |
| 165 } | 160 } |
| 166 | 161 |
| 167 /** | 162 /** |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 _logEvent("Starting Safari browser on: $url"); | 244 _logEvent("Starting Safari browser on: $url"); |
| 250 // Get the version and log that. | 245 // Get the version and log that. |
| 251 return allowPopUps().then((success) { | 246 return allowPopUps().then((success) { |
| 252 if (!success) { | 247 if (!success) { |
| 253 return new Future.immediate(false); | 248 return new Future.immediate(false); |
| 254 } | 249 } |
| 255 return getVersion().then((version) { | 250 return getVersion().then((version) { |
| 256 _logEvent("Got version: $version"); | 251 _logEvent("Got version: $version"); |
| 257 var args = ["'$url'"]; | 252 var args = ["'$url'"]; |
| 258 return new Directory('').createTemp().then((userDir) { | 253 return new Directory('').createTemp().then((userDir) { |
| 259 _cleanup = () { userDir.delete(recursive: true); }; | 254 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 260 _createLaunchHTML(userDir.path, url); | 255 _createLaunchHTML(userDir.path, url); |
| 261 var args = ["${userDir.path}/launch.html"]; | 256 var args = ["${userDir.path}/launch.html"]; |
| 262 return startBrowser(binary, args); | 257 return startBrowser(binary, args); |
| 263 }); | 258 }); |
| 264 }).catchError((e) { | 259 }).catchError((e) { |
| 265 _logEvent("Running $binary --version failed with $e"); | 260 _logEvent("Running $binary --version failed with $e"); |
| 266 return false; | 261 return false; |
| 267 }); | 262 }); |
| 268 }); | 263 }); |
| 269 } | 264 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 285 return Process.run(binary, ["--version"]).then((var versionResult) { | 280 return Process.run(binary, ["--version"]).then((var versionResult) { |
| 286 if (versionResult.exitCode != 0) { | 281 if (versionResult.exitCode != 0) { |
| 287 _logEvent("Failed to chrome get version"); | 282 _logEvent("Failed to chrome get version"); |
| 288 _logEvent("Make sure $binary is a valid program for running chrome"); | 283 _logEvent("Make sure $binary is a valid program for running chrome"); |
| 289 return new Future.immediate(false); | 284 return new Future.immediate(false); |
| 290 } | 285 } |
| 291 version = versionResult.stdout; | 286 version = versionResult.stdout; |
| 292 _logEvent("Got version: $version"); | 287 _logEvent("Got version: $version"); |
| 293 | 288 |
| 294 return new Directory('').createTemp().then((userDir) { | 289 return new Directory('').createTemp().then((userDir) { |
| 295 _cleanup = () { userDir.delete(recursive: true); }; | 290 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 296 var args = ["--user-data-dir=${userDir.path}", url, | 291 var args = ["--user-data-dir=${userDir.path}", url, |
| 297 "--disable-extensions", "--disable-popup-blocking", | 292 "--disable-extensions", "--disable-popup-blocking", |
| 298 "--bwsi", "--no-first-run"]; | 293 "--bwsi", "--no-first-run"]; |
| 299 return startBrowser(binary, args); | 294 return startBrowser(binary, args); |
| 300 | 295 |
| 301 }); | 296 }); |
| 302 }).catchError((e) { | 297 }).catchError((e) { |
| 303 _logEvent("Running $binary --version failed with $e"); | 298 _logEvent("Running $binary --version failed with $e"); |
| 304 return false; | 299 return false; |
| 305 }); | 300 }); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 if (versionResult.exitCode != 0) { | 397 if (versionResult.exitCode != 0) { |
| 403 _logEvent("Failed to firefox get version"); | 398 _logEvent("Failed to firefox get version"); |
| 404 _logEvent("Make sure $binary is a valid program for running firefox"); | 399 _logEvent("Make sure $binary is a valid program for running firefox"); |
| 405 return new Future.immediate(false); | 400 return new Future.immediate(false); |
| 406 } | 401 } |
| 407 version = versionResult.stdout; | 402 version = versionResult.stdout; |
| 408 _logEvent("Got version: $version"); | 403 _logEvent("Got version: $version"); |
| 409 | 404 |
| 410 return new Directory('').createTemp().then((userDir) { | 405 return new Directory('').createTemp().then((userDir) { |
| 411 _createPreferenceFile(userDir.path); | 406 _createPreferenceFile(userDir.path); |
| 412 _cleanup = () { userDir.delete(recursive: true); }; | 407 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 413 var args = ["-profile", "${userDir.path}", | 408 var args = ["-profile", "${userDir.path}", |
| 414 "-no-remote", "-new-instance", url]; | 409 "-no-remote", "-new-instance", url]; |
| 415 return startBrowser(binary, args); | 410 return startBrowser(binary, args); |
| 416 | 411 |
| 417 }); | 412 }); |
| 418 }).catchError((e) { | 413 }).catchError((e) { |
| 419 _logEvent("Running $binary --version failed with $e"); | 414 _logEvent("Running $binary --version failed with $e"); |
| 420 return false; | 415 return false; |
| 421 }); | 416 }); |
| 422 } | 417 } |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 </head> | 928 </head> |
| 934 <body onload="startTesting()"> | 929 <body onload="startTesting()"> |
| 935 Dart test driver, number of tests: <div id="number"></div> | 930 Dart test driver, number of tests: <div id="number"></div> |
| 936 <iframe id="embedded_iframe"></iframe> | 931 <iframe id="embedded_iframe"></iframe> |
| 937 </body> | 932 </body> |
| 938 </html> | 933 </html> |
| 939 """; | 934 """; |
| 940 return driverContent; | 935 return driverContent; |
| 941 } | 936 } |
| 942 } | 937 } |
| OLD | NEW |