Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2891)

Unified Diff: lib/src/runner/browser/content_shell.dart

Issue 1257953008: Expose content shell's remote debugging URL. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/runner/browser/browser_manager.dart ('k') | lib/src/runner/environment.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/runner/browser/content_shell.dart
diff --git a/lib/src/runner/browser/content_shell.dart b/lib/src/runner/browser/content_shell.dart
index 77ff14926ad9071be1f61ce398be922395b28043..acab425e7baa71cd494fb1be0ea90a58a57907a4 100644
--- a/lib/src/runner/browser/content_shell.dart
+++ b/lib/src/runner/browser/content_shell.dart
@@ -5,8 +5,10 @@
library test.runner.browser.content_shell;
import 'dart:async';
+import 'dart:convert';
import 'dart:io';
+import '../../util/io.dart';
import '../../utils.dart';
import '../application_exception.dart';
import 'browser.dart';
@@ -25,43 +27,97 @@ class ContentShell extends Browser {
final Future<Uri> observatoryUrl;
+ final Future<Uri> remoteDebuggerUrl;
+
factory ContentShell(url, {String executable, bool debug: false}) {
- var completer = new Completer.sync();
- return new ContentShell._(() async {
+ var observatoryCompleter = new Completer.sync();
+ var remoteDebuggerCompleter = new Completer.sync();
+ return new ContentShell._(() {
if (executable == null) executable = _defaultExecutable();
- var process = await Process.start(
- executable, ["--dump-render-tree", url.toString()],
- environment: {"DART_FLAGS": "--checked"});
-
- if (debug) {
- completer.complete(lineSplitter.bind(process.stdout).map((line) {
- var match = _observatoryRegExp.firstMatch(line);
- if (match == null) return null;
- return Uri.parse(match[1]);
- }).where((uri) => uri != null).first);
- } else {
- completer.complete(null);
+ tryPort([port]) async {
+ var args = ["--dump-render-tree", url.toString()];
+ if (port != null) args.add("--remote-debugging-port=$port");
+
+ var process = await Process.start(executable, args,
+ environment: {"DART_FLAGS": "--checked"});
+
+ if (debug) {
+ observatoryCompleter.complete(lineSplitter.bind(process.stdout)
+ .map((line) {
+ var match = _observatoryRegExp.firstMatch(line);
+ if (match == null) return null;
+ return Uri.parse(match[1]);
+ }).where((uri) => uri != null).first);
+ } else {
+ observatoryCompleter.complete(null);
+ }
+
+ var stderr = new StreamIterator(lineSplitter.bind(process.stderr));
+
+ // Before we can consider content_shell started successfully, we have to
+ // make sure it's not expired and that the remote debugging port worked.
+ // Any errors from this will always come before the "Running without
+ // renderer sanxbox" message.
+ while (await stderr.moveNext() &&
+ !stderr.current.endsWith("Running without renderer sandbox")) {
+ if (stderr.current == "[dartToStderr]: Dartium build has expired") {
+ stderr.cancel();
+ process.kill();
+ // TODO(nweiz): link to dartlang.org once it has download links for
+ // content shell
+ // (https://github.com/dart-lang/www.dartlang.org/issues/1164).
+ throw new ApplicationException(
+ "You're using an expired content_shell. Upgrade to the latest "
+ "version:\n"
+ "http://gsdview.appspot.com/dart-archive/channels/stable/"
+ "release/latest/dartium/");
+ } else if (stderr.current.contains("bind() returned an error")) {
+ // If we failed to bind to the port, return null to tell
+ // getUnusedPort to try another one.
+ stderr.cancel();
+ process.kill();
+ return null;
+ }
+ }
+
+ if (port != null) {
+ remoteDebuggerCompleter.complete(
+ _getRemoteDebuggerUrl(Uri.parse("http://localhost:$port")));
+ } else {
+ remoteDebuggerCompleter.complete(null);
+ }
+
+ stderr.cancel();
+ return process;
}
- lineSplitter.bind(process.stderr).listen((line) {
- if (line != "[dartToStderr]: Dartium build has expired") return;
-
- // TODO(nweiz): link to dartlang.org once it has download links for
- // content shell
- // (https://github.com/dart-lang/www.dartlang.org/issues/1164).
- throw new ApplicationException(
- "You're using an expired content_shell. Upgrade to the latest "
- "version:\n"
- "http://gsdview.appspot.com/dart-archive/channels/stable/release/"
- "latest/dartium/");
- });
-
- return process;
- }, completer.future);
+ if (!debug) return tryPort();
+ return getUnusedPort(tryPort);
+ }, observatoryCompleter.future, remoteDebuggerCompleter.future);
+ }
+
+ /// Returns the full URL of the remote debugger for the host page.
+ ///
+ /// This takes the base remote debugger URL (which points to a browser-wide
+ /// page) and uses its JSON API to find the resolved URL for debugging the
+ /// host page.
+ static Future<Uri> _getRemoteDebuggerUrl(Uri base) async {
+ try {
+ var client = new HttpClient();
+ var request = await client.getUrl(base.resolve("/json/list"));
+ var response = await request.close();
+ var json = await JSON.fuse(UTF8).decoder.bind(response).single;
+ return base.resolve(json.first["devtoolsFrontendUrl"]);
+ } catch (_) {
+ // If we fail to talk to the remote debugger protocol, give up and return
+ // the raw URL rather than crashing.
+ return base;
+ }
}
- ContentShell._(Future<Process> startBrowser(), this.observatoryUrl)
+ ContentShell._(Future<Process> startBrowser(), this.observatoryUrl,
+ this.remoteDebuggerUrl)
: super(startBrowser);
/// Return the default executable for the current operating system.
« no previous file with comments | « lib/src/runner/browser/browser_manager.dart ('k') | lib/src/runner/environment.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698