Commit 7231fd3e authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Enable `flutter drive` on Windows (#8146)

... and run some more tests on Windows.
parent 36f64051
...@@ -53,7 +53,6 @@ Future<Null> main() async { ...@@ -53,7 +53,6 @@ Future<Null> main() async {
workingDirectory: p.join(flutterRoot, 'packages', 'flutter_driver'), workingDirectory: p.join(flutterRoot, 'packages', 'flutter_driver'),
expectFailure: true, expectFailure: true,
printOutput: false, printOutput: false,
skip: Platform.isWindows, // TODO(goderbauer): run on Windows when 'drive' command works
); );
List<String> coverageFlags = <String>[]; List<String> coverageFlags = <String>[];
......
...@@ -14,7 +14,7 @@ void main() { ...@@ -14,7 +14,7 @@ void main() {
for (String testName in testNames) { for (String testName in testNames) {
options..addAll(<String>['-t', testName]); options..addAll(<String>['-t', testName]);
} }
Process scriptProcess = await Process.start( ProcessResult scriptProcess = Process.runSync(
'../../bin/cache/dart-sdk/bin/dart', '../../bin/cache/dart-sdk/bin/dart',
options, options,
); );
...@@ -35,7 +35,7 @@ void main() { ...@@ -35,7 +35,7 @@ void main() {
test('exits with code 1 when task throws', () async { test('exits with code 1 when task throws', () async {
expect(await runScript(<String>['smoke_test_throws']), 1); expect(await runScript(<String>['smoke_test_throws']), 1);
}, skip: Platform.isWindows); // TODO(goderbauer): figure out why this fails on Windows });
test('exits with code 1 when fails', () async { test('exits with code 1 when fails', () async {
expect(await runScript(<String>['smoke_test_failure']), 1); expect(await runScript(<String>['smoke_test_failure']), 1);
......
...@@ -225,8 +225,8 @@ Future<Device> findTargetDevice() async { ...@@ -225,8 +225,8 @@ Future<Device> findTargetDevice() async {
printError('Failed to start iOS Simulator.'); printError('Failed to start iOS Simulator.');
return null; return null;
} }
} else if (os.isLinux) { } else if (os.isLinux || os.isWindows) {
// On Linux, for now, we just grab the first connected device we can find. // On Linux and Windows, for now, we just grab the first connected device we can find.
if (devices.isEmpty) { if (devices.isEmpty) {
printError('No devices found.'); printError('No devices found.');
return null; return null;
...@@ -236,9 +236,6 @@ Future<Device> findTargetDevice() async { ...@@ -236,9 +236,6 @@ Future<Device> findTargetDevice() async {
} }
printStatus('Using device ${devices.first.name}.'); printStatus('Using device ${devices.first.name}.');
return devices.first; return devices.first;
} else if (os.isWindows) {
printError('Windows is not yet supported.');
return null;
} else { } else {
printError('The operating system on this computer is not supported.'); printError('The operating system on this computer is not supported.');
return null; return null;
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:io' as io;
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_device.dart'; import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
...@@ -24,7 +22,8 @@ void main() { ...@@ -24,7 +22,8 @@ void main() {
group('drive', () { group('drive', () {
DriveCommand command; DriveCommand command;
Device mockDevice; Device mockDevice;
MemoryFileSystem memoryFileSystem; MemoryFileSystem fs;
Directory cwd;
void withMockDevice([Device mock]) { void withMockDevice([Device mock]) {
mockDevice = mock ?? new MockDevice(); mockDevice = mock ?? new MockDevice();
...@@ -35,14 +34,13 @@ void main() { ...@@ -35,14 +34,13 @@ void main() {
setUp(() { setUp(() {
command = new DriveCommand(); command = new DriveCommand();
applyMocksToCommand(command); applyMocksToCommand(command);
memoryFileSystem = new MemoryFileSystem(); fs = new MemoryFileSystem();
String cwd = '/some/app'; cwd = fs.systemTempDirectory.createTempSync('some_app_');
memoryFileSystem.directory(cwd).createSync(recursive: true); fs.currentDirectory = cwd;
memoryFileSystem.currentDirectory = cwd; fs.directory('test').createSync();
memoryFileSystem.directory('test').createSync(); fs.directory('test_driver').createSync();
memoryFileSystem.directory('test_driver').createSync(); fs.file('pubspec.yaml')..createSync();
memoryFileSystem.file('pubspec.yaml').createSync(); fs.file('.packages').createSync();
memoryFileSystem.file('.packages').createSync();
setExitFunctionForTests(); setExitFunctionForTests();
targetDeviceFinder = () { targetDeviceFinder = () {
throw 'Unexpected call to targetDeviceFinder'; throw 'Unexpected call to targetDeviceFinder';
...@@ -69,29 +67,33 @@ void main() { ...@@ -69,29 +67,33 @@ void main() {
testUsingContext('returns 1 when test file is not found', () async { testUsingContext('returns 1 when test file is not found', () async {
withMockDevice(); withMockDevice();
String testApp = fs.path.join(cwd.path, 'test', 'e2e.dart');
String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
List<String> args = <String>[ List<String> args = <String>[
'drive', 'drive',
'--target=/some/app/test/e2e.dart', '--target=$testApp}',
]; ];
try { try {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
fail('Expect exception'); fail('Expect exception');
} on ToolExit catch (e) { } on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1); expect(e.exitCode ?? 1, 1);
expect(e.message, contains('Test file not found: /some/app/test_driver/e2e_test.dart')); expect(e.message, contains('Test file not found: $testFile'));
} }
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('returns 1 when app fails to run', () async { testUsingContext('returns 1 when app fails to run', () async {
withMockDevice(); withMockDevice();
appStarter = expectAsync((DriveCommand command) async => null); appStarter = expectAsync((DriveCommand command) async => null);
String testApp = '/some/app/test_driver/e2e.dart'; String testApp = fs.path.join(cwd.path, 'test_driver', 'e2e.dart');
String testFile = '/some/app/test_driver/e2e_test.dart'; String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
MemoryFileSystem memFs = memoryFileSystem; MemoryFileSystem memFs = fs;
await memFs.file(testApp).writeAsString('main() { }'); await memFs.file(testApp).writeAsString('main() { }');
await memFs.file(testFile).writeAsString('main() { }'); await memFs.file(testFile).writeAsString('main() { }');
...@@ -107,11 +109,11 @@ void main() { ...@@ -107,11 +109,11 @@ void main() {
expect(e.message, contains('Application failed to start. Will not run test. Quitting.')); expect(e.message, contains('Application failed to start. Will not run test. Quitting.'));
} }
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('returns 1 when app file is outside package', () async { testUsingContext('returns 1 when app file is outside package', () async {
String appFile = '/not/in/my/app.dart'; String appFile = fs.path.join(cwd.dirname, 'other_app', 'app.dart');
List<String> args = <String>[ List<String> args = <String>[
'drive', 'drive',
'--target=$appFile', '--target=$appFile',
...@@ -122,15 +124,15 @@ void main() { ...@@ -122,15 +124,15 @@ void main() {
} on ToolExit catch (e) { } on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1); expect(e.exitCode ?? 1, 1);
expect(testLogger.errorText, contains( expect(testLogger.errorText, contains(
'Application file $appFile is outside the package directory /some/app', 'Application file $appFile is outside the package directory ${cwd.path}',
)); ));
} }
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('returns 1 when app file is in the root dir', () async { testUsingContext('returns 1 when app file is in the root dir', () async {
String appFile = '/some/app/main.dart'; String appFile = fs.path.join(cwd.path, 'main.dart');
List<String> args = <String>[ List<String> args = <String>[
'drive', 'drive',
'--target=$appFile', '--target=$appFile',
...@@ -141,19 +143,19 @@ void main() { ...@@ -141,19 +143,19 @@ void main() {
} on ToolExit catch (e) { } on ToolExit catch (e) {
expect(e.exitCode ?? 1, 1); expect(e.exitCode ?? 1, 1);
expect(testLogger.errorText, contains( expect(testLogger.errorText, contains(
'Application file main.dart must reside in one of the ' 'Application file main.dart must reside in one of the '
'sub-directories of the package structure, not in the root directory.', 'sub-directories of the package structure, not in the root directory.',
)); ));
} }
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('returns 0 when test ends successfully', () async { testUsingContext('returns 0 when test ends successfully', () async {
withMockDevice(); withMockDevice();
String testApp = '/some/app/test/e2e.dart'; String testApp = fs.path.join(cwd.path, 'test', 'e2e.dart');
String testFile = '/some/app/test_driver/e2e_test.dart'; String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
appStarter = expectAsync((DriveCommand command) async { appStarter = expectAsync((DriveCommand command) async {
return new LaunchResult.succeeded(); return new LaunchResult.succeeded();
...@@ -166,7 +168,7 @@ void main() { ...@@ -166,7 +168,7 @@ void main() {
return true; return true;
}); });
MemoryFileSystem memFs = memoryFileSystem; MemoryFileSystem memFs = fs;
await memFs.file(testApp).writeAsString('main() {}'); await memFs.file(testApp).writeAsString('main() {}');
await memFs.file(testFile).writeAsString('main() {}'); await memFs.file(testFile).writeAsString('main() {}');
...@@ -177,14 +179,14 @@ void main() { ...@@ -177,14 +179,14 @@ void main() {
await createTestCommandRunner(command).run(args); await createTestCommandRunner(command).run(args);
expect(testLogger.errorText, isEmpty); expect(testLogger.errorText, isEmpty);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('returns exitCode set by test runner', () async { testUsingContext('returns exitCode set by test runner', () async {
withMockDevice(); withMockDevice();
String testApp = '/some/app/test/e2e.dart'; String testApp = fs.path.join(cwd.path, 'test', 'e2e.dart');
String testFile = '/some/app/test_driver/e2e_test.dart'; String testFile = fs.path.join(cwd.path, 'test_driver', 'e2e_test.dart');
appStarter = expectAsync((DriveCommand command) async { appStarter = expectAsync((DriveCommand command) async {
return new LaunchResult.succeeded(); return new LaunchResult.succeeded();
...@@ -196,7 +198,7 @@ void main() { ...@@ -196,7 +198,7 @@ void main() {
return true; return true;
}); });
MemoryFileSystem memFs = memoryFileSystem; MemoryFileSystem memFs = fs;
await memFs.file(testApp).writeAsString('main() {}'); await memFs.file(testApp).writeAsString('main() {}');
await memFs.file(testFile).writeAsString('main() {}'); await memFs.file(testFile).writeAsString('main() {}');
...@@ -212,7 +214,7 @@ void main() { ...@@ -212,7 +214,7 @@ void main() {
expect(e.message, isNull); expect(e.message, isNull);
} }
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
group('findTargetDevice', () { group('findTargetDevice', () {
...@@ -225,7 +227,7 @@ void main() { ...@@ -225,7 +227,7 @@ void main() {
Device device = await findTargetDevice(); Device device = await findTargetDevice();
expect(device.name, 'specified-device'); expect(device.name, 'specified-device');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
}); });
...@@ -233,6 +235,7 @@ void main() { ...@@ -233,6 +235,7 @@ void main() {
void setOs() { void setOs() {
when(os.isMacOS).thenReturn(true); when(os.isMacOS).thenReturn(true);
when(os.isLinux).thenReturn(false); when(os.isLinux).thenReturn(false);
when(os.isWindows).thenReturn(false);
} }
testUsingContext('uses existing emulator', () async { testUsingContext('uses existing emulator', () async {
...@@ -244,7 +247,7 @@ void main() { ...@@ -244,7 +247,7 @@ void main() {
Device device = await findTargetDevice(); Device device = await findTargetDevice();
expect(device.name, 'mock-simulator'); expect(device.name, 'mock-simulator');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('uses existing Android device if and there are no simulators', () async { testUsingContext('uses existing Android device if and there are no simulators', () async {
...@@ -257,7 +260,7 @@ void main() { ...@@ -257,7 +260,7 @@ void main() {
Device device = await findTargetDevice(); Device device = await findTargetDevice();
expect(device.name, 'mock-android-device'); expect(device.name, 'mock-android-device');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('launches emulator', () async { testUsingContext('launches emulator', () async {
...@@ -271,21 +274,23 @@ void main() { ...@@ -271,21 +274,23 @@ void main() {
Device device = await findTargetDevice(); Device device = await findTargetDevice();
expect(device.name, 'new-simulator'); expect(device.name, 'new-simulator');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
}); });
group('findTargetDevice on Linux', () { void findTargetDeviceOnLinuxOrWindows({bool isWindows: false, bool isLinux: false}) {
assert(isWindows != isLinux);
void setOs() { void setOs() {
when(os.isMacOS).thenReturn(false); when(os.isMacOS).thenReturn(false);
when(os.isLinux).thenReturn(true); when(os.isLinux).thenReturn(isLinux);
when(os.isWindows).thenReturn(isWindows);
} }
testUsingContext('returns null if no devices found', () async { testUsingContext('returns null if no devices found', () async {
setOs(); setOs();
expect(await findTargetDevice(), isNull); expect(await findTargetDevice(), isNull);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
testUsingContext('uses existing Android device', () async { testUsingContext('uses existing Android device', () async {
...@@ -297,10 +302,18 @@ void main() { ...@@ -297,10 +302,18 @@ void main() {
Device device = await findTargetDevice(); Device device = await findTargetDevice();
expect(device.name, 'mock-android-device'); expect(device.name, 'mock-android-device');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem, FileSystem: () => fs,
}); });
}
group('findTargetDevice on Linux', () {
findTargetDeviceOnLinuxOrWindows(isLinux: true);
});
group('findTargetDevice on Windows', () {
findTargetDeviceOnLinuxOrWindows(isWindows: true);
}); });
}, skip: io.Platform.isWindows); // TODO(goderbauer): enable when drive command is working });
} }
class MockDevice extends Mock implements Device { class MockDevice extends Mock implements Device {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment