Serve DevTools when running flutter test (#123607)

Also clean up messaging output by `flutter test` when `--start-paused` is provided.
This commit is contained in:
Ben Konyi 2023-03-30 11:51:08 -04:00 committed by GitHub
parent 302c087738
commit c3de901538
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 6 deletions

View file

@ -21,6 +21,7 @@ import '../convert.dart';
import '../device.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../resident_runner.dart';
import '../vmservice.dart';
import 'font_config_manager.dart';
@ -72,6 +73,7 @@ class FlutterTesterTestDevice extends TestDevice {
Process? _process;
HttpServer? _server;
DevtoolsLauncher? _devToolsLauncher;
/// Starts the device.
///
@ -163,9 +165,11 @@ class FlutterTesterTestDevice extends TestDevice {
debuggingOptions.hostVmServicePort == detectedUri.port);
Uri? forwardingUri;
DartDevelopmentService? dds;
if (debuggingOptions.enableDds) {
logger.printTrace('test $id: Starting Dart Development Service');
final DartDevelopmentService dds = await startDds(
dds = await startDds(
detectedUri,
uriConverter: uriConverter,
);
@ -193,10 +197,10 @@ class FlutterTesterTestDevice extends TestDevice {
}));
if (debuggingOptions.startPaused && !machine!) {
logger.printStatus('The test process has been started.');
logger.printStatus('You can now connect to it using vmService. To connect, load the following Web site in your browser:');
logger.printStatus(' $forwardingUri');
logger.printStatus('You should first set appropriate breakpoints, then resume the test in the debugger.');
logger.printStatus('The Dart VM service is listening on $forwardingUri');
await _startDevTools(forwardingUri, dds);
logger.printStatus('');
logger.printStatus('The test process has been started. Set any relevant breakpoints and then resume the test in the debugger.');
}
_gotProcessVmServiceUri.complete(forwardingUri);
},
@ -215,6 +219,9 @@ class FlutterTesterTestDevice extends TestDevice {
logger.printTrace('test $id: Terminating flutter_tester process');
_process?.kill(io.ProcessSignal.sigkill);
logger.printTrace('test $id: Shutting down DevTools server');
await _devToolsLauncher?.close();
logger.printTrace('test $id: Shutting down test harness socket server');
await _server?.close(force: true);
await finished;
@ -261,6 +268,29 @@ class FlutterTesterTestDevice extends TestDevice {
);
}
Future<void> _startDevTools(Uri forwardingUri, DartDevelopmentService? dds) async {
_devToolsLauncher = DevtoolsLauncher.instance;
logger.printTrace('test $id: Serving DevTools...');
final DevToolsServerAddress? devToolsServerAddress = await _devToolsLauncher?.serve();
if (devToolsServerAddress == null) {
logger.printTrace('test $id: Failed to start DevTools');
return;
}
await _devToolsLauncher?.ready;
logger.printTrace('test $id: DevTools is being served at ${devToolsServerAddress.uri}');
// Notify the DDS instance that there's a DevTools instance available so it can correctly
// redirect DevTools related requests.
dds?.setExternalDevToolsUri(devToolsServerAddress.uri!);
final Uri devToolsUri = devToolsServerAddress.uri!.replace(
// Use query instead of queryParameters to avoid unnecessary encoding.
query: 'uri=$forwardingUri',
);
logger.printStatus('The Flutter DevTools debugger and profiler is available at: $devToolsUri');
}
/// Binds an [HttpServer] serving from `host` on `port`.
///
/// Only intended to be overridden in tests.

View file

@ -222,7 +222,7 @@ void main() {
final Completer<Uri> completer = Completer<Uri>();
final RegExp vmServiceUriRegExp = RegExp(r'((http)?:\/\/)[^\s]+');
sub = process.stdout.transform(utf8.decoder).listen((String e) {
if (vmServiceUriRegExp.hasMatch(e)) {
if (!completer.isCompleted && vmServiceUriRegExp.hasMatch(e)) {
completer.complete(Uri.parse(vmServiceUriRegExp.firstMatch(e)!.group(0)!));
}
});
@ -237,6 +237,31 @@ void main() {
process.kill();
}
});
testWithoutContext('flutter test should serve DevTools', () async {
late final Process process;
late final StreamSubscription<String> sub;
try {
process = await _runFlutterTestConcurrent('trivial', automatedTestsDirectory, flutterTestDirectory,
extraArguments: const <String>['--start-paused']);
final Completer<Uri> completer = Completer<Uri>();
final RegExp devToolsUriRegExp = RegExp(r'The Flutter DevTools debugger and profiler is available at: (http://[^\s]+)');
sub = process.stdout.transform(utf8.decoder).listen((String e) {
if (!completer.isCompleted && devToolsUriRegExp.hasMatch(e)) {
completer.complete(Uri.parse(devToolsUriRegExp.firstMatch(e)!.group(1)!));
}
});
final Uri devToolsUri = await completer.future;
final HttpClient client = HttpClient();
final HttpClientRequest request = await client.getUrl(devToolsUri);
final HttpClientResponse response = await request.close();
final String content = await response.transform(utf8.decoder).join();
expect(content.contains('DevTools'), true);
} finally {
await sub.cancel();
process.kill();
}
});
}
Future<void> _testFile(