Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[macOS] Add run release test in devicelab (#100526)
Adds a test that invokes flutter run in release mode on macOS desktop, waits for successful launch and the flutter command list, then sends the 'q' command to quit the running app. This adds an integration test for #100504. Issue: #100348 (fix) Issue: #97978 (partial fix) Issue: #97977 (partial fix) Umbrella issue: #60113
- Loading branch information
Showing
6 changed files
with
294 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// 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. | ||
|
||
import 'dart:async'; | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
|
||
import 'package:flutter_devicelab/common.dart'; | ||
import 'package:flutter_devicelab/framework/devices.dart'; | ||
import 'package:flutter_devicelab/framework/framework.dart'; | ||
import 'package:flutter_devicelab/framework/task_result.dart'; | ||
import 'package:flutter_devicelab/framework/utils.dart'; | ||
import 'package:path/path.dart' as path; | ||
|
||
/// Basic launch test for desktop operating systems. | ||
void main() { | ||
task(() async { | ||
deviceOperatingSystem = DeviceOperatingSystem.macos; | ||
final Device device = await devices.workingDevice; | ||
// TODO(cbracken): https://github.com/flutter/flutter/issues/87508#issuecomment-1043753201 | ||
// Switch to dev/integration_tests/ui once we have CocoaPods working on M1 Macs. | ||
final Directory appDir = dir(path.join(flutterDirectory.path, 'examples/hello_world')); | ||
await inDirectory(appDir, () async { | ||
final Completer<void> ready = Completer<void>(); | ||
final List<String> stdout = <String>[]; | ||
final List<String> stderr = <String>[]; | ||
|
||
print('run: starting...'); | ||
final List<String> options = <String>[ | ||
'--release', | ||
'-d', | ||
device.deviceId, | ||
]; | ||
final Process run = await startFlutter( | ||
'run', | ||
options: options, | ||
isBot: false, | ||
); | ||
int? runExitCode; | ||
run.stdout | ||
.transform<String>(utf8.decoder) | ||
.transform<String>(const LineSplitter()) | ||
.listen((String line) { | ||
print('run:stdout: $line'); | ||
if ( | ||
!line.startsWith('Building flutter tool...') && | ||
!line.startsWith('Running "flutter pub get" in ui...') && | ||
!line.startsWith('Resolving dependencies...') && | ||
// Catch engine piped output from unrelated concurrent Flutter apps | ||
!line.contains(RegExp(r'[A-Z]\/flutter \([0-9]+\):')) && | ||
// Empty lines could be due to the progress spinner breaking up. | ||
line.length > 1 | ||
) { | ||
stdout.add(line); | ||
} | ||
if (line.contains('Quit (terminate the application on the device).')) { | ||
ready.complete(); | ||
} | ||
}); | ||
run.stderr | ||
.transform<String>(utf8.decoder) | ||
.transform<String>(const LineSplitter()) | ||
.listen((String line) { | ||
print('run:stderr: $line'); | ||
stderr.add(line); | ||
}); | ||
unawaited(run.exitCode.then<void>((int exitCode) { runExitCode = exitCode; })); | ||
await Future.any<dynamic>(<Future<dynamic>>[ ready.future, run.exitCode ]); | ||
if (runExitCode != null) { | ||
throw 'Failed to run test app; runner unexpected exited, with exit code $runExitCode.'; | ||
} | ||
run.stdin.write('q'); | ||
|
||
await run.exitCode; | ||
|
||
if (stderr.isNotEmpty) { | ||
throw 'flutter run --release had output on standard error.'; | ||
} | ||
|
||
_findNextMatcherInList( | ||
stdout, | ||
(String line) => line.startsWith('Launching lib/main.dart on ') && line.endsWith(' in release mode...'), | ||
'Launching lib/main.dart on', | ||
); | ||
|
||
_findNextMatcherInList( | ||
stdout, | ||
(String line) => line.contains('Quit (terminate the application on the device).'), | ||
'q Quit (terminate the application on the device)', | ||
); | ||
|
||
_findNextMatcherInList( | ||
stdout, | ||
(String line) => line == 'Application finished.', | ||
'Application finished.', | ||
); | ||
}); | ||
return TaskResult.success(null); | ||
}); | ||
} | ||
|
||
void _findNextMatcherInList( | ||
List<String> list, | ||
bool Function(String testLine) matcher, | ||
String errorMessageExpectedLine | ||
) { | ||
final List<String> copyOfListForErrorMessage = List<String>.from(list); | ||
|
||
while (list.isNotEmpty) { | ||
final String nextLine = list.first; | ||
list.removeAt(0); | ||
|
||
if (matcher(nextLine)) { | ||
return; | ||
} | ||
} | ||
|
||
throw ''' | ||
Did not find expected line | ||
$errorMessageExpectedLine | ||
in flutter run --release stdout | ||
$copyOfListForErrorMessage | ||
'''; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.