2019-11-27 23:04:02 +00:00
|
|
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
2019-08-05 23:51:57 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2021-01-27 23:17:53 +00:00
|
|
|
// @dart = 2.8
|
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'dart:async';
|
2019-09-26 21:23:19 +00:00
|
|
|
import 'dart:convert';
|
2020-06-09 18:18:03 +00:00
|
|
|
import 'dart:io';
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
import 'package:dwds/dwds.dart';
|
2020-06-26 20:36:06 +00:00
|
|
|
import 'package:file/memory.dart';
|
2021-06-15 23:54:02 +00:00
|
|
|
import 'package:flutter_tools/src/application_package.dart';
|
2021-06-10 19:00:38 +00:00
|
|
|
import 'package:flutter_tools/src/asset.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/base/common.dart';
|
2021-06-15 23:54:02 +00:00
|
|
|
import 'package:flutter_tools/src/base/dds.dart';
|
2020-06-26 20:36:06 +00:00
|
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
2020-05-06 15:15:39 +00:00
|
|
|
import 'package:flutter_tools/src/base/platform.dart';
|
2021-03-02 23:29:03 +00:00
|
|
|
import 'package:flutter_tools/src/base/time.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/build_info.dart';
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:flutter_tools/src/compile.dart';
|
|
|
|
import 'package:flutter_tools/src/devfs.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/device.dart';
|
2021-04-16 00:01:34 +00:00
|
|
|
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
|
2021-04-21 20:49:03 +00:00
|
|
|
import 'package:flutter_tools/src/isolated/devfs_web.dart';
|
|
|
|
import 'package:flutter_tools/src/isolated/resident_web_runner.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/project.dart';
|
2019-09-11 16:38:42 +00:00
|
|
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
2021-06-15 23:54:02 +00:00
|
|
|
import 'package:flutter_tools/src/resident_devtools_handler.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
import 'package:flutter_tools/src/resident_runner.dart';
|
2020-05-06 15:15:39 +00:00
|
|
|
import 'package:flutter_tools/src/vmservice.dart';
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:flutter_tools/src/web/chrome.dart';
|
2019-09-11 02:29:31 +00:00
|
|
|
import 'package:flutter_tools/src/web/web_device.dart';
|
2021-06-10 19:00:38 +00:00
|
|
|
import 'package:meta/meta.dart';
|
|
|
|
import 'package:package_config/package_config.dart';
|
|
|
|
import 'package:package_config/package_config_types.dart';
|
2021-06-15 23:54:02 +00:00
|
|
|
import 'package:test/fake.dart';
|
2020-05-06 15:15:39 +00:00
|
|
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
2019-11-08 04:13:02 +00:00
|
|
|
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
import '../src/common.dart';
|
2019-11-24 05:54:43 +00:00
|
|
|
import '../src/context.dart';
|
2021-04-07 05:55:03 +00:00
|
|
|
import '../src/fake_vm_services.dart';
|
2019-08-05 23:51:57 +00:00
|
|
|
|
2020-04-20 22:15:54 +00:00
|
|
|
const List<VmServiceExpectation> kAttachLogExpectations = <VmServiceExpectation>[
|
|
|
|
FakeVmServiceRequest(
|
|
|
|
method: 'streamListen',
|
|
|
|
args: <String, Object>{
|
|
|
|
'streamId': 'Stdout',
|
|
|
|
},
|
|
|
|
),
|
|
|
|
FakeVmServiceRequest(
|
|
|
|
method: 'streamListen',
|
|
|
|
args: <String, Object>{
|
|
|
|
'streamId': 'Stderr',
|
|
|
|
},
|
|
|
|
)
|
|
|
|
];
|
|
|
|
|
|
|
|
const List<VmServiceExpectation> kAttachIsolateExpectations = <VmServiceExpectation>[
|
|
|
|
FakeVmServiceRequest(
|
|
|
|
method: 'streamListen',
|
|
|
|
args: <String, Object>{
|
|
|
|
'streamId': 'Isolate'
|
|
|
|
}
|
|
|
|
),
|
2020-06-09 18:18:03 +00:00
|
|
|
FakeVmServiceRequest(
|
2021-03-30 04:44:03 +00:00
|
|
|
method: 'registerService',
|
2020-06-09 18:18:03 +00:00
|
|
|
args: <String, Object>{
|
2021-03-30 04:44:03 +00:00
|
|
|
'service': 'reloadSources',
|
|
|
|
'alias': 'Flutter Tools',
|
|
|
|
}
|
2020-06-09 18:18:03 +00:00
|
|
|
),
|
2020-04-20 22:15:54 +00:00
|
|
|
FakeVmServiceRequest(
|
|
|
|
method: 'registerService',
|
|
|
|
args: <String, Object>{
|
2021-03-30 04:44:03 +00:00
|
|
|
'service': 'flutterVersion',
|
|
|
|
'alias': 'Flutter Tools',
|
2020-04-20 22:15:54 +00:00
|
|
|
}
|
2021-03-30 04:44:03 +00:00
|
|
|
),
|
|
|
|
FakeVmServiceRequest(
|
|
|
|
method: 'registerService',
|
|
|
|
args: <String, Object>{
|
|
|
|
'service': 'flutterMemoryInfo',
|
|
|
|
'alias': 'Flutter Tools',
|
|
|
|
}
|
|
|
|
),
|
|
|
|
FakeVmServiceRequest(
|
|
|
|
method: 'streamListen',
|
|
|
|
args: <String, Object>{
|
|
|
|
'streamId': 'Extension',
|
|
|
|
},
|
|
|
|
),
|
2020-04-20 22:15:54 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
const List<VmServiceExpectation> kAttachExpectations = <VmServiceExpectation>[
|
|
|
|
...kAttachLogExpectations,
|
|
|
|
...kAttachIsolateExpectations,
|
|
|
|
];
|
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
void main() {
|
2021-06-15 23:54:02 +00:00
|
|
|
FakeDebugConnection debugConnection;
|
2021-06-10 19:00:38 +00:00
|
|
|
FakeChromeDevice chromeDevice;
|
2021-06-15 23:54:02 +00:00
|
|
|
FakeAppConnection appConnection;
|
|
|
|
FakeFlutterDevice flutterDevice;
|
2021-06-10 19:00:38 +00:00
|
|
|
FakeWebDevFS webDevFS;
|
|
|
|
FakeResidentCompiler residentCompiler;
|
2021-05-14 20:04:11 +00:00
|
|
|
FakeChromeConnection chromeConnection;
|
|
|
|
FakeChromeTab chromeTab;
|
2021-06-15 23:54:02 +00:00
|
|
|
FakeWebServerDevice webServerDevice;
|
|
|
|
FakeDevice mockDevice;
|
2020-04-20 22:15:54 +00:00
|
|
|
FakeVmServiceHost fakeVmServiceHost;
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem fileSystem;
|
|
|
|
ProcessManager processManager;
|
2021-03-02 23:29:03 +00:00
|
|
|
TestUsage testUsage;
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
setUp(() {
|
2021-03-02 23:29:03 +00:00
|
|
|
testUsage = TestUsage();
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem = MemoryFileSystem.test();
|
|
|
|
processManager = FakeProcessManager.any();
|
2021-06-15 23:54:02 +00:00
|
|
|
debugConnection = FakeDebugConnection();
|
|
|
|
mockDevice = FakeDevice();
|
|
|
|
appConnection = FakeAppConnection();
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS = FakeWebDevFS();
|
|
|
|
residentCompiler = FakeResidentCompiler();
|
2021-05-14 20:04:11 +00:00
|
|
|
chromeConnection = FakeChromeConnection();
|
|
|
|
chromeTab = FakeChromeTab('index.html');
|
2021-06-15 23:54:02 +00:00
|
|
|
webServerDevice = FakeWebServerDevice();
|
|
|
|
flutterDevice = FakeFlutterDevice()
|
|
|
|
.._devFS = webDevFS
|
|
|
|
..device = mockDevice
|
|
|
|
..generator = residentCompiler;
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem.file('.packages').writeAsStringSync('\n');
|
2019-08-05 23:51:57 +00:00
|
|
|
});
|
|
|
|
|
2019-09-24 19:03:37 +00:00
|
|
|
void _setupMocks() {
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem.file('pubspec.yaml').createSync();
|
|
|
|
fileSystem.file('lib/main.dart').createSync(recursive: true);
|
|
|
|
fileSystem.file('web/index.html').createSync(recursive: true);
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: true, syncedBytes: 0);
|
2021-06-15 23:54:02 +00:00
|
|
|
debugConnection.fakeVmServiceHost = () => fakeVmServiceHost;
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.result = ConnectionResult(
|
2021-06-15 23:54:02 +00:00
|
|
|
appConnection,
|
|
|
|
debugConnection,
|
|
|
|
debugConnection.vmService,
|
2021-06-10 19:00:38 +00:00
|
|
|
);
|
2021-06-15 23:54:02 +00:00
|
|
|
debugConnection.uri = 'ws://127.0.0.1/abcd/';
|
2021-05-14 20:04:11 +00:00
|
|
|
chromeConnection.tabs.add(chromeTab);
|
2019-08-05 23:51:57 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('runner with web server device does not support debugging without --start-paused', () {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
|
|
|
flutterDevice.device = WebServerDevice(
|
2020-04-22 08:28:51 +00:00
|
|
|
logger: BufferLogger.test(),
|
2021-06-15 23:54:02 +00:00
|
|
|
);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentRunner profileResidentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-09-11 02:29:31 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2019-09-11 02:29:31 +00:00
|
|
|
|
|
|
|
expect(profileResidentWebRunner.debuggingEnabled, false);
|
2019-11-08 04:13:02 +00:00
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = FakeChromeDevice();
|
2020-06-26 20:36:06 +00:00
|
|
|
|
2019-09-11 02:29:31 +00:00
|
|
|
expect(residentWebRunner.debuggingEnabled, true);
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-09-11 02:29:31 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('runner with web server device supports debugging with --start-paused', () {
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2020-02-23 00:49:03 +00:00
|
|
|
_setupMocks();
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = WebServerDevice(
|
2020-04-22 08:28:51 +00:00
|
|
|
logger: BufferLogger.test(),
|
2021-06-15 23:54:02 +00:00
|
|
|
);
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentRunner profileResidentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-11-19 20:11:53 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
2019-11-19 20:11:53 +00:00
|
|
|
);
|
|
|
|
|
2021-06-10 19:00:38 +00:00
|
|
|
expect(profileResidentWebRunner.uri, webDevFS.baseUri);
|
2019-11-19 20:11:53 +00:00
|
|
|
expect(profileResidentWebRunner.debuggingEnabled, true);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
|
|
|
testUsingContext('profile does not supportsServiceProtocol', () {
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentRunner residentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2020-06-26 20:36:06 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = chromeDevice;
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentRunner profileResidentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-08-28 02:06:48 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
2019-08-28 02:06:48 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
expect(profileResidentWebRunner.supportsServiceProtocol, false);
|
|
|
|
expect(residentWebRunner.supportsServiceProtocol, true);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-08-05 23:51:57 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Can successfully run and connect to vmservice', () async {
|
2021-06-10 19:00:38 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
2019-08-05 23:51:57 +00:00
|
|
|
_setupMocks();
|
2021-06-10 19:00:38 +00:00
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
final DebugConnectionInfo debugConnectionInfo = await connectionInfoCompleter.future;
|
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
expect(appConnection.ranMain, true);
|
2021-06-10 19:00:38 +00:00
|
|
|
expect(logger.statusText, contains('Debug service listening on ws://127.0.0.1/abcd/'));
|
2019-08-05 23:51:57 +00:00
|
|
|
expect(debugConnectionInfo.wsUri.toString(), 'ws://127.0.0.1/abcd/');
|
2019-10-15 04:36:31 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-06-04 17:17:43 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('WebRunner copies compiled app.dill to cache during startup', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-06-04 17:17:43 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
|
|
|
_setupMocks();
|
|
|
|
|
|
|
|
residentWebRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
expect(await fileSystem.file(fileSystem.path.join('build', 'cache.dill')).readAsString(), 'ABC');
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-08-05 23:51:57 +00:00
|
|
|
|
2020-06-30 19:26:18 +00:00
|
|
|
// Regression test for https://github.com/flutter/flutter/issues/60613
|
|
|
|
testUsingContext('ResidentWebRunner calls appFailedToStart if initial compilation fails', () async {
|
|
|
|
_setupMocks();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-06-30 19:26:18 +00:00
|
|
|
fileSystem.file(globals.fs.path.join('lib', 'main.dart'))
|
|
|
|
.createSync(recursive: true);
|
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: false, syncedBytes: 0);
|
2020-06-30 19:26:18 +00:00
|
|
|
|
|
|
|
expect(await residentWebRunner.run(), 1);
|
|
|
|
// Completing this future ensures that the daemon can exit correctly.
|
|
|
|
expect(await residentWebRunner.waitForAppToFinish(), 1);
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Can successfully run without an index.html including status warning', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2020-04-24 16:09:53 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
|
|
|
_setupMocks();
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem.file(fileSystem.path.join('web', 'index.html'))
|
2020-04-24 16:09:53 +00:00
|
|
|
.deleteSync();
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentWebRunner residentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2020-06-30 19:26:18 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: false,
|
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: logger,
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2020-04-24 16:09:53 +00:00
|
|
|
|
|
|
|
expect(await residentWebRunner.run(), 0);
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText,
|
2020-04-24 16:09:53 +00:00
|
|
|
contains('This application is not configured to build on the web'));
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-04-24 16:09:53 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Can successfully run and disconnect with --no-resident', () async {
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
2019-11-04 17:08:40 +00:00
|
|
|
_setupMocks();
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentRunner residentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-11-04 17:08:40 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: false,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2019-11-04 17:08:40 +00:00
|
|
|
|
|
|
|
expect(await residentWebRunner.run(), 0);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-11-04 17:08:40 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Listens to stdout and stderr streams before running main', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachLogExpectations,
|
|
|
|
FakeVmServiceStreamResponse(
|
|
|
|
streamId: 'Stdout',
|
|
|
|
event: vm_service.Event(
|
|
|
|
timestamp: 0,
|
|
|
|
kind: vm_service.EventStreams.kStdout,
|
|
|
|
bytes: base64.encode(utf8.encode('THIS MESSAGE IS IMPORTANT'))
|
|
|
|
),
|
|
|
|
),
|
|
|
|
FakeVmServiceStreamResponse(
|
|
|
|
streamId: 'Stderr',
|
|
|
|
event: vm_service.Event(
|
|
|
|
timestamp: 0,
|
|
|
|
kind: vm_service.EventStreams.kStderr,
|
|
|
|
bytes: base64.encode(utf8.encode('SO IS THIS'))
|
|
|
|
),
|
|
|
|
),
|
|
|
|
...kAttachIsolateExpectations,
|
|
|
|
]);
|
2019-09-26 21:23:19 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText, contains('THIS MESSAGE IS IMPORTANT'));
|
|
|
|
expect(logger.statusText, contains('SO IS THIS'));
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-09-26 21:23:19 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Listens to extension events with structured errors', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: testLogger);
|
2020-06-09 18:18:03 +00:00
|
|
|
final Map<String, String> extensionData = <String, String>{
|
|
|
|
'test': 'data',
|
|
|
|
'renderedErrorText': 'error text',
|
|
|
|
};
|
|
|
|
final Map<String, String> emptyExtensionData = <String, String>{
|
|
|
|
'test': 'data',
|
|
|
|
'renderedErrorText': '',
|
|
|
|
};
|
|
|
|
final Map<String, String> nonStructuredErrorData = <String, String>{
|
|
|
|
'other': 'other stuff',
|
|
|
|
};
|
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
FakeVmServiceStreamResponse(
|
|
|
|
streamId: 'Extension',
|
|
|
|
event: vm_service.Event(
|
|
|
|
timestamp: 0,
|
|
|
|
extensionKind: 'Flutter.Error',
|
|
|
|
extensionData: vm_service.ExtensionData.parse(extensionData),
|
|
|
|
kind: vm_service.EventStreams.kExtension,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
// Empty error text should not break anything.
|
|
|
|
FakeVmServiceStreamResponse(
|
|
|
|
streamId: 'Extension',
|
|
|
|
event: vm_service.Event(
|
|
|
|
timestamp: 0,
|
|
|
|
extensionKind: 'Flutter.Error',
|
|
|
|
extensionData: vm_service.ExtensionData.parse(emptyExtensionData),
|
|
|
|
kind: vm_service.EventStreams.kExtension,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
// This is not Flutter.Error kind data, so it should not be logged.
|
|
|
|
FakeVmServiceStreamResponse(
|
|
|
|
streamId: 'Extension',
|
|
|
|
event: vm_service.Event(
|
|
|
|
timestamp: 0,
|
|
|
|
extensionKind: 'Other',
|
|
|
|
extensionData: vm_service.ExtensionData.parse(nonStructuredErrorData),
|
|
|
|
kind: vm_service.EventStreams.kExtension,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
]);
|
|
|
|
|
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
await null;
|
|
|
|
|
|
|
|
expect(testLogger.statusText, contains('\nerror text'));
|
|
|
|
expect(testLogger.statusText, isNot(contains('other stuff')));
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-06-09 18:18:03 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Does not run main with --start-paused', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentRunner residentWebRunner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-10-24 14:57:52 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
|
|
|
|
ipv6: true,
|
2019-11-08 04:13:02 +00:00
|
|
|
stayResident: true,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: BufferLogger.test(),
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2020-06-26 20:36:06 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
2019-10-24 14:57:52 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2020-04-20 22:15:54 +00:00
|
|
|
|
2019-10-24 14:57:52 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
expect(appConnection.ranMain, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-10-24 14:57:52 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Can hot reload after attaching', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: logger,
|
|
|
|
systemClock: SystemClock.fixed(DateTime(2001, 1, 1)),
|
|
|
|
);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
const FakeVmServiceRequest(
|
|
|
|
method: 'hotRestart',
|
|
|
|
jsonResponse: <String, Object>{
|
|
|
|
'type': 'Success',
|
|
|
|
}
|
|
|
|
),
|
2021-06-15 23:54:02 +00:00
|
|
|
const FakeVmServiceRequest(
|
|
|
|
method: 'streamListen',
|
|
|
|
args: <String, Object>{
|
|
|
|
'streamId': 'Isolate',
|
|
|
|
},
|
|
|
|
),
|
2020-04-20 22:15:54 +00:00
|
|
|
]);
|
2019-11-08 04:13:02 +00:00
|
|
|
_setupMocks();
|
2021-03-02 23:29:03 +00:00
|
|
|
final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
|
2021-05-14 20:04:11 +00:00
|
|
|
final Chromium chrome = Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher);
|
2021-03-02 23:29:03 +00:00
|
|
|
chromiumLauncher.instance = chrome;
|
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = GoogleChromeDevice(
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem: fileSystem,
|
2020-04-22 08:28:51 +00:00
|
|
|
chromiumLauncher: chromiumLauncher,
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: BufferLogger.test(),
|
2020-04-22 08:28:51 +00:00
|
|
|
platform: FakePlatform(operatingSystem: 'linux'),
|
|
|
|
processManager: FakeProcessManager.any(),
|
2021-06-15 23:54:02 +00:00
|
|
|
);
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: true);
|
|
|
|
|
2019-11-08 04:13:02 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
2019-12-12 21:55:09 +00:00
|
|
|
final DebugConnectionInfo debugConnectionInfo = await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
expect(debugConnectionInfo, isNotNull);
|
|
|
|
|
2019-11-08 04:13:02 +00:00
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText, contains('Restarted application in'));
|
2019-11-08 04:13:02 +00:00
|
|
|
expect(result.code, 0);
|
2021-06-10 19:00:38 +00:00
|
|
|
expect(webDevFS.mainUri.toString(), contains('entrypoint.dart'));
|
2021-03-02 23:29:03 +00:00
|
|
|
|
|
|
|
// ensure that analytics are sent.
|
2021-05-19 03:29:03 +00:00
|
|
|
expect(testUsage.events, <TestUsageEvent>[
|
|
|
|
TestUsageEvent('hot', 'restart', parameters: CustomDimensions.fromMap(<String, String>{'cd27': 'web-javascript', 'cd28': '', 'cd29': 'false', 'cd30': 'true', 'cd13': '0'})),
|
2021-03-02 23:29:03 +00:00
|
|
|
]);
|
|
|
|
expect(testUsage.timings, const <TestTimingEvent>[
|
|
|
|
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
|
|
|
|
]);
|
2019-11-08 04:13:02 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2021-03-02 23:29:03 +00:00
|
|
|
Usage: () => testUsage,
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-11-08 04:13:02 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Can hot restart after attaching', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: logger,
|
|
|
|
systemClock: SystemClock.fixed(DateTime(2001, 1, 1)),
|
|
|
|
);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
const FakeVmServiceRequest(
|
|
|
|
method: 'hotRestart',
|
|
|
|
jsonResponse: <String, Object>{
|
|
|
|
'type': 'Success',
|
|
|
|
}
|
|
|
|
),
|
|
|
|
]);
|
2019-11-08 04:13:02 +00:00
|
|
|
_setupMocks();
|
2021-03-02 23:29:03 +00:00
|
|
|
final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
|
2021-05-14 20:04:11 +00:00
|
|
|
final Chromium chrome = Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher);
|
2021-03-02 23:29:03 +00:00
|
|
|
chromiumLauncher.instance = chrome;
|
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = GoogleChromeDevice(
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem: fileSystem,
|
2020-04-22 08:28:51 +00:00
|
|
|
chromiumLauncher: chromiumLauncher,
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: BufferLogger.test(),
|
2020-04-22 08:28:51 +00:00
|
|
|
platform: FakePlatform(operatingSystem: 'linux'),
|
|
|
|
processManager: FakeProcessManager.any(),
|
2021-06-15 23:54:02 +00:00
|
|
|
);
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: true);
|
|
|
|
|
2019-11-08 04:13:02 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
2020-02-04 04:38:03 +00:00
|
|
|
// Ensure that generated entrypoint is generated correctly.
|
2021-06-10 19:00:38 +00:00
|
|
|
expect(webDevFS.mainUri, isNotNull);
|
|
|
|
final String entrypointContents = fileSystem.file(webDevFS.mainUri).readAsStringSync();
|
2020-04-20 15:24:50 +00:00
|
|
|
expect(entrypointContents, contains('// Flutter web bootstrap script'));
|
|
|
|
expect(entrypointContents, contains("import 'dart:ui' as ui;"));
|
|
|
|
expect(entrypointContents, contains('await ui.webOnlyInitializePlatform();'));
|
2020-02-04 04:38:03 +00:00
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText, contains('Restarted application in'));
|
2019-11-08 04:13:02 +00:00
|
|
|
expect(result.code, 0);
|
2021-03-02 23:29:03 +00:00
|
|
|
|
2019-11-08 04:13:02 +00:00
|
|
|
// ensure that analytics are sent.
|
2021-05-19 03:29:03 +00:00
|
|
|
expect(testUsage.events, <TestUsageEvent>[
|
|
|
|
TestUsageEvent('hot', 'restart', parameters: CustomDimensions.fromMap(<String, String>{'cd27': 'web-javascript', 'cd28': '', 'cd29': 'false', 'cd30': 'true', 'cd13': '0'})),
|
2021-03-02 23:29:03 +00:00
|
|
|
]);
|
|
|
|
expect(testUsage.timings, const <TestTimingEvent>[
|
|
|
|
TestTimingEvent('hot', 'web-incremental-restart', Duration.zero),
|
|
|
|
]);
|
2019-11-08 04:13:02 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2021-03-02 23:29:03 +00:00
|
|
|
Usage: () => testUsage,
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-11-08 04:13:02 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Can hot restart after attaching with web-server device', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: logger,
|
|
|
|
systemClock: SystemClock.fixed(DateTime(2001, 1, 1)),
|
|
|
|
);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests :kAttachExpectations);
|
2019-11-27 21:32:45 +00:00
|
|
|
_setupMocks();
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = webServerDevice;
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: true);
|
|
|
|
|
2019-11-27 21:32:45 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText, contains('Restarted application in'));
|
2019-11-27 21:32:45 +00:00
|
|
|
expect(result.code, 0);
|
2021-03-02 23:29:03 +00:00
|
|
|
|
|
|
|
// web-server device does not send restart analytics
|
|
|
|
expect(testUsage.events, isEmpty);
|
|
|
|
expect(testUsage.timings, isEmpty);
|
2019-11-27 21:32:45 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2021-03-02 23:29:03 +00:00
|
|
|
Usage: () => testUsage,
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-12-13 03:05:48 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('web resident runner is debuggable', () {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
|
|
|
|
2020-02-11 23:43:46 +00:00
|
|
|
expect(residentWebRunner.debuggingEnabled, true);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-03-13 14:02:34 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Exits when initial compile fails', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2019-08-05 23:51:57 +00:00
|
|
|
_setupMocks();
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: false, syncedBytes: 0);
|
|
|
|
|
2019-08-05 23:51:57 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
|
2020-02-11 23:43:46 +00:00
|
|
|
expect(await residentWebRunner.run(), 1);
|
2021-03-02 23:29:03 +00:00
|
|
|
expect(testUsage.events, isEmpty);
|
|
|
|
expect(testUsage.timings, isEmpty);
|
2019-09-11 16:38:42 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2021-03-02 23:29:03 +00:00
|
|
|
Usage: () => testUsage,
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-08-05 23:51:57 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Faithfully displays stdout messages with leading/trailing spaces', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachLogExpectations,
|
|
|
|
FakeVmServiceStreamResponse(
|
|
|
|
streamId: 'Stdout',
|
|
|
|
event: vm_service.Event(
|
|
|
|
timestamp: 0,
|
|
|
|
kind: vm_service.EventStreams.kStdout,
|
|
|
|
bytes: base64.encode(
|
|
|
|
utf8.encode(' This is a message with 4 leading and trailing spaces '),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
...kAttachIsolateExpectations,
|
|
|
|
]);
|
2020-03-27 01:08:05 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText,
|
2020-03-27 01:08:05 +00:00
|
|
|
contains(' This is a message with 4 leading and trailing spaces '));
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-03-27 01:08:05 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Fails on compilation errors in hot restart', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList());
|
2019-08-05 23:51:57 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-08-05 23:51:57 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.report = UpdateFSReport(success: false, syncedBytes: 0);
|
2019-08-05 23:51:57 +00:00
|
|
|
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
|
|
|
|
|
|
|
expect(result.code, 1);
|
2020-02-11 23:43:46 +00:00
|
|
|
expect(result.message, contains('Failed to recompile application.'));
|
2021-03-02 23:29:03 +00:00
|
|
|
expect(testUsage.events, isEmpty);
|
|
|
|
expect(testUsage.timings, isEmpty);
|
2019-10-22 19:36:56 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2021-03-02 23:29:03 +00:00
|
|
|
Usage: () => testUsage,
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-10-22 19:36:56 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Fails non-fatally on vmservice response error for hot restart', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
const FakeVmServiceRequest(
|
|
|
|
method: 'hotRestart',
|
|
|
|
jsonResponse: <String, Object>{
|
|
|
|
'type': 'Failed',
|
|
|
|
}
|
|
|
|
)
|
|
|
|
]);
|
2020-03-24 19:58:30 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
|
|
|
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(result.code, 0);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-03-24 19:58:30 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Fails fatally on Vm Service error response', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
const FakeVmServiceRequest(
|
|
|
|
method: 'hotRestart',
|
|
|
|
// Failed response,
|
|
|
|
errorCode: RPCErrorCodes.kInternalError,
|
|
|
|
),
|
|
|
|
]);
|
2020-03-24 19:58:30 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
final OperationResult result = await residentWebRunner.restart(fullRestart: false);
|
|
|
|
|
|
|
|
expect(result.code, 1);
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(result.message,
|
|
|
|
contains(RPCErrorCodes.kInternalError.toString()));
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-08-20 00:33:46 +00:00
|
|
|
|
2021-01-22 19:07:08 +00:00
|
|
|
testUsingContext('printHelp without details shows hot restart help message', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
|
2021-01-22 19:07:08 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
|
|
|
residentWebRunner.printHelp(details: false);
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText, contains('To hot restart changes'));
|
2021-01-22 19:07:08 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('cleanup of resources is safe to call multiple times', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
]);
|
2019-09-03 18:00:39 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-09-03 18:00:39 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
await residentWebRunner.exit();
|
|
|
|
await residentWebRunner.exit();
|
2019-10-15 00:29:04 +00:00
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
expect(debugConnection.didClose, false);
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-09-03 19:55:06 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('cleans up Chrome if tab is closed', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
]);
|
2019-10-28 17:26:18 +00:00
|
|
|
_setupMocks();
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
final Future<int> result = residentWebRunner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
);
|
|
|
|
await connectionInfoCompleter.future;
|
2021-06-15 23:54:02 +00:00
|
|
|
debugConnection.completer.complete();
|
2019-10-28 17:26:18 +00:00
|
|
|
|
|
|
|
await result;
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-10-28 17:26:18 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Prints target and device name on run', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachExpectations,
|
|
|
|
]);
|
2019-09-03 19:55:06 +00:00
|
|
|
_setupMocks();
|
2021-06-15 23:54:02 +00:00
|
|
|
mockDevice.name = 'Chromez';
|
2019-09-03 19:55:06 +00:00
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
2019-09-24 19:03:37 +00:00
|
|
|
unawaited(residentWebRunner.run(
|
2019-09-03 19:55:06 +00:00
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.statusText, contains(
|
2020-06-26 20:36:06 +00:00
|
|
|
'Launching ${fileSystem.path.join('lib', 'main.dart')} on '
|
2020-04-20 22:15:54 +00:00
|
|
|
'Chromez in debug mode',
|
|
|
|
));
|
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-10-10 23:34:27 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Sends launched app.webLaunchUrl event for Chrome device', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
|
|
...kAttachLogExpectations,
|
2020-06-09 18:18:03 +00:00
|
|
|
...kAttachIsolateExpectations,
|
2020-04-20 22:15:54 +00:00
|
|
|
]);
|
2019-11-18 18:10:15 +00:00
|
|
|
_setupMocks();
|
2021-05-14 20:04:11 +00:00
|
|
|
final FakeChromeConnection chromeConnection = FakeChromeConnection();
|
2021-03-02 23:29:03 +00:00
|
|
|
final TestChromiumLauncher chromiumLauncher = TestChromiumLauncher();
|
2021-05-14 20:04:11 +00:00
|
|
|
final Chromium chrome = Chromium(1, chromeConnection, chromiumLauncher: chromiumLauncher);
|
2021-03-02 23:29:03 +00:00
|
|
|
chromiumLauncher.instance = chrome;
|
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = GoogleChromeDevice(
|
2020-06-26 20:36:06 +00:00
|
|
|
fileSystem: fileSystem,
|
2020-04-22 08:28:51 +00:00
|
|
|
chromiumLauncher: chromiumLauncher,
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: logger,
|
2020-04-22 08:28:51 +00:00
|
|
|
platform: FakePlatform(operatingSystem: 'linux'),
|
|
|
|
processManager: FakeProcessManager.any(),
|
2021-06-15 23:54:02 +00:00
|
|
|
);
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.baseUri = Uri.parse('http://localhost:8765/app/');
|
|
|
|
|
2021-05-14 20:04:11 +00:00
|
|
|
final FakeChromeTab chromeTab = FakeChromeTab('index.html');
|
|
|
|
chromeConnection.tabs.add(chromeTab);
|
2019-11-18 18:10:15 +00:00
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentWebRunner runner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-11-18 18:10:15 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: logger,
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2019-11-18 18:10:15 +00:00
|
|
|
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(runner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
// Ensure we got the URL and that it was already launched.
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.eventText,
|
2020-03-03 00:23:56 +00:00
|
|
|
contains(json.encode(<String, Object>{
|
|
|
|
'name': 'app.webLaunchUrl',
|
|
|
|
'args': <String, Object>{
|
|
|
|
'url': 'http://localhost:8765/app/',
|
|
|
|
'launched': true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)));
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2019-11-18 18:10:15 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2019-11-18 18:10:15 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Sends unlaunched app.webLaunchUrl event for Web Server device', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2019-11-18 18:10:15 +00:00
|
|
|
_setupMocks();
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice.device = WebServerDevice(
|
2021-03-08 22:38:26 +00:00
|
|
|
logger: logger,
|
2021-06-15 23:54:02 +00:00
|
|
|
);
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.baseUri = Uri.parse('http://localhost:8765/app/');
|
2019-11-18 18:10:15 +00:00
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
final ResidentWebRunner runner = ResidentWebRunner(
|
2021-06-15 23:54:02 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
|
2019-11-18 18:10:15 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
2019-12-12 18:43:58 +00:00
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
fileSystem: fileSystem,
|
|
|
|
logger: logger,
|
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: globals.systemClock,
|
|
|
|
);
|
2019-11-18 18:10:15 +00:00
|
|
|
|
|
|
|
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
|
|
|
unawaited(runner.run(
|
|
|
|
connectionInfoCompleter: connectionInfoCompleter,
|
|
|
|
));
|
|
|
|
await connectionInfoCompleter.future;
|
|
|
|
|
|
|
|
// Ensure we got the URL and that it was not already launched.
|
2021-03-08 22:38:26 +00:00
|
|
|
expect(logger.eventText,
|
2020-03-03 00:23:56 +00:00
|
|
|
contains(json.encode(<String, Object>{
|
|
|
|
'name': 'app.webLaunchUrl',
|
|
|
|
'args': <String, Object>{
|
|
|
|
'url': 'http://localhost:8765/app/',
|
|
|
|
'launched': false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)));
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2019-11-18 18:10:15 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Successfully turns WebSocketException into ToolExit', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2020-02-18 19:27:14 +00:00
|
|
|
_setupMocks();
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.exception = const WebSocketException();
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-07-10 00:58:51 +00:00
|
|
|
await expectLater(residentWebRunner.run, throwsToolExit());
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Successfully turns AppConnectionException into ToolExit', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2020-02-18 19:27:14 +00:00
|
|
|
_setupMocks();
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.exception = AppConnectionException('');
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-07-10 00:58:51 +00:00
|
|
|
await expectLater(residentWebRunner.run, throwsToolExit());
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Successfully turns ChromeDebugError into ToolExit', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
|
|
|
_setupMocks();
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.exception = ChromeDebugException(<String, dynamic>{});
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-07-10 00:58:51 +00:00
|
|
|
await expectLater(residentWebRunner.run, throwsToolExit());
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Rethrows unknown Exception type from dwds', () async {
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2020-02-18 19:27:14 +00:00
|
|
|
_setupMocks();
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.exception = Exception();
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-07-10 00:58:51 +00:00
|
|
|
await expectLater(residentWebRunner.run, throwsException);
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-06-26 20:36:06 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
2020-04-20 22:15:54 +00:00
|
|
|
|
2020-06-26 20:36:06 +00:00
|
|
|
testUsingContext('Rethrows unknown Error type from dwds tooling', () async {
|
2021-03-08 22:38:26 +00:00
|
|
|
final BufferLogger logger = BufferLogger.test();
|
2021-06-15 23:54:02 +00:00
|
|
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
|
2020-04-20 22:15:54 +00:00
|
|
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
2020-02-18 19:27:14 +00:00
|
|
|
_setupMocks();
|
2021-06-10 19:00:38 +00:00
|
|
|
webDevFS.exception = StateError('');
|
2020-02-18 19:27:14 +00:00
|
|
|
|
2020-07-10 00:58:51 +00:00
|
|
|
await expectLater(residentWebRunner.run, throwsStateError);
|
2020-04-20 22:15:54 +00:00
|
|
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
2020-02-18 19:27:14 +00:00
|
|
|
}, overrides: <Type, Generator>{
|
2020-06-26 20:36:06 +00:00
|
|
|
FileSystem: () => fileSystem,
|
|
|
|
ProcessManager: () => processManager,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-03-08 22:38:26 +00:00
|
|
|
ResidentRunner setUpResidentRunner(FlutterDevice flutterDevice, {
|
|
|
|
Logger logger,
|
|
|
|
SystemClock systemClock,
|
|
|
|
}) {
|
|
|
|
return ResidentWebRunner(
|
2020-06-26 20:36:06 +00:00
|
|
|
flutterDevice,
|
2021-02-18 20:36:04 +00:00
|
|
|
flutterProject: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory),
|
2020-06-26 20:36:06 +00:00
|
|
|
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
|
|
|
|
ipv6: true,
|
|
|
|
stayResident: true,
|
|
|
|
urlTunneller: null,
|
2021-03-08 22:38:26 +00:00
|
|
|
usage: globals.flutterUsage,
|
|
|
|
systemClock: systemClock ?? SystemClock.fixed(DateTime.now()),
|
|
|
|
fileSystem: globals.fs,
|
|
|
|
logger: logger ?? BufferLogger.test(),
|
2021-06-15 23:54:02 +00:00
|
|
|
devtoolsHandler: createNoOpHandler,
|
2021-03-08 22:38:26 +00:00
|
|
|
);
|
2019-08-05 23:51:57 +00:00
|
|
|
}
|
|
|
|
|
2021-06-15 23:54:02 +00:00
|
|
|
class FakeWebServerDevice extends FakeDevice implements WebServerDevice {}
|
|
|
|
|
|
|
|
class FakeDevice extends Fake implements Device {
|
|
|
|
@override
|
|
|
|
String name;
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<String> get sdkNameAndVersion async => 'SDK Name and Version';
|
|
|
|
|
|
|
|
@override
|
|
|
|
DartDevelopmentService dds;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<LaunchResult> startApp(
|
|
|
|
covariant ApplicationPackage package, {
|
|
|
|
String mainPath,
|
|
|
|
String route,
|
|
|
|
DebuggingOptions debuggingOptions,
|
|
|
|
Map<String, dynamic> platformArgs,
|
|
|
|
bool prebuiltApplication = false,
|
|
|
|
bool ipv6 = false,
|
|
|
|
String userIdentifier,
|
|
|
|
}) async {
|
|
|
|
return LaunchResult.succeeded();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<bool> stopApp(
|
|
|
|
covariant ApplicationPackage app, {
|
|
|
|
String userIdentifier,
|
|
|
|
}) async {
|
|
|
|
if (count > 0) {
|
|
|
|
throw StateError('stopApp called more than once.');
|
|
|
|
}
|
|
|
|
count += 1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class FakeDebugConnection extends Fake implements DebugConnection {
|
|
|
|
FakeVmServiceHost Function() fakeVmServiceHost;
|
|
|
|
|
|
|
|
@override
|
|
|
|
vm_service.VmService get vmService => fakeVmServiceHost.call().vmService.service;
|
|
|
|
|
|
|
|
@override
|
|
|
|
String uri;
|
|
|
|
|
|
|
|
final Completer<void> completer = Completer<void>();
|
|
|
|
bool didClose = false;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> get onDone => completer.future;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> close() async {
|
|
|
|
didClose = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class FakeAppConnection extends Fake implements AppConnection {
|
|
|
|
bool ranMain = false;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void runMain() {
|
|
|
|
ranMain = true;
|
|
|
|
}
|
|
|
|
}
|
2021-06-10 19:00:38 +00:00
|
|
|
|
|
|
|
class FakeChromeDevice extends Fake implements ChromiumDevice {}
|
2021-06-15 23:54:02 +00:00
|
|
|
|
2021-06-10 19:00:38 +00:00
|
|
|
class FakeWipDebugger extends Fake implements WipDebugger {}
|
|
|
|
|
|
|
|
class FakeResidentCompiler extends Fake implements ResidentCompiler {
|
|
|
|
@override
|
|
|
|
Future<CompilerOutput> recompile(
|
|
|
|
Uri mainUri,
|
|
|
|
List<Uri> invalidatedFiles, {
|
|
|
|
@required String outputPath,
|
|
|
|
@required PackageConfig packageConfig,
|
|
|
|
@required String projectRootPath,
|
|
|
|
@required FileSystem fs,
|
|
|
|
bool suppressErrors = false,
|
|
|
|
}) async {
|
|
|
|
return const CompilerOutput('foo.dill', 0, <Uri>[]);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void accept() { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
void reset() { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<CompilerOutput> reject() async {
|
|
|
|
return const CompilerOutput('foo.dill', 0, <Uri>[]);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void addFileSystemRoot(String root) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
class FakeWebDevFS extends Fake implements WebDevFS {
|
|
|
|
Object exception;
|
|
|
|
ConnectionResult result;
|
|
|
|
UpdateFSReport report;
|
|
|
|
|
|
|
|
Uri mainUri;
|
|
|
|
|
|
|
|
@override
|
|
|
|
List<Uri> sources = <Uri>[];
|
|
|
|
|
|
|
|
@override
|
|
|
|
Uri baseUri = Uri.parse('http://localhost:12345');
|
|
|
|
|
|
|
|
@override
|
|
|
|
DateTime lastCompiled = DateTime.now();
|
|
|
|
|
|
|
|
@override
|
|
|
|
PackageConfig lastPackageConfig = PackageConfig.empty;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<Uri> create() async {
|
|
|
|
return baseUri;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<UpdateFSReport> update({
|
|
|
|
@required Uri mainUri,
|
|
|
|
@required ResidentCompiler generator,
|
|
|
|
@required bool trackWidgetCreation,
|
|
|
|
@required String pathToReload,
|
|
|
|
@required List<Uri> invalidatedFiles,
|
|
|
|
@required PackageConfig packageConfig,
|
|
|
|
@required String dillOutputPath,
|
|
|
|
DevFSWriter devFSWriter,
|
|
|
|
String target,
|
|
|
|
AssetBundle bundle,
|
|
|
|
DateTime firstBuildTime,
|
|
|
|
bool bundleFirstUpload = false,
|
|
|
|
bool fullRestart = false,
|
|
|
|
String projectRootPath,
|
|
|
|
}) async {
|
|
|
|
this.mainUri = mainUri;
|
|
|
|
return report;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<ConnectionResult> connect(bool useDebugExtension) async {
|
|
|
|
if (exception != null) {
|
|
|
|
throw exception;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
2021-05-14 20:04:11 +00:00
|
|
|
|
|
|
|
class FakeChromeConnection extends Fake implements ChromeConnection {
|
|
|
|
final List<ChromeTab> tabs = <ChromeTab>[];
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<ChromeTab> getTab(bool Function(ChromeTab tab) accept, {Duration retryFor}) async {
|
|
|
|
return tabs.firstWhere(accept);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class FakeChromeTab extends Fake implements ChromeTab {
|
|
|
|
FakeChromeTab(this.url);
|
|
|
|
|
|
|
|
@override
|
|
|
|
final String url;
|
|
|
|
final FakeWipConnection connection = FakeWipConnection();
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<WipConnection> connect() async {
|
|
|
|
return connection;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class FakeWipConnection extends Fake implements WipConnection {
|
|
|
|
@override
|
|
|
|
final WipDebugger debugger = FakeWipDebugger();
|
|
|
|
}
|
|
|
|
|
2021-03-02 23:29:03 +00:00
|
|
|
/// A test implementation of the [ChromiumLauncher] that launches a fixed instance.
|
|
|
|
class TestChromiumLauncher implements ChromiumLauncher {
|
|
|
|
TestChromiumLauncher();
|
|
|
|
|
|
|
|
set instance(Chromium chromium) {
|
|
|
|
_hasInstance = true;
|
|
|
|
currentCompleter.complete(chromium);
|
|
|
|
}
|
|
|
|
bool _hasInstance = false;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Completer<Chromium> currentCompleter = Completer<Chromium>();
|
|
|
|
|
|
|
|
@override
|
|
|
|
bool canFindExecutable() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<Chromium> get connectedInstance => currentCompleter.future;
|
|
|
|
|
|
|
|
@override
|
|
|
|
String findExecutable() {
|
|
|
|
return 'chrome';
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
bool get hasChromeInstance => _hasInstance;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<Chromium> launch(String url, {bool headless = false, int debugPort, bool skipCheck = false, Directory cacheDir}) async {
|
|
|
|
return currentCompleter.future;
|
|
|
|
}
|
|
|
|
}
|
2021-06-15 23:54:02 +00:00
|
|
|
|
|
|
|
class FakeFlutterDevice extends Fake implements FlutterDevice {
|
|
|
|
Uri testUri;
|
|
|
|
UpdateFSReport report = UpdateFSReport(
|
|
|
|
success: true,
|
|
|
|
syncedBytes: 0,
|
|
|
|
invalidatedSourcesCount: 1,
|
|
|
|
);
|
|
|
|
Object reportError;
|
|
|
|
|
|
|
|
@override
|
|
|
|
ResidentCompiler generator;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Stream<Uri> get observatoryUris => Stream<Uri>.value(testUri);
|
|
|
|
|
|
|
|
@override
|
|
|
|
FlutterVmService vmService;
|
|
|
|
|
|
|
|
DevFS _devFS;
|
|
|
|
|
|
|
|
@override
|
|
|
|
DevFS get devFS => _devFS;
|
|
|
|
|
|
|
|
@override
|
|
|
|
set devFS(DevFS value) { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
Device device;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> stopEchoingDeviceLog() async { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> initLogReader() async { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<Uri> setupDevFS(String fsName, Directory rootDirectory) async {
|
|
|
|
return testUri;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> exitApps({Duration timeoutDelay = const Duration(seconds: 10)}) async { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> connect({
|
|
|
|
ReloadSources reloadSources,
|
|
|
|
Restart restart,
|
|
|
|
CompileExpression compileExpression,
|
|
|
|
GetSkSLMethod getSkSLMethod,
|
|
|
|
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
|
|
|
|
int hostVmServicePort,
|
|
|
|
int ddsPort,
|
|
|
|
bool disableServiceAuthCodes = false,
|
|
|
|
bool enableDds = true,
|
|
|
|
@required bool allowExistingDdsInstance,
|
|
|
|
bool ipv6 = false,
|
|
|
|
}) async { }
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<UpdateFSReport> updateDevFS({
|
|
|
|
Uri mainUri,
|
|
|
|
String target,
|
|
|
|
AssetBundle bundle,
|
|
|
|
DateTime firstBuildTime,
|
|
|
|
bool bundleFirstUpload = false,
|
|
|
|
bool bundleDirty = false,
|
|
|
|
bool fullRestart = false,
|
|
|
|
String projectRootPath,
|
|
|
|
String pathToReload,
|
|
|
|
String dillOutputPath,
|
|
|
|
List<Uri> invalidatedFiles,
|
|
|
|
PackageConfig packageConfig,
|
|
|
|
}) async {
|
|
|
|
if (reportError != null) {
|
|
|
|
throw reportError;
|
|
|
|
}
|
|
|
|
return report;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Future<void> updateReloadStatus(bool wasReloadSuccessful) async { }
|
|
|
|
}
|