diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md index 9e9538ce55..3f31a4953f 100644 --- a/script/tool/CHANGELOG.md +++ b/script/tool/CHANGELOG.md @@ -9,6 +9,7 @@ immediately abort the test. - Deprecated `--plugins` in favor of new `--packages`. `--plugins` continues to work for now, but will be removed in the future. +- Make `drive-examples` device detection robust against Flutter tool banners. ## 0.3.0 diff --git a/script/tool/lib/src/drive_examples_command.dart b/script/tool/lib/src/drive_examples_command.dart index 1e19535f4a..df74119e40 100644 --- a/script/tool/lib/src/drive_examples_command.dart +++ b/script/tool/lib/src/drive_examples_command.dart @@ -208,9 +208,14 @@ class DriveExamplesCommand extends PackageLoopingCommand { return deviceIds; } + String output = result.stdout as String; + // --machine doesn't currently prevent the tool from printing banners; + // see https://github.com/flutter/flutter/issues/86055. This workaround + // can be removed once that is fixed. + output = output.substring(output.indexOf('[')); + final List> devices = - (jsonDecode(result.stdout as String) as List) - .cast>(); + (jsonDecode(output) as List).cast>(); for (final Map deviceInfo in devices) { final String targetPlatform = (deviceInfo['targetPlatform'] as String?) ?? ''; diff --git a/script/tool/test/drive_examples_command_test.dart b/script/tool/test/drive_examples_command_test.dart index d22d95f14d..681a9e0e58 100644 --- a/script/tool/test/drive_examples_command_test.dart +++ b/script/tool/test/drive_examples_command_test.dart @@ -44,13 +44,22 @@ void main() { void setMockFlutterDevicesOutput({ bool hasIosDevice = true, bool hasAndroidDevice = true, + bool includeBanner = false, }) { + const String updateBanner = ''' +╔════════════════════════════════════════════════════════════════════════════╗ +║ A new version of Flutter is available! ║ +║ ║ +║ To update to the latest version, run "flutter upgrade". ║ +╚════════════════════════════════════════════════════════════════════════════╝ +'''; final List devices = [ if (hasIosDevice) '{"id": "$_fakeIosDevice", "targetPlatform": "ios"}', if (hasAndroidDevice) '{"id": "$_fakeAndroidDevice", "targetPlatform": "android-x86"}', ]; - final String output = '''[${devices.join(',')}]'''; + final String output = + '''${includeBanner ? updateBanner : ''}[${devices.join(',')}]'''; final MockProcess mockDevicesProcess = MockProcess.succeeding(); mockDevicesProcess.stdoutController.close(); // ignore: unawaited_futures @@ -113,6 +122,32 @@ void main() { ); }); + test('handles flutter tool banners when checking devices', () async { + createFakePlugin( + 'plugin', + packagesDir, + extraFiles: [ + 'example/test_driver/integration_test.dart', + 'example/integration_test/foo_test.dart', + ], + platformSupport: { + kPlatformIos: PlatformSupport.inline, + }, + ); + + setMockFlutterDevicesOutput(includeBanner: true); + final List output = + await runCapturingPrint(runner, ['drive-examples', '--ios']); + + expect( + output, + containsAllInOrder([ + contains('Running for plugin'), + contains('No issues found!'), + ]), + ); + }); + test('fails for iOS if getting devices fails', () async { // Simulate failure from `flutter devices`. processRunner.mockProcessesForExecutable['flutter'] = [