[ Web ] Register service extensions with DDS, not DWDS (#79479)
This commit is contained in:
parent
437e32b9cf
commit
75a44a29ad
@ -17,6 +17,7 @@ import 'package:mime/mime.dart' as mime;
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:shelf/shelf.dart' as shelf;
|
||||
import 'package:shelf/shelf_io.dart' as shelf;
|
||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../asset.dart';
|
||||
@ -35,6 +36,7 @@ import '../dart/package_map.dart';
|
||||
import '../devfs.dart';
|
||||
import '../globals.dart' as globals;
|
||||
import '../project.dart';
|
||||
import '../vmservice.dart';
|
||||
import '../web/bootstrap.dart';
|
||||
import '../web/chrome.dart';
|
||||
import '../web/compile.dart';
|
||||
@ -592,10 +594,11 @@ class WebAssetServer implements AssetReader {
|
||||
}
|
||||
|
||||
class ConnectionResult {
|
||||
ConnectionResult(this.appConnection, this.debugConnection);
|
||||
ConnectionResult(this.appConnection, this.debugConnection, this.vmService);
|
||||
|
||||
final AppConnection appConnection;
|
||||
final DebugConnection debugConnection;
|
||||
final vm_service.VmService vmService;
|
||||
}
|
||||
|
||||
/// The web specific DevFS implementation.
|
||||
@ -665,8 +668,12 @@ class WebDevFS implements DevFS {
|
||||
if (firstConnection.isCompleted) {
|
||||
appConnection.runMain();
|
||||
} else {
|
||||
final vm_service.VmService vmService = await createVmServiceDelegate(
|
||||
Uri.parse(debugConnection.uri),
|
||||
logger: globals.logger,
|
||||
);
|
||||
firstConnection
|
||||
.complete(ConnectionResult(appConnection, debugConnection));
|
||||
.complete(ConnectionResult(appConnection, debugConnection, vmService));
|
||||
}
|
||||
} on Exception catch (error, stackTrace) {
|
||||
if (!firstConnection.isCompleted) {
|
||||
|
@ -155,7 +155,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
if (_instance != null) {
|
||||
return _instance;
|
||||
}
|
||||
final vmservice.VmService service =_connectionResult?.debugConnection?.vmService;
|
||||
final vmservice.VmService service =_connectionResult?.vmService;
|
||||
final Uri websocketUri = Uri.parse(_connectionResult.debugConnection.uri);
|
||||
final Uri httpUri = _httpUriFromWebsocketUri(websocketUri);
|
||||
return _instance ??= FlutterVmService(service, wsAddress: websocketUri, httpAddress: httpUri);
|
||||
@ -835,7 +835,7 @@ class ResidentWebRunner extends ResidentRunner {
|
||||
_connectionResult.appConnection.runMain();
|
||||
} else {
|
||||
StreamSubscription<void> resumeSub;
|
||||
resumeSub = _connectionResult.debugConnection.vmService.onDebugEvent
|
||||
resumeSub = _vmService.service.onDebugEvent
|
||||
.listen((vmservice.Event event) {
|
||||
if (event.type == vmservice.EventKind.kResume) {
|
||||
_connectionResult.appConnection.runMain();
|
||||
|
@ -326,6 +326,22 @@ Future<FlutterVmService> connectToVmService(
|
||||
);
|
||||
}
|
||||
|
||||
Future<vm_service.VmService> createVmServiceDelegate(
|
||||
Uri wsUri, {
|
||||
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
|
||||
@required Logger logger,
|
||||
}) async {
|
||||
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression, logger: logger);
|
||||
return vm_service.VmService(
|
||||
channel,
|
||||
channel.add,
|
||||
log: null,
|
||||
disposeHandler: () async {
|
||||
await channel.close();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<FlutterVmService> _connect(
|
||||
Uri httpUri, {
|
||||
ReloadSources reloadSources,
|
||||
@ -338,14 +354,8 @@ Future<FlutterVmService> _connect(
|
||||
@required Logger logger,
|
||||
}) async {
|
||||
final Uri wsUri = httpUri.replace(scheme: 'ws', path: urlContext.join(httpUri.path, 'ws'));
|
||||
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression, logger: logger);
|
||||
final vm_service.VmService delegateService = vm_service.VmService(
|
||||
channel,
|
||||
channel.add,
|
||||
log: null,
|
||||
disposeHandler: () async {
|
||||
await channel.close();
|
||||
},
|
||||
final vm_service.VmService delegateService = await createVmServiceDelegate(
|
||||
wsUri, compression: compression, logger: logger,
|
||||
);
|
||||
|
||||
final vm_service.VmService service = await setUpVmService(
|
||||
|
@ -130,7 +130,11 @@ void main() {
|
||||
when(mockFlutterDevice.devFS).thenReturn(mockWebDevFS);
|
||||
when(mockFlutterDevice.device).thenReturn(mockDevice);
|
||||
when(mockWebDevFS.connect(any)).thenAnswer((Invocation invocation) async {
|
||||
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
||||
return ConnectionResult(
|
||||
mockAppConnection,
|
||||
mockDebugConnection,
|
||||
mockDebugConnection.vmService,
|
||||
);
|
||||
});
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
});
|
||||
|
@ -63,6 +63,7 @@ abstract class FlutterTestDriver {
|
||||
Stream<String> get stdout => _stdout.stream;
|
||||
int get vmServicePort => _vmServiceWsUri.port;
|
||||
bool get hasExited => _hasExited;
|
||||
Uri get vmServiceWsUri => _vmServiceWsUri;
|
||||
|
||||
String lastTime = '';
|
||||
void _debugPrint(String message, { String topic = '' }) {
|
||||
@ -219,7 +220,7 @@ abstract class FlutterTestDriver {
|
||||
return _flutterIsolateId;
|
||||
}
|
||||
|
||||
Future<Isolate> _getFlutterIsolate() async {
|
||||
Future<Isolate> getFlutterIsolate() async {
|
||||
final Isolate isolate = await _vmService.getIsolate(await _getFlutterIsolateId());
|
||||
return isolate;
|
||||
}
|
||||
@ -281,7 +282,7 @@ abstract class FlutterTestDriver {
|
||||
// Cancel the subscription on either of the above.
|
||||
await pauseSubscription.cancel();
|
||||
|
||||
return _getFlutterIsolate();
|
||||
return getFlutterIsolate();
|
||||
},
|
||||
task: 'Waiting for isolate to pause',
|
||||
);
|
||||
@ -294,7 +295,7 @@ abstract class FlutterTestDriver {
|
||||
Future<Isolate> stepOut({ bool waitForNextPause = true }) => _resume(StepOption.kOut, waitForNextPause);
|
||||
|
||||
Future<bool> isAtAsyncSuspension() async {
|
||||
final Isolate isolate = await _getFlutterIsolate();
|
||||
final Isolate isolate = await getFlutterIsolate();
|
||||
return isolate.pauseEvent.atAsyncSuspension == true;
|
||||
}
|
||||
|
||||
|
@ -13,160 +13,163 @@ import '../integration.shard/test_driver.dart';
|
||||
import '../integration.shard/test_utils.dart';
|
||||
import '../src/common.dart';
|
||||
|
||||
void batch1() {
|
||||
final BasicProject _project = BasicProject();
|
||||
Directory tempDir;
|
||||
FlutterRunTestDriver _flutter;
|
||||
void main() {
|
||||
group('Flutter run for web', () {
|
||||
final BasicProject project = BasicProject();
|
||||
Directory tempDir;
|
||||
FlutterRunTestDriver flutter;
|
||||
|
||||
Future<void> initProject() async {
|
||||
tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
|
||||
await _project.setUpIn(tempDir);
|
||||
_flutter = FlutterRunTestDriver(tempDir);
|
||||
}
|
||||
setUp(() async {
|
||||
tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
|
||||
await project.setUpIn(tempDir);
|
||||
flutter = FlutterRunTestDriver(tempDir);
|
||||
});
|
||||
|
||||
Future<void> cleanProject() async {
|
||||
await _flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
}
|
||||
tearDown(() async {
|
||||
await flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
Future<void> start({bool expressionEvaluation}) {
|
||||
// The non-test project has a loop around its breakpoints.
|
||||
// No need to start paused as all breakpoint would be eventually reached.
|
||||
return _flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
expressionEvaluation: expressionEvaluation,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
}
|
||||
Future<void> start({bool expressionEvaluation}) async {
|
||||
// The non-test project has a loop around its breakpoints.
|
||||
// No need to start paused as all breakpoint would be eventually reached.
|
||||
await flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
expressionEvaluation: expressionEvaluation,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
}
|
||||
|
||||
Future<void> breakInBuildMethod(FlutterTestDriver flutter) async {
|
||||
await _flutter.breakAt(
|
||||
_project.buildMethodBreakpointUri,
|
||||
_project.buildMethodBreakpointLine,
|
||||
);
|
||||
}
|
||||
Future<void> breakInBuildMethod(FlutterTestDriver flutter) async {
|
||||
await flutter.breakAt(
|
||||
project.buildMethodBreakpointUri,
|
||||
project.buildMethodBreakpointLine,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> breakInTopLevelFunction(FlutterTestDriver flutter) async {
|
||||
await _flutter.breakAt(
|
||||
_project.topLevelFunctionBreakpointUri,
|
||||
_project.topLevelFunctionBreakpointLine,
|
||||
);
|
||||
}
|
||||
Future<void> breakInTopLevelFunction(FlutterTestDriver flutter) async {
|
||||
await flutter.breakAt(
|
||||
project.topLevelFunctionBreakpointUri,
|
||||
project.topLevelFunctionBreakpointLine,
|
||||
);
|
||||
}
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - error if expression evaluation disabled', () async {
|
||||
await initProject();
|
||||
await start(expressionEvaluation: false);
|
||||
await breakInTopLevelFunction(_flutter);
|
||||
await failToEvaluateExpression(_flutter);
|
||||
await cleanProject();
|
||||
testWithoutContext('cannot evaluate expression if feature is disabled', () async {
|
||||
await start(expressionEvaluation: false);
|
||||
await breakInTopLevelFunction(flutter);
|
||||
await failToEvaluateExpression(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('shows no native javascript objects in static scope', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(flutter);
|
||||
await checkStaticScope(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can handle compilation errors', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(flutter);
|
||||
await evaluateErrorExpressions(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can evaluate trivial expressions in top level function', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(flutter);
|
||||
await evaluateTrivialExpressions(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can evaluate trivial expressions in build method', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInBuildMethod(flutter);
|
||||
await evaluateTrivialExpressions(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can evaluate complex expressions in top level function', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(flutter);
|
||||
await evaluateComplexExpressions(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can evaluate complex expressions in build method', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInBuildMethod(flutter);
|
||||
await evaluateComplexExpressions(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can evaluate trivial expressions in library without pause', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await evaluateTrivialExpressionsInLibrary(flutter);
|
||||
});
|
||||
|
||||
testWithoutContext('can evaluate complex expressions in library without pause', () async {
|
||||
await start(expressionEvaluation: true);
|
||||
await evaluateComplexExpressionsInLibrary(flutter);
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - no native javascript objects in static scope', () async {
|
||||
await initProject();
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(_flutter);
|
||||
await checkStaticScope(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - can handle compilation errors', () async {
|
||||
await initProject();
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(_flutter);
|
||||
await evaluateErrorExpressions(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
group('Flutter test for web', () {
|
||||
final TestsProject project = TestsProject();
|
||||
Directory tempDir;
|
||||
FlutterRunTestDriver flutter;
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - can evaluate trivial expressions in top level function', () async {
|
||||
await initProject();
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(_flutter);
|
||||
await evaluateTrivialExpressions(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
setUp(() async {
|
||||
tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
|
||||
await project.setUpIn(tempDir);
|
||||
flutter = FlutterRunTestDriver(tempDir);
|
||||
});
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - can evaluate trivial expressions in build method', () async {
|
||||
await initProject();
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInBuildMethod(_flutter);
|
||||
await evaluateTrivialExpressions(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
tearDown(() async {
|
||||
await flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - can evaluate complex expressions in top level function', () async {
|
||||
await initProject();
|
||||
await start(expressionEvaluation: true);
|
||||
await breakInTopLevelFunction(_flutter);
|
||||
await evaluateComplexExpressions(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
Future<Isolate> breakInMethod(FlutterTestDriver flutter) async {
|
||||
await flutter.addBreakpoint(
|
||||
project.breakpointAppUri,
|
||||
project.breakpointLine,
|
||||
);
|
||||
await flutter.resume();
|
||||
return flutter.waitForPause();
|
||||
}
|
||||
|
||||
testWithoutContext('flutter run expression evaluation - can evaluate complex expressions in build method', () async {
|
||||
await initProject();
|
||||
await _flutter.run(withDebugger: true, chrome: true);
|
||||
await breakInBuildMethod(_flutter);
|
||||
await evaluateComplexExpressions(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
}
|
||||
Future<void> startPaused({bool expressionEvaluation}) {
|
||||
// The test project does not have a loop around its breakpoints.
|
||||
// Start paused so we can set a breakpoint before passing it
|
||||
// in the execution.
|
||||
return flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
expressionEvaluation: expressionEvaluation,
|
||||
startPaused: true, script: project.testFilePath,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
}
|
||||
|
||||
void batch2() {
|
||||
final TestsProject _project = TestsProject();
|
||||
Directory tempDir;
|
||||
FlutterRunTestDriver _flutter;
|
||||
testWithoutContext('cannot evaluate expressions if feature is disabled', () async {
|
||||
await startPaused(expressionEvaluation: false);
|
||||
await breakInMethod(flutter);
|
||||
await failToEvaluateExpression(flutter);
|
||||
});
|
||||
|
||||
Future<void> initProject() async {
|
||||
tempDir = createResolvedTempDirectorySync('test_expression_eval_test.');
|
||||
await _project.setUpIn(tempDir);
|
||||
_flutter = FlutterRunTestDriver(tempDir);
|
||||
}
|
||||
testWithoutContext('can evaluate trivial expressions in a test', () async {
|
||||
await startPaused(expressionEvaluation: true);
|
||||
await breakInMethod(flutter);
|
||||
await evaluateTrivialExpressions(flutter);
|
||||
});
|
||||
|
||||
Future<void> cleanProject() async {
|
||||
await _flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
}
|
||||
testWithoutContext('can evaluate complex expressions in a test', () async {
|
||||
await startPaused(expressionEvaluation: true);
|
||||
await breakInMethod(flutter);
|
||||
await evaluateComplexExpressions(flutter);
|
||||
});
|
||||
|
||||
Future<void> breakInMethod(FlutterTestDriver flutter) async {
|
||||
await _flutter.addBreakpoint(
|
||||
_project.breakpointAppUri,
|
||||
_project.breakpointLine,
|
||||
);
|
||||
await _flutter.resume();
|
||||
await _flutter.waitForPause();
|
||||
}
|
||||
testWithoutContext('can evaluate trivial expressions in library without pause', () async {
|
||||
await startPaused(expressionEvaluation: true);
|
||||
await evaluateTrivialExpressionsInLibrary(flutter);
|
||||
});
|
||||
|
||||
Future<void> startPaused({bool expressionEvaluation}) {
|
||||
// The test project does not have a loop around its breakpoints.
|
||||
// Start paused so we can set a breakpoint before passing it
|
||||
// in the execution.
|
||||
return _flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
expressionEvaluation: expressionEvaluation,
|
||||
startPaused: true, script: _project.testFilePath,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
}
|
||||
|
||||
testWithoutContext('flutter test expression evaluation - error if expression evaluation disabled', () async {
|
||||
await initProject();
|
||||
await startPaused(expressionEvaluation: false);
|
||||
await breakInMethod(_flutter);
|
||||
await failToEvaluateExpression(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
|
||||
testWithoutContext('flutter test expression evaluation - can evaluate trivial expressions in a test', () async {
|
||||
await initProject();
|
||||
await startPaused(expressionEvaluation: true);
|
||||
await breakInMethod(_flutter);
|
||||
await evaluateTrivialExpressions(_flutter);
|
||||
await cleanProject();
|
||||
});
|
||||
|
||||
testWithoutContext('flutter test expression evaluation - can evaluate complex expressions in a test', () async {
|
||||
await initProject();
|
||||
await startPaused(expressionEvaluation: true);
|
||||
await breakInMethod(_flutter);
|
||||
await evaluateComplexExpressions(_flutter);
|
||||
await cleanProject();
|
||||
testWithoutContext('can evaluate complex expressions in library without pause', () async {
|
||||
await startPaused(expressionEvaluation: true);
|
||||
await evaluateComplexExpressionsInLibrary(flutter);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -208,6 +211,28 @@ Future<void> evaluateComplexExpressions(FlutterTestDriver flutter) async {
|
||||
expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
|
||||
}
|
||||
|
||||
Future<void> evaluateTrivialExpressionsInLibrary(FlutterTestDriver flutter) async {
|
||||
final LibraryRef library = await getRootLibrary(flutter);
|
||||
final ObjRef res = await flutter.evaluate(library.id, '"test"');
|
||||
expectInstance(res, InstanceKind.kString, 'test');
|
||||
}
|
||||
|
||||
Future<void> evaluateComplexExpressionsInLibrary(FlutterTestDriver flutter) async {
|
||||
final LibraryRef library = await getRootLibrary(flutter);
|
||||
final ObjRef res = await flutter.evaluate(library.id, 'new DateTime.now().year');
|
||||
expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
|
||||
}
|
||||
|
||||
Future<LibraryRef> getRootLibrary(FlutterTestDriver flutter) async {
|
||||
// `isolate.rootLib` returns incorrect library, so find the
|
||||
// entrypoint manually here instead.
|
||||
//
|
||||
// Issue: https://github.com/dart-lang/sdk/issues/44760
|
||||
final Isolate isolate = await flutter.getFlutterIsolate();
|
||||
return isolate.libraries
|
||||
.firstWhere((LibraryRef l) => l.uri.contains('org-dartlang-app'));
|
||||
}
|
||||
|
||||
void expectInstance(ObjRef result, String kind, String message) {
|
||||
expect(result,
|
||||
const TypeMatcher<InstanceRef>()
|
||||
@ -220,8 +245,3 @@ void expectError(ObjRef result, String message) {
|
||||
const TypeMatcher<ErrorRef>()
|
||||
.having((ErrorRef instance) => instance.message, 'message', message));
|
||||
}
|
||||
|
||||
void main() {
|
||||
batch1();
|
||||
batch2();
|
||||
}
|
||||
|
139
packages/flutter_tools/test/web.shard/vm_service_web_test.dart
Normal file
139
packages/flutter_tools/test/web.shard/vm_service_web_test.dart
Normal file
@ -0,0 +1,139 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
import 'package:vm_service/vm_service_io.dart';
|
||||
|
||||
import '../integration.shard/test_data/basic_project.dart';
|
||||
import '../integration.shard/test_driver.dart';
|
||||
import '../integration.shard/test_utils.dart';
|
||||
import '../src/common.dart';
|
||||
|
||||
void main() {
|
||||
Directory tempDir;
|
||||
final BasicProjectWithUnaryMain project = BasicProjectWithUnaryMain();
|
||||
FlutterRunTestDriver flutter;
|
||||
|
||||
group('Clients of flutter run on web with DDS enabled', () {
|
||||
setUp(() async {
|
||||
tempDir = createResolvedTempDirectorySync('run_test.');
|
||||
await project.setUpIn(tempDir);
|
||||
flutter = FlutterRunTestDriver(tempDir, spawnDdsInstance: true);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
testWithoutContext('can validate flutter version', () async {
|
||||
await flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
|
||||
expect(flutter.vmServiceWsUri, isNotNull);
|
||||
|
||||
final VmService client =
|
||||
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||
await validateFlutterVersion(client);
|
||||
});
|
||||
|
||||
testWithoutContext('can validate flutter version in parallel', () async {
|
||||
await flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
|
||||
expect(flutter.vmServiceWsUri, isNotNull);
|
||||
|
||||
final VmService client1 =
|
||||
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||
|
||||
final VmService client2 =
|
||||
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||
|
||||
await Future.wait(<Future<void>>[
|
||||
validateFlutterVersion(client1),
|
||||
validateFlutterVersion(client2)]
|
||||
);
|
||||
}, skip: 'DDS failure: https://github.com/dart-lang/sdk/issues/45569');
|
||||
});
|
||||
|
||||
group('Clients of flutter run on web with DDS disabled', () {
|
||||
setUp(() async {
|
||||
tempDir = createResolvedTempDirectorySync('run_test.');
|
||||
await project.setUpIn(tempDir);
|
||||
flutter = FlutterRunTestDriver(tempDir, spawnDdsInstance: false);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await flutter.stop();
|
||||
tryToDelete(tempDir);
|
||||
});
|
||||
|
||||
testWithoutContext('can validate flutter version', () async {
|
||||
await flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
|
||||
expect(flutter.vmServiceWsUri, isNotNull);
|
||||
|
||||
final VmService client =
|
||||
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||
await validateFlutterVersion(client);
|
||||
});
|
||||
|
||||
|
||||
testWithoutContext('can validate flutter version in parallel', () async {
|
||||
await flutter.run(
|
||||
withDebugger: true, chrome: true,
|
||||
additionalCommandArgs: <String>['--verbose']);
|
||||
|
||||
expect(flutter.vmServiceWsUri, isNotNull);
|
||||
|
||||
final VmService client1 =
|
||||
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||
|
||||
final VmService client2 =
|
||||
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||
|
||||
await Future.wait(<Future<void>>[
|
||||
validateFlutterVersion(client1),
|
||||
validateFlutterVersion(client2)]
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> validateFlutterVersion(VmService client) async {
|
||||
String method;
|
||||
|
||||
final Future<dynamic> registration = expectLater(
|
||||
client.onEvent('Service'),
|
||||
emitsThrough(predicate((Event e) {
|
||||
if (e.kind == EventKind.kServiceRegistered &&
|
||||
e.service == 'flutterVersion') {
|
||||
method = e.method;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}))
|
||||
);
|
||||
|
||||
await client.streamListen('Service');
|
||||
await registration;
|
||||
await client.streamCancel('Service');
|
||||
|
||||
final dynamic version1 = await client.callServiceExtension(method);
|
||||
expect(version1, const TypeMatcher<Success>()
|
||||
.having((Success r) => r.type, 'type', 'Success')
|
||||
.having((Success r) => r.json['frameworkVersion'], 'frameworkVersion', isNotNull));
|
||||
|
||||
await client.dispose();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user