Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 | 4 |
| 5 library unittest.runner.browser.chrome; | 5 library unittest.runner.browser.chrome; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import '../../util/io.dart'; | 10 import '../../util/io.dart'; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 /// A future that completes when the browser process has started. | 38 /// A future that completes when the browser process has started. |
| 39 /// | 39 /// |
| 40 /// This is used to ensure that [close] works regardless of when it's called. | 40 /// This is used to ensure that [close] works regardless of when it's called. |
| 41 Future get _onProcessStarted => _onProcessStartedCompleter.future; | 41 Future get _onProcessStarted => _onProcessStartedCompleter.future; |
| 42 final _onProcessStartedCompleter = new Completer(); | 42 final _onProcessStartedCompleter = new Completer(); |
| 43 | 43 |
| 44 /// Starts a new instance of Chrome open to the given [url], which may be a | 44 /// Starts a new instance of Chrome open to the given [url], which may be a |
| 45 /// [Uri] or a [String]. | 45 /// [Uri] or a [String]. |
| 46 /// | 46 /// |
| 47 /// If [executable] is passed, it's used as the Chrome executable. Otherwise | 47 /// If [executable] is passed, it's used as the Chrome executable. Otherwise |
| 48 /// `"google-chrome"` will be looked up on the system PATH. | 48 /// the default executable name for the current OS will be used. |
| 49 Chrome(url, {String executable}) { | 49 Chrome(url, {String executable}) { |
| 50 if (executable == null) executable = "google-chrome"; | 50 if (executable == null) executable = _defaultExecutable(); |
| 51 | 51 |
| 52 // Don't return a Future here because there's no need for the caller to wait | 52 // Don't return a Future here because there's no need for the caller to wait |
| 53 // for the process to actually start. They should just wait for the HTTP | 53 // for the process to actually start. They should just wait for the HTTP |
| 54 // request instead. | 54 // request instead. |
| 55 withTempDir((dir) { | 55 withTempDir((dir) { |
| 56 _dir = dir; | 56 _dir = dir; |
| 57 return Process.start(executable, [ | 57 return Process.start(executable, [ |
| 58 "--user-data-dir=$_dir", | 58 "--user-data-dir=$_dir", |
| 59 url.toString(), | 59 url.toString(), |
| 60 "--disable-extensions", | 60 "--disable-extensions", |
| 61 "--disable-popup-blocking", | 61 "--disable-popup-blocking", |
| 62 "--bwsi", | 62 "--bwsi", |
| 63 "--no-first-run" | 63 "--no-first-run", |
| 64 "--no-default-browser-check", | |
| 65 "--disable-default-apps", | |
| 66 "--disable-translate" | |
| 64 ]).then((process) { | 67 ]).then((process) { |
| 65 _process = process; | 68 _process = process; |
| 66 _onProcessStartedCompleter.complete(); | 69 _onProcessStartedCompleter.complete(); |
| 67 | 70 |
| 68 // TODO(nweiz): the browser's standard output is almost always useless | 71 // TODO(nweiz): the browser's standard output is almost always useless |
| 69 // noise, but we should allow the user to opt in to seeing it. | 72 // noise, but we should allow the user to opt in to seeing it. |
| 70 return _process.exitCode; | 73 return _process.exitCode; |
| 71 }); | 74 }); |
| 72 }).then((exitCode) { | 75 }).then((exitCode) { |
| 73 if (exitCode != 0) throw "Chrome failed with exit code $exitCode."; | 76 if (exitCode != 0) throw "Chrome failed with exit code $exitCode."; |
| 74 }).then(_onExitCompleter.complete) | 77 }).then(_onExitCompleter.complete) |
| 75 .catchError(_onExitCompleter.completeError); | 78 .catchError(_onExitCompleter.completeError); |
| 76 } | 79 } |
| 77 | 80 |
| 78 /// Kills the browser process. | 81 /// Kills the browser process. |
| 79 /// | 82 /// |
| 80 /// Returns the same [Future] as [onExit], except that it won't emit | 83 /// Returns the same [Future] as [onExit], except that it won't emit |
| 81 /// exceptions. | 84 /// exceptions. |
| 82 Future close() { | 85 Future close() { |
| 83 _onProcessStarted.then((_) => _process.kill()); | 86 _onProcessStarted.then((_) => _process.kill()); |
| 84 | 87 |
| 85 // Swallow exceptions. The user should explicitly use [onExit] for these. | 88 // Swallow exceptions. The user should explicitly use [onExit] for these. |
| 86 return onExit.catchError((_) {}); | 89 return onExit.catchError((_) {}); |
| 87 } | 90 } |
| 91 | |
| 92 /// Return the default executable for the current operating system. | |
| 93 String _defaultExecutable() { | |
| 94 if (Platform.isMacOS) { | |
| 95 return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'; | |
| 96 } | |
| 97 if (!Platform.isWindows) return 'google-chrome'; | |
| 98 | |
| 99 // Chrome could be installed in several places on Windows. The only way to | |
| 100 // find it is to check. | |
| 101 var prefixes = [ | |
| 102 Platform.environment['LOCALAPPDATA'], | |
| 103 Platform.environment['PROGRAMFILES'], | |
| 104 Platform.environment['PROGRAMFILES(X86)'] | |
| 105 ]; | |
| 106 var suffix = r'Google\Chrome\Application\chrome.exe'; | |
| 107 | |
| 108 for (var prefix in prefixes) { | |
| 109 if (prefix == null) continue; | |
| 110 | |
| 111 var path = p.join(prefix, suffix); | |
|
kevmoo
2015/03/05 23:10:00
spoke too soon: pkg/path is not imported here
nweiz
2015/03/06 01:38:19
Done.
| |
| 112 if (new File(p.join(prefix, suffix)).existsSync()) return path; | |
| 113 } | |
| 114 | |
| 115 // Fall back on looking it up on the path. This probably won't work, but at | |
| 116 // least it will fail with a useful error message. | |
| 117 return "chrome.exe"; | |
| 118 } | |
| 88 } | 119 } |
| OLD | NEW |