mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[ Tool ] Output app.dtd and app.devTools in machine mode (#176655)
Fixes https://github.com/flutter/flutter/issues/176310
This commit is contained in:
parent
00da9435e3
commit
c8c09f6d05
@ -17,13 +17,13 @@ A set of `flutter daemon` commands/events are also exposed via `flutter run --ma
|
||||
The daemon speaks [JSON-RPC](http://json-rpc.org/) to clients. It uses stdin and stdout as the transport protocol. To send a command to the server, create your command as a JSON-RPC message, encode it to JSON, surround the encoded text with square brackets, and write it as one line of text to the stdin of the process:
|
||||
|
||||
```json
|
||||
[{"method":"daemon.version","id":0}]
|
||||
[{ "method": "daemon.version", "id": 0 }]
|
||||
```
|
||||
|
||||
The response will come back as a single line from stdout:
|
||||
|
||||
```json
|
||||
[{"id":0,"result":"0.1.0"}]
|
||||
[{ "id": 0, "result": "0.1.0" }]
|
||||
```
|
||||
|
||||
All requests and responses should be wrapped in square brackets. This ensures that the communications are resilient to stray output in the stdout/stdin stream.
|
||||
@ -35,17 +35,42 @@ Each command should have a `method` field. This is in the form '`domain.command`
|
||||
Any params for that command should be passed in through a `params` field. Here's an example request/response for the `device.getDevices` method:
|
||||
|
||||
```json
|
||||
[{"method":"device.getDevices","id":2}]
|
||||
[{ "method": "device.getDevices", "id": 2 }]
|
||||
```
|
||||
|
||||
```json
|
||||
[{"id":2,"result":[{"id":"702ABC1F-5EA5-4F83-84AB-6380CA91D39A","name":"iPhone 6","platform":"ios_x64","available":true}]}]
|
||||
[
|
||||
{
|
||||
"id": 2,
|
||||
"result": [
|
||||
{
|
||||
"id": "702ABC1F-5EA5-4F83-84AB-6380CA91D39A",
|
||||
"name": "iPhone 6",
|
||||
"platform": "ios_x64",
|
||||
"available": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Events that come from the server will have an `event` field containing the type of event, along with a `params` field.
|
||||
|
||||
```json
|
||||
[{"event":"device.added","params":{"id":"1DD6786B-37D4-4355-AA15-B818A87A18B4","name":"iPhone XS Max","platform":"ios","emulator":true,"ephemeral":false,"platformType":"ios","category":"mobile"}}]
|
||||
[
|
||||
{
|
||||
"event": "device.added",
|
||||
"params": {
|
||||
"id": "1DD6786B-37D4-4355-AA15-B818A87A18B4",
|
||||
"name": "iPhone XS Max",
|
||||
"platform": "ios",
|
||||
"emulator": true,
|
||||
"ephemeral": false,
|
||||
"platformType": "ios",
|
||||
"category": "mobile"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Domains and Commands
|
||||
@ -75,7 +100,7 @@ The schema for each element in `reasons` is:
|
||||
- reasonText (String) - a description of why the platform is not supported
|
||||
- fixText (String) - human readable instructions of how to fix this reason
|
||||
- fixCode (String) - stringified version of the `_ReasonCode` enum. To be used
|
||||
by daemon clients who intend to auto-fix.
|
||||
by daemon clients who intend to auto-fix.
|
||||
|
||||
The possible platform types are the `PlatformType` enumeration in the lib/src/device.dart library.
|
||||
|
||||
@ -170,6 +195,17 @@ This is sent when an app is stopped or detached from. The `params` field will be
|
||||
|
||||
This is sent once a web application is being served and available for the user to access. The `params` field will be a map with a string `url` field and a boolean `launched` indicating whether the application has already been launched in a browser (this will generally be true for a browser device unless `--no-web-browser-launch` was used, and false for the headless `web-server` device).
|
||||
|
||||
#### app.devTools
|
||||
|
||||
This is sent after the [`app.debugPort`](#appdebugPort) event if DevTools is being served for this application instance. The
|
||||
`params` field will be a map with the string `uri` field containing the DevTools URI with query parameters already set to connect
|
||||
to the running application.
|
||||
|
||||
#### app.dtd
|
||||
|
||||
This is sent after the [`app.debugPort`](#appdebugPort) event if the Dart Tooling Daemon (DTD) is being served for this application
|
||||
instance. The `params` field will be a map with the string `uri` field containing the DTD URI.
|
||||
|
||||
### Daemon-to-Editor Requests
|
||||
|
||||
These requests come _from_ the Flutter daemon and should be responded to by the client/editor.
|
||||
@ -224,11 +260,11 @@ Removed a forwarded port. It takes `deviceId`, `devicePort`, and `hostPort` as r
|
||||
|
||||
#### device.added
|
||||
|
||||
This is sent when a device is connected (and polling has been enabled via `enable()`). The `params` field will be a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, and `emulator`. For more information on `platform`, `category`, `platformType`, and `ephemeral` see `device.getDevices`.
|
||||
This is sent when a device is connected (and polling has been enabled via `enable()`). The `params` field will be a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, and `emulator`. For more information on `platform`, `category`, `platformType`, and `ephemeral` see `device.getDevices`.
|
||||
|
||||
#### device.removed
|
||||
|
||||
This is sent when a device is disconnected (and polling has been enabled via `enable()`). The `params` field will be a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, and `emulator`. For more information on `platform`, `category`, `platformType`, and `ephemeral` see `device.getDevices`.
|
||||
This is sent when a device is disconnected (and polling has been enabled via `enable()`). The `params` field will be a map with the fields `id`, `name`, `platform`, `category`, `platformType`, `ephemeral`, and `emulator`. For more information on `platform`, `category`, `platformType`, and `ephemeral` see `device.getDevices`.
|
||||
|
||||
### emulator domain
|
||||
|
||||
|
||||
@ -796,15 +796,18 @@ class AppDomain extends Domain {
|
||||
// As it just writes to stdout.
|
||||
unawaited(
|
||||
connectionInfoCompleter.future.then<void>((DebugConnectionInfo info) {
|
||||
final params = <String, Object?>{
|
||||
_sendAppEvent(app, 'debugPort', {
|
||||
// The web vmservice proxy does not have an http address.
|
||||
'port': info.httpUri?.port ?? info.wsUri!.port,
|
||||
'wsUri': info.wsUri.toString(),
|
||||
};
|
||||
if (info.baseUri != null) {
|
||||
params['baseUri'] = info.baseUri;
|
||||
'baseUri': ?info.baseUri,
|
||||
});
|
||||
if (info.devToolsUri != null) {
|
||||
_sendAppEvent(app, 'devTools', {'uri': info.devToolsUri!.toString()});
|
||||
}
|
||||
if (info.dtdUri != null) {
|
||||
_sendAppEvent(app, 'dtd', {'uri': info.dtdUri!.toString()});
|
||||
}
|
||||
_sendAppEvent(app, 'debugPort', params);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
@override
|
||||
FileSystem get fileSystem => _fileSystem;
|
||||
|
||||
FlutterDevice? get device => flutterDevices.first;
|
||||
FlutterDevice? get flutterDevice => flutterDevices.first;
|
||||
final FlutterProject flutterProject;
|
||||
|
||||
// Mapping from service name to service method.
|
||||
@ -156,11 +156,11 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
/// Device is debuggable if not a WebServer device, or if running with
|
||||
/// --start-paused or using DWDS WebSocket connection (WebServer device).
|
||||
late final bool _deviceIsDebuggable =
|
||||
device!.device is! WebServerDevice ||
|
||||
flutterDevice!.device is! WebServerDevice ||
|
||||
debuggingOptions.startPaused ||
|
||||
useDwdsWebSocketConnection;
|
||||
|
||||
late final useDwdsWebSocketConnection = device!.device is! ChromiumDevice;
|
||||
late final useDwdsWebSocketConnection = flutterDevice!.device is! ChromiumDevice;
|
||||
|
||||
@override
|
||||
// Web uses a different plugin registry.
|
||||
@ -220,7 +220,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
await _extensionEventSub?.cancel();
|
||||
|
||||
if (stopAppDuringCleanup) {
|
||||
await device!.device!.stopApp(null);
|
||||
await flutterDevice!.device!.stopApp(null);
|
||||
}
|
||||
|
||||
_registeredMethodsForService.clear();
|
||||
@ -243,7 +243,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
@override
|
||||
Future<void> stopEchoingDeviceLog() async {
|
||||
// Do nothing for ResidentWebRunner
|
||||
await device!.stopEchoingDeviceLog();
|
||||
await flutterDevice!.stopEchoingDeviceLog();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -264,10 +264,10 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
final String modeName = debuggingOptions.buildInfo.mode.friendlyName;
|
||||
_logger.printStatus(
|
||||
'Launching ${getDisplayPath(target, _fileSystem)} '
|
||||
'on ${device!.device!.displayName} in $modeName mode...',
|
||||
'on ${flutterDevice!.device!.displayName} in $modeName mode...',
|
||||
);
|
||||
if (device!.device is ChromiumDevice) {
|
||||
_chromiumLauncher = (device!.device! as ChromiumDevice).chromeLauncher;
|
||||
if (flutterDevice!.device is ChromiumDevice) {
|
||||
_chromiumLauncher = (flutterDevice!.device! as ChromiumDevice).chromeLauncher;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -280,10 +280,10 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
final WebDevServerConfig updatedConfig = originalConfig.copyWith(port: resolvedPort);
|
||||
final ExpressionCompiler? expressionCompiler =
|
||||
debuggingOptions.webEnableExpressionEvaluation
|
||||
? WebExpressionCompiler(device!.generator!, fileSystem: _fileSystem)
|
||||
? WebExpressionCompiler(flutterDevice!.generator!, fileSystem: _fileSystem)
|
||||
: null;
|
||||
|
||||
device!.devFS = WebDevFS(
|
||||
flutterDevice!.devFS = WebDevFS(
|
||||
webDevServerConfig: updatedConfig,
|
||||
packagesFilePath: packagesFilePath,
|
||||
urlTunneller: _urlTunneller,
|
||||
@ -313,7 +313,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
logger: logger,
|
||||
platform: _platform,
|
||||
);
|
||||
Uri url = await device!.devFS!.create();
|
||||
Uri url = await flutterDevice!.devFS!.create();
|
||||
if (updatedConfig.https?.certKeyPath != null && updatedConfig.https?.certPath != null) {
|
||||
url = url.replace(scheme: 'https');
|
||||
}
|
||||
@ -325,7 +325,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
appFailedToStart();
|
||||
return 1;
|
||||
}
|
||||
device!.generator!.accept();
|
||||
flutterDevice!.generator!.accept();
|
||||
cacheInitialDillCompilation();
|
||||
} else {
|
||||
final webBuilder = WebBuilder(
|
||||
@ -344,15 +344,15 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
compilerConfigs: <WebCompilerConfig>[_compilerConfig],
|
||||
);
|
||||
}
|
||||
final webDevFS = device!.devFS! as WebDevFS;
|
||||
final webDevFS = flutterDevice!.devFS! as WebDevFS;
|
||||
final bool useDebugExtension =
|
||||
device!.device is WebServerDevice && debuggingOptions.startPaused;
|
||||
flutterDevice!.device is WebServerDevice && debuggingOptions.startPaused;
|
||||
// Listen for connected apps early and then await this `Future` later
|
||||
// when we attach.
|
||||
final Future<ConnectionResult?>? connectDebug = supportsServiceProtocol
|
||||
? webDevFS.connect(useDebugExtension)
|
||||
: null;
|
||||
await device!.device!.startApp(
|
||||
await flutterDevice!.device!.startApp(
|
||||
package,
|
||||
mainPath: target,
|
||||
debuggingOptions: debuggingOptions,
|
||||
@ -427,7 +427,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
}
|
||||
|
||||
final String targetPlatform = getNameForTargetPlatform(TargetPlatform.web_javascript);
|
||||
final String sdkName = await device!.device!.sdkNameAndVersion;
|
||||
final String sdkName = await flutterDevice!.device!.sdkNameAndVersion;
|
||||
|
||||
// Will be null if there is no report.
|
||||
final UpdateFSReport? report;
|
||||
@ -437,10 +437,10 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
// wasteful.
|
||||
report = await _updateDevFS(fullRestart: fullRestart, resetCompiler: false);
|
||||
if (report.success) {
|
||||
device!.generator!.accept();
|
||||
flutterDevice!.generator!.accept();
|
||||
} else {
|
||||
status.stop();
|
||||
await device!.generator!.reject();
|
||||
await flutterDevice!.generator!.reject();
|
||||
if (report.hotReloadRejected) {
|
||||
// We cannot capture the reason why the reload was rejected as it may
|
||||
// contain user information.
|
||||
@ -725,16 +725,17 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
}
|
||||
}
|
||||
final InvalidationResult invalidationResult = await projectFileInvalidator.findInvalidated(
|
||||
lastCompiled: device!.devFS!.lastCompiled,
|
||||
urisToMonitor: device!.devFS!.sources,
|
||||
lastCompiled: flutterDevice!.devFS!.lastCompiled,
|
||||
urisToMonitor: flutterDevice!.devFS!.sources,
|
||||
packagesPath: packagesFilePath,
|
||||
packageConfig: device!.devFS!.lastPackageConfig ?? debuggingOptions.buildInfo.packageConfig,
|
||||
packageConfig:
|
||||
flutterDevice!.devFS!.lastPackageConfig ?? debuggingOptions.buildInfo.packageConfig,
|
||||
);
|
||||
final Status devFSStatus = _logger.startProgress(
|
||||
'Waiting for connection from debug service on '
|
||||
'${device!.device!.displayName}...',
|
||||
'${flutterDevice!.device!.displayName}...',
|
||||
);
|
||||
final UpdateFSReport report = await device!.devFS!.update(
|
||||
final UpdateFSReport report = await flutterDevice!.devFS!.update(
|
||||
mainUri: await _generateEntrypoint(
|
||||
_fileSystem.file(mainPath).absolute.uri,
|
||||
invalidationResult.packageConfig,
|
||||
@ -742,7 +743,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
target: target,
|
||||
bundle: assetBundle,
|
||||
bundleFirstUpload: isFirstUpload,
|
||||
generator: device!.generator!,
|
||||
generator: flutterDevice!.generator!,
|
||||
fullRestart: fullRestart,
|
||||
resetCompiler: resetCompiler,
|
||||
dillOutputPath: dillOutputPath,
|
||||
@ -750,7 +751,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
invalidatedFiles: invalidationResult.uris!,
|
||||
packageConfig: invalidationResult.packageConfig!,
|
||||
trackWidgetCreation: debuggingOptions.buildInfo.trackWidgetCreation,
|
||||
shaderCompiler: device!.developmentShaderCompiler,
|
||||
shaderCompiler: flutterDevice!.developmentShaderCompiler,
|
||||
);
|
||||
devFSStatus.stop();
|
||||
_logger.printTrace('Synced ${getSizeAsPlatformMB(report.syncedBytes)}.');
|
||||
@ -841,20 +842,23 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
// It is safe to ignore this error because we expect an error to be
|
||||
// thrown if we're not already subscribed.
|
||||
}
|
||||
final Device device = flutterDevice!.device!;
|
||||
await setUpVmService(
|
||||
reloadSources: (String isolateId, {bool? force, bool? pause}) async {
|
||||
await restart(pause: pause);
|
||||
},
|
||||
device: device!.device,
|
||||
device: device,
|
||||
flutterProject: flutterProject,
|
||||
printStructuredErrorLogMethod: printStructuredErrorLog,
|
||||
vmService: _vmService.service,
|
||||
);
|
||||
|
||||
final Uri websocketUri = Uri.parse(debugConnection.uri);
|
||||
device!.vmService = _vmService;
|
||||
flutterDevice!.vmService = _vmService;
|
||||
if (debugConnection.devToolsUri != null) {
|
||||
(device!.device! as WebDevice).devToolsUri = Uri.parse(debugConnection.devToolsUri!);
|
||||
(flutterDevice!.device! as WebDevice).devToolsUri = Uri.parse(
|
||||
debugConnection.devToolsUri!,
|
||||
);
|
||||
}
|
||||
|
||||
// Run main immediately if the app is not started paused or if there
|
||||
@ -881,7 +885,13 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
// service message instead.
|
||||
_logger.printStatus('Debug service listening on $websocketUri');
|
||||
printDebuggerList();
|
||||
connectionInfoCompleter?.complete(DebugConnectionInfo(wsUri: websocketUri));
|
||||
connectionInfoCompleter?.complete(
|
||||
DebugConnectionInfo(
|
||||
wsUri: websocketUri,
|
||||
devToolsUri: Uri.tryParse(debugConnection.devToolsUri ?? ''),
|
||||
// TODO(bkonyi): surface DTD URI once it's visible from DWDS
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
@ -902,7 +912,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
@override
|
||||
Future<void> exitApp() async {
|
||||
if (stopAppDuringCleanup) {
|
||||
await device!.exitApps();
|
||||
await flutterDevice!.exitApps();
|
||||
}
|
||||
appFinished();
|
||||
}
|
||||
|
||||
@ -1867,11 +1867,14 @@ class TerminalHandler {
|
||||
}
|
||||
|
||||
class DebugConnectionInfo {
|
||||
DebugConnectionInfo({this.httpUri, this.wsUri, this.baseUri});
|
||||
DebugConnectionInfo({this.httpUri, this.wsUri, this.baseUri, this.dtdUri, this.devToolsUri});
|
||||
|
||||
final Uri? httpUri;
|
||||
final Uri? wsUri;
|
||||
final String? baseUri;
|
||||
|
||||
final Uri? dtdUri;
|
||||
final Uri? devToolsUri;
|
||||
}
|
||||
|
||||
/// Returns the next platform value for the switcher.
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'base/dds.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/logger.dart';
|
||||
import 'build_info.dart';
|
||||
@ -75,12 +76,17 @@ class ColdRunner extends ResidentRunner {
|
||||
}
|
||||
}
|
||||
|
||||
if (flutterDevices.first.vmServiceUris != null) {
|
||||
final FlutterDevice flutterDevice = flutterDevices.first;
|
||||
if (flutterDevice.vmServiceUris != null) {
|
||||
final FlutterVmService? vmService = flutterDevice.vmService;
|
||||
final DartDevelopmentService dds = flutterDevice.device!.dds;
|
||||
// For now, only support one debugger connection.
|
||||
connectionInfoCompleter?.complete(
|
||||
DebugConnectionInfo(
|
||||
httpUri: flutterDevices.first.vmService!.httpAddress,
|
||||
wsUri: flutterDevices.first.vmService!.wsAddress,
|
||||
httpUri: vmService!.httpAddress,
|
||||
wsUri: vmService.wsAddress,
|
||||
devToolsUri: dds.devToolsUri,
|
||||
dtdUri: dds.dtdUri,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import 'package:unified_analytics/unified_analytics.dart';
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import 'base/context.dart';
|
||||
import 'base/dds.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/logger.dart';
|
||||
import 'base/platform.dart';
|
||||
@ -278,12 +279,16 @@ class HotRunner extends ResidentRunner {
|
||||
try {
|
||||
final List<Uri?> baseUris = await _initDevFS();
|
||||
if (connectionInfoCompleter != null) {
|
||||
final FlutterVmService vmService = flutterDevices.first.vmService!;
|
||||
final DartDevelopmentService dds = flutterDevices.first.device!.dds;
|
||||
// Only handle one debugger connection.
|
||||
connectionInfoCompleter.complete(
|
||||
DebugConnectionInfo(
|
||||
httpUri: flutterDevices.first.vmService!.httpAddress,
|
||||
wsUri: flutterDevices.first.vmService!.wsAddress,
|
||||
httpUri: vmService.httpAddress,
|
||||
wsUri: vmService.wsAddress,
|
||||
baseUri: baseUris.first.toString(),
|
||||
devToolsUri: dds.devToolsUri,
|
||||
dtdUri: dds.dtdUri,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/dds.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
@ -210,6 +211,9 @@ class FakeDevice extends Fake implements Device {
|
||||
@override
|
||||
Future<TargetPlatform> get targetPlatform async => TargetPlatform.tester;
|
||||
|
||||
@override
|
||||
DartDevelopmentService get dds => FakeDartDevelopmentService();
|
||||
|
||||
var wasDisposed = false;
|
||||
|
||||
@override
|
||||
@ -218,6 +222,36 @@ class FakeDevice extends Fake implements Device {
|
||||
}
|
||||
}
|
||||
|
||||
class FakeDartDevelopmentService extends Fake implements DartDevelopmentService {
|
||||
@override
|
||||
late Future<void> done;
|
||||
|
||||
@override
|
||||
Uri? uri;
|
||||
|
||||
@override
|
||||
Uri? devToolsUri;
|
||||
|
||||
@override
|
||||
Uri? dtdUri;
|
||||
|
||||
@override
|
||||
Future<void> startDartDevelopmentService(
|
||||
Uri vmServiceUri, {
|
||||
int? ddsPort,
|
||||
FlutterDevice? device,
|
||||
bool? ipv6,
|
||||
bool? disableServiceAuthCodes,
|
||||
bool enableDevTools = false,
|
||||
bool cacheStartupProfile = false,
|
||||
String? google3WorkspaceRoot,
|
||||
Uri? devToolsServerAddress,
|
||||
}) async {}
|
||||
|
||||
@override
|
||||
Future<void> shutdown() async {}
|
||||
}
|
||||
|
||||
class TestFlutterDevice extends FlutterDevice {
|
||||
TestFlutterDevice({
|
||||
required Device device,
|
||||
|
||||
@ -52,6 +52,18 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWithoutContext('flutter run outputs DTD and DevTools events', () async {
|
||||
await flutter.run(startPaused: true, withDebugger: true);
|
||||
expect(flutter.devToolsUri, isNotNull);
|
||||
expect(flutter.dtdUri, isNotNull);
|
||||
});
|
||||
|
||||
testWithoutContext('flutter run does not output DTD and DevTools events', () async {
|
||||
await flutter.run(startPaused: true, withDebugger: true, noDevtools: true);
|
||||
expect(flutter.devToolsUri, isNull);
|
||||
expect(flutter.dtdUri, isNull);
|
||||
});
|
||||
|
||||
testWithoutContext('sets activeDevToolsServerAddress extension', () async {
|
||||
await flutter.run(
|
||||
startPaused: true,
|
||||
|
||||
@ -52,6 +52,8 @@ abstract final class FlutterTestDriver {
|
||||
final _errorBuffer = StringBuffer();
|
||||
String? _lastResponse;
|
||||
Uri? _vmServiceWsUri;
|
||||
Uri? _devToolsUri;
|
||||
Uri? _dtdUri;
|
||||
int? _attachPort;
|
||||
var _hasExited = false;
|
||||
|
||||
@ -62,6 +64,8 @@ abstract final class FlutterTestDriver {
|
||||
int? get vmServicePort => _vmServiceWsUri?.port;
|
||||
bool get hasExited => _hasExited;
|
||||
Uri? get vmServiceWsUri => _vmServiceWsUri;
|
||||
Uri? get devToolsUri => _devToolsUri;
|
||||
Uri? get dtdUri => _dtdUri;
|
||||
|
||||
/// Completes with the full method name for the 'reloadSources' service once
|
||||
/// it's registered (e.g., `s0.reloadSources`).
|
||||
@ -602,8 +606,14 @@ final class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
...?additionalCommandArgs,
|
||||
],
|
||||
withDebugger: withDebugger,
|
||||
withDevtools: !noDevtools,
|
||||
startPaused: startPaused,
|
||||
waitForDebugPort: device != WebServerDevice.kWebServerDeviceId && !wasm,
|
||||
waitForDtdAndDevTools:
|
||||
device != WebServerDevice.kWebServerDeviceId &&
|
||||
device != GoogleChromeDevice.kChromeDeviceId &&
|
||||
!noDevtools &&
|
||||
spawnDdsInstance,
|
||||
pauseOnExceptions: pauseOnExceptions,
|
||||
script: script,
|
||||
verbose: verbose,
|
||||
@ -642,9 +652,11 @@ final class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
List<String> args, {
|
||||
String? script,
|
||||
bool withDebugger = false,
|
||||
bool withDevtools = false,
|
||||
bool startPaused = false,
|
||||
bool pauseOnExceptions = false,
|
||||
bool waitForDebugPort = false,
|
||||
bool waitForDtdAndDevTools = true,
|
||||
bool verbose = false,
|
||||
int? attachPort,
|
||||
}) async {
|
||||
@ -685,11 +697,30 @@ final class FlutterRunTestDriver extends FlutterTestDriver {
|
||||
event: 'app.started',
|
||||
timeout: appStartTimeout,
|
||||
);
|
||||
final Future<void> devTools =
|
||||
_waitFor(
|
||||
event: 'app.devTools',
|
||||
timeout: appStartTimeout,
|
||||
ignoreAppStopEvent: true,
|
||||
).then((event) async {
|
||||
_devToolsUri = Uri.parse(
|
||||
(event['params']! as Map<String, Object?>)['uri']! as String,
|
||||
);
|
||||
});
|
||||
final Future<void> dtd =
|
||||
_waitFor(event: 'app.dtd', timeout: appStartTimeout, ignoreAppStopEvent: true).then((
|
||||
event,
|
||||
) {
|
||||
_dtdUri = Uri.parse((event['params']! as Map<String, Object?>)['uri']! as String);
|
||||
});
|
||||
|
||||
late final Map<String, Object?> debugPort;
|
||||
if (waitForDebugPort || withDebugger || attachPort != null) {
|
||||
debugPort = await _waitFor(event: 'app.debugPort', timeout: appStartTimeout);
|
||||
}
|
||||
if (withDebugger && waitForDtdAndDevTools) {
|
||||
await Future.wait([devTools, dtd]);
|
||||
}
|
||||
if (withDebugger || attachPort != null) {
|
||||
final wsUriString = (debugPort['params']! as Map<String, Object?>)['wsUri']! as String;
|
||||
_vmServiceWsUri = Uri.parse(wsUriString);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user