@@ -51,9 +51,12 @@ abstract class Browser {
5151 Future get onExit => _onExitCompleter.future;
5252 final _onExitCompleter = new Completer ();
5353
54+ /// Standard IO streams for the underlying browser process.
55+ final _ioSubscriptions = < StreamSubscription > [];
56+
5457 Future _drainAndIgnore (Stream s) async {
5558 try {
56- await s. drain ( );
59+ _ioSubscriptions. add (s. listen ( null , cancelOnError : true ) );
5760 } on StateError catch (_) {}
5861 }
5962
@@ -72,8 +75,8 @@ abstract class Browser {
7275 _processCompleter.complete (process);
7376
7477 // If we don't drain the stdout and stderr the process can hang.
75- await Future . wait (
76- [ _drainAndIgnore (process.stdout), _drainAndIgnore (process. stderr)] );
78+ _drainAndIgnore (process.stdout);
79+ _drainAndIgnore (process.stderr);
7780
7881 var exitCode = await process.exitCode;
7982
@@ -120,6 +123,13 @@ abstract class Browser {
120123 Future close () {
121124 _closed = true ;
122125
126+ // If we don't manually close the stream the test runner can hang.
127+ // For example this happens with Chrome Headless.
128+ // See SDK issue: https://github.com/dart-lang/sdk/issues/31264
129+ for (var stream in _ioSubscriptions) {
130+ stream.cancel ();
131+ }
132+
123133 _process.then ((process) {
124134 // Dartium has a difficult time being killed on Linux. To ensure it is
125135 // properly closed, find all children processes and kill those first.
0 commit comments