diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 8ae32ebf0f..abdd2992da 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:meta/meta.dart'; +import 'package:package_config/package_config_types.dart'; import '../android/android_device.dart'; import '../application_package.dart'; @@ -13,6 +14,7 @@ import '../base/common.dart'; import '../base/file_system.dart'; import '../base/logger.dart'; import '../build_info.dart'; +import '../dart/package_map.dart'; import '../device.dart'; import '../drive/drive_service.dart'; import '../globals.dart' as globals; @@ -178,7 +180,12 @@ class DriveCommand extends RunCommandBase { logger: _logger, processUtils: globals.processUtils, dartSdkPath: globals.artifacts.getArtifactPath(Artifact.engineDartBinary), - ); + ); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( + globals.fs.file('.packages'), + logger: _logger, + throwOnError: false, + ) ?? PackageConfig.empty; final DriverService driverService = _flutterDriverFactory.createDriverService(web); final BuildInfo buildInfo = getBuildInfo(); final DebuggingOptions debuggingOptions = createDebuggingOptions(); @@ -220,6 +227,7 @@ class DriveCommand extends RunCommandBase { testFile, stringsArg('test-arguments'), {}, + packageConfig, chromeBinary: stringArg('chrome-binary'), headless: boolArg('headless'), browserDimension: stringArg('browser-dimension').split(','), diff --git a/packages/flutter_tools/lib/src/drive/drive_service.dart b/packages/flutter_tools/lib/src/drive/drive_service.dart index f8e64c53aa..67242407cb 100644 --- a/packages/flutter_tools/lib/src/drive/drive_service.dart +++ b/packages/flutter_tools/lib/src/drive/drive_service.dart @@ -5,6 +5,7 @@ import 'package:dds/dds.dart' as dds; import 'package:file/file.dart'; import 'package:meta/meta.dart'; +import 'package:package_config/package_config_types.dart'; import 'package:vm_service/vm_service.dart' as vm_service; import '../application_package.dart'; @@ -77,7 +78,8 @@ abstract class DriverService { Future startTest( String testFile, List arguments, - Map environment, { + Map environment, + PackageConfig packageConfig, { bool headless, String chromeBinary, String browserName, @@ -224,7 +226,8 @@ class FlutterDriverService extends DriverService { Future startTest( String testFile, List arguments, - Map environment, { + Map environment, + PackageConfig packageConfig, { bool headless, String chromeBinary, String browserName, @@ -232,14 +235,16 @@ class FlutterDriverService extends DriverService { int driverPort, List browserDimension, }) async { + // Check if package:test is available. If not, fall back to invoking + // the test script directly. `pub run test` is strictly better because + // in the even that a socket or something similar is left open, the + // test runner will correctly shutdown the VM instead of hanging forever. return _processUtils.stream([ _dartSdkPath, - 'pub', - 'run', - 'test', - ...arguments, - testFile, - '-rexpanded', + if (packageConfig['test'] != null) + ...['pub', 'run', 'test', ...arguments, testFile, '-rexpanded'] + else + ...[...arguments, testFile, '-rexpanded'], ], environment: { 'VM_SERVICE_URL': _vmServiceUri, ...environment, diff --git a/packages/flutter_tools/lib/src/drive/web_driver_service.dart b/packages/flutter_tools/lib/src/drive/web_driver_service.dart index 12087d093f..21a6a9b9b4 100644 --- a/packages/flutter_tools/lib/src/drive/web_driver_service.dart +++ b/packages/flutter_tools/lib/src/drive/web_driver_service.dart @@ -7,6 +7,7 @@ import 'dart:math' as math; import 'package:file/file.dart'; import 'package:meta/meta.dart'; +import 'package:package_config/package_config.dart'; import 'package:webdriver/async_io.dart' as async_io; import '../base/common.dart'; @@ -82,7 +83,7 @@ class WebDriverService extends DriverService { } @override - Future startTest(String testFile, List arguments, Map environment, { + Future startTest(String testFile, List arguments, Map environment, PackageConfig packageConfig, { bool headless, String chromeBinary, String browserName, diff --git a/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart b/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart index a21602e94f..ca396f8020 100644 --- a/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart +++ b/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart @@ -14,6 +14,7 @@ import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/drive/drive_service.dart'; import 'package:flutter_tools/src/vmservice.dart'; import 'package:mockito/mockito.dart'; +import 'package:package_config/package_config_types.dart'; import 'package:process/process.dart'; import 'package:vm_service/vm_service.dart' as vm_service; @@ -168,11 +169,43 @@ void main() { 'foo.test', ['--enable-experiment=non-nullable'], {'FOO': 'BAR'}, + PackageConfig([Package('test', Uri.base)]), ); expect(testResult, 23); }); + testWithoutContext('Uses dart to execute the test if there is no package:test dependency', () async { + final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: [ + getVM, + ]); + final FakeProcessManager processManager = FakeProcessManager.list([ + const FakeCommand( + command: ['dart', '--enable-experiment=non-nullable', 'foo.test', '-rexpanded'], + exitCode: 23, + environment: { + 'FOO': 'BAR', + 'VM_SERVICE_URL': 'http://127.0.0.1:1234/' // dds forwarded URI + }, + ), + ]); + final DriverService driverService = setUpDriverService(processManager: processManager, vmService: fakeVmServiceHost.vmService); + final Device device = FakeDevice(LaunchResult.succeeded( + observatoryUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), + )); + + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); + final int testResult = await driverService.startTest( + 'foo.test', + ['--enable-experiment=non-nullable'], + {'FOO': 'BAR'}, + PackageConfig.empty, + ); + + expect(testResult, 23); + }); + + testWithoutContext('Connects to device VM Service and runs test application without dds', () async { final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: [ getVM, @@ -196,6 +229,7 @@ void main() { 'foo.test', [], {}, + PackageConfig([Package('test', Uri.base)]), ); expect(testResult, 11);