Skip to content

Commit

Permalink
Take screenshot on devicelab failure (flutter#122249)
Browse files Browse the repository at this point in the history
Take screenshot on devicelab failure
  • Loading branch information
jmagman committed Mar 15, 2023
1 parent a599c08 commit e2e313e
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 16 deletions.
36 changes: 24 additions & 12 deletions dev/devicelab/bin/tasks/gradle_plugin_light_apk_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,14 @@ Future<void> main() async {
section('gradlew on build script with error');
await project.introduceError();
ProcessResult result = await inDirectory(project.rootPath, () {
return executeFlutter('build', options: <String>[
'apk',
'--release',
]);
return executeFlutter(
'build',
options: <String>[
'apk',
'--release',
],
canFail: true,
);
});

if (result.exitCode == 0) {
Expand All @@ -278,10 +282,14 @@ Future<void> main() async {
section('flutter build apk on build script with error');
await project.introduceError();
result = await inDirectory(project.rootPath, () {
return executeFlutter('build', options: <String>[
'apk',
'--release',
]);
return executeFlutter(
'build',
options: <String>[
'apk',
'--release',
],
canFail: true,
);
});
if (result.exitCode == 0) {
throw failure(
Expand All @@ -304,10 +312,14 @@ Future<void> main() async {
section('gradlew assembleDebug forwards stderr');
await project.introducePubspecError();
final ProcessResult result = await inDirectory(project.rootPath, () {
return executeFlutter('build', options: <String>[
'apk',
'--release',
]);
return executeFlutter(
'build',
options: <String>[
'apk',
'--release',
],
canFail: true,
);
});
if (result.exitCode == 0) {
throw failure(
Expand Down
61 changes: 57 additions & 4 deletions dev/devicelab/lib/framework/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,15 @@ Future<int> flutter(String command, {
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
Map<String, String>? environment,
String? workingDirectory,
}) {
}) async {
final List<String> args = _flutterCommandArgs(command, options);
return exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
final int exitCode = await exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
canFail: canFail, environment: environment, workingDirectory: workingDirectory);

if (exitCode != 0 && !canFail) {
await _flutterScreenshot(workingDirectory: workingDirectory);
}
return exitCode;
}

/// Starts a Flutter subprocess.
Expand Down Expand Up @@ -506,13 +511,20 @@ Future<Process> startFlutter(String command, {
String? workingDirectory,
}) async {
final List<String> args = _flutterCommandArgs(command, options);
return startProcess(
final Process process = await startProcess(
path.join(flutterDirectory.path, 'bin', 'flutter'),
args,
environment: environment,
isBot: isBot,
workingDirectory: workingDirectory,
);

unawaited(process.exitCode.then<void>((int exitCode) async {
if (exitCode != 0) {
await _flutterScreenshot(workingDirectory: workingDirectory);
}
}));
return process;
}

/// Runs a `flutter` command and returns the standard output as a string.
Expand All @@ -530,12 +542,53 @@ Future<String> evalFlutter(String command, {

Future<ProcessResult> executeFlutter(String command, {
List<String> options = const <String>[],
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
}) async {
final List<String> args = _flutterCommandArgs(command, options);
return _processManager.run(
final ProcessResult processResult = await _processManager.run(
<String>[path.join(flutterDirectory.path, 'bin', 'flutter'), ...args],
workingDirectory: cwd,
);

if (processResult.exitCode != 0 && !canFail) {
await _flutterScreenshot();
}
return processResult;
}

Future<void> _flutterScreenshot({ String? workingDirectory }) async {
try {
final Directory? dumpDirectory = hostAgent.dumpDirectory;
if (dumpDirectory == null) {
return;
}
// On command failure try uploading screenshot of failing command.
final String screenshotPath = path.join(
dumpDirectory.path,
'device-screenshot-${DateTime.now().toLocal().toIso8601String()}.png',
);

final String deviceId = (await devices.workingDevice).deviceId;
print('Taking screenshot of working device $deviceId at $screenshotPath');
final List<String> args = _flutterCommandArgs(
'screenshot',
<String>[
'--out',
screenshotPath,
'-d', deviceId,
],
);
final ProcessResult screenshot = await _processManager.run(
<String>[path.join(flutterDirectory.path, 'bin', 'flutter'), ...args],
workingDirectory: workingDirectory ?? cwd,
);

if (screenshot.exitCode != 0) {
print('Failed to take screenshot. Continuing.');
}
} catch (exception) {
print('Failed to take screenshot. Continuing.\n$exception');
}
}

String get dartBin =>
Expand Down

0 comments on commit e2e313e

Please sign in to comment.