Unverified Commit 0f886448 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[devicelab] allow the devicelab to take a screenshot if the iOS connection...

[devicelab] allow the devicelab to take a screenshot if the iOS connection fails with FLUTTER_IOS_SCREENSHOT_ON_CONNECTION_FAILURE (#68156)

More attempts to remote diagnose the issues in the iOS devicelab
parent 25857ce5
...@@ -443,11 +443,11 @@ List<String> flutterCommandArgs(String command, List<String> options) { ...@@ -443,11 +443,11 @@ List<String> flutterCommandArgs(String command, List<String> options) {
Future<int> flutter(String command, { Future<int> flutter(String command, {
List<String> options = const <String>[], List<String> options = const <String>[],
bool canFail = false, // as in, whether failures are ok. False means that they are fatal. bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
Map<String, String> environment, Map<String, String> environment = const <String, String>{},
}) { }) {
final List<String> args = flutterCommandArgs(command, options); final List<String> args = flutterCommandArgs(command, options);
return exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args, return exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
canFail: canFail, environment: environment); canFail: canFail, environment: <String, String>{...?environment, 'FLUTTER_IOS_SCREENSHOT_ON_CONNECTION_FAILURE': 'true'});
} }
/// Runs a `flutter` command and returns the standard output as a string. /// Runs a `flutter` command and returns the standard output as a string.
......
...@@ -11,6 +11,7 @@ import 'package:vm_service/vm_service.dart' as vm_service; ...@@ -11,6 +11,7 @@ import 'package:vm_service/vm_service.dart' as vm_service;
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/error_handling_io.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
...@@ -439,6 +440,7 @@ class IOSDevice extends Device { ...@@ -439,6 +440,7 @@ class IOSDevice extends Device {
installationResult = await iosDeployDebugger.launchAndAttach() ? 0 : 1; installationResult = await iosDeployDebugger.launchAndAttach() ? 0 : 1;
} }
if (installationResult != 0) { if (installationResult != 0) {
await _screenshotOnFailure();
_logger.printError('Could not run ${bundle.path} on $id.'); _logger.printError('Could not run ${bundle.path} on $id.');
_logger.printError('Try launching Xcode and selecting "Product > Run" to fix the problem:'); _logger.printError('Try launching Xcode and selecting "Product > Run" to fix the problem:');
_logger.printError(' open ios/Runner.xcworkspace'); _logger.printError(' open ios/Runner.xcworkspace');
...@@ -468,6 +470,7 @@ class IOSDevice extends Device { ...@@ -468,6 +470,7 @@ class IOSDevice extends Device {
packageName: FlutterProject.current().manifest.appName, packageName: FlutterProject.current().manifest.appName,
); );
if (localUri == null) { if (localUri == null) {
await _screenshotOnFailure();
return LaunchResult.failed(); return LaunchResult.failed();
} }
return LaunchResult.succeeded(observatoryUri: localUri); return LaunchResult.succeeded(observatoryUri: localUri);
...@@ -549,6 +552,23 @@ class IOSDevice extends Device { ...@@ -549,6 +552,23 @@ class IOSDevice extends Device {
}); });
await _portForwarder?.dispose(); await _portForwarder?.dispose();
} }
Future<void> _screenshotOnFailure() async {
final bool screenshotOnConnectionFailure = _platform
.environment['FLUTTER_IOS_SCREENSHOT_ON_CONNECTION_FAILURE'] == 'true';
if (!screenshotOnConnectionFailure) {
return;
}
final File file = _fileSystem.file('test_screenshot.png');
try {
await takeScreenshot(file);
_logger.printStatus('BASE64 SCREENSHOT:${base64.encode(file.readAsBytesSync())}');
} on Exception {
_logger.printError('Failed to take screenshot');
} finally {
ErrorHandlingFileSystem.deleteIfExists(file);
}
}
} }
/// Decodes a vis-encoded syslog string to a UTF-8 representation. /// Decodes a vis-encoded syslog string to a UTF-8 representation.
......
// 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:convert';
import 'dart:io';
/// decodes a base64 screenshot stored in the devicelab.
///
/// Usage dart tool/screenshot_decoder.dart path/to/log_file
void main(List<String> arguments) {
int screenshot = 0;
final String logFile = arguments.first;
for (final String line in File(logFile).readAsLinesSync()) {
if (!line.contains('BASE64 SCREENSHOT:')) {
continue;
}
final String message = line.split('BASE64 SCREENSHOT:')[1];
final List<int> bytes = base64.decode(message);
File('flutter_screenshot_$screenshot.png').writeAsBytesSync(bytes);
screenshot += 1;
}
}
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