Skip to content

Commit 0f88644

Browse files
[devicelab] allow the devicelab to take a screenshot if the iOS connection fails with FLUTTER_IOS_SCREENSHOT_ON_CONNECTION_FAILURE (flutter#68156)
More attempts to remote diagnose the issues in the iOS devicelab
1 parent 25857ce commit 0f88644

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

dev/devicelab/lib/framework/utils.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,11 +443,11 @@ List<String> flutterCommandArgs(String command, List<String> options) {
443443
Future<int> flutter(String command, {
444444
List<String> options = const <String>[],
445445
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
446-
Map<String, String> environment,
446+
Map<String, String> environment = const <String, String>{},
447447
}) {
448448
final List<String> args = flutterCommandArgs(command, options);
449449
return exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
450-
canFail: canFail, environment: environment);
450+
canFail: canFail, environment: <String, String>{...?environment, 'FLUTTER_IOS_SCREENSHOT_ON_CONNECTION_FAILURE': 'true'});
451451
}
452452

453453
/// Runs a `flutter` command and returns the standard output as a string.

packages/flutter_tools/lib/src/ios/devices.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:vm_service/vm_service.dart' as vm_service;
1111

1212
import '../application_package.dart';
1313
import '../base/common.dart';
14+
import '../base/error_handling_io.dart';
1415
import '../base/file_system.dart';
1516
import '../base/io.dart';
1617
import '../base/logger.dart';
@@ -439,6 +440,7 @@ class IOSDevice extends Device {
439440
installationResult = await iosDeployDebugger.launchAndAttach() ? 0 : 1;
440441
}
441442
if (installationResult != 0) {
443+
await _screenshotOnFailure();
442444
_logger.printError('Could not run ${bundle.path} on $id.');
443445
_logger.printError('Try launching Xcode and selecting "Product > Run" to fix the problem:');
444446
_logger.printError(' open ios/Runner.xcworkspace');
@@ -468,6 +470,7 @@ class IOSDevice extends Device {
468470
packageName: FlutterProject.current().manifest.appName,
469471
);
470472
if (localUri == null) {
473+
await _screenshotOnFailure();
471474
return LaunchResult.failed();
472475
}
473476
return LaunchResult.succeeded(observatoryUri: localUri);
@@ -549,6 +552,23 @@ class IOSDevice extends Device {
549552
});
550553
await _portForwarder?.dispose();
551554
}
555+
556+
Future<void> _screenshotOnFailure() async {
557+
final bool screenshotOnConnectionFailure = _platform
558+
.environment['FLUTTER_IOS_SCREENSHOT_ON_CONNECTION_FAILURE'] == 'true';
559+
if (!screenshotOnConnectionFailure) {
560+
return;
561+
}
562+
final File file = _fileSystem.file('test_screenshot.png');
563+
try {
564+
await takeScreenshot(file);
565+
_logger.printStatus('BASE64 SCREENSHOT:${base64.encode(file.readAsBytesSync())}');
566+
} on Exception {
567+
_logger.printError('Failed to take screenshot');
568+
} finally {
569+
ErrorHandlingFileSystem.deleteIfExists(file);
570+
}
571+
}
552572
}
553573

554574
/// Decodes a vis-encoded syslog string to a UTF-8 representation.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:convert';
6+
import 'dart:io';
7+
8+
/// decodes a base64 screenshot stored in the devicelab.
9+
///
10+
/// Usage dart tool/screenshot_decoder.dart path/to/log_file
11+
void main(List<String> arguments) {
12+
int screenshot = 0;
13+
final String logFile = arguments.first;
14+
for (final String line in File(logFile).readAsLinesSync()) {
15+
if (!line.contains('BASE64 SCREENSHOT:')) {
16+
continue;
17+
}
18+
final String message = line.split('BASE64 SCREENSHOT:')[1];
19+
final List<int> bytes = base64.decode(message);
20+
File('flutter_screenshot_$screenshot.png').writeAsBytesSync(bytes);
21+
screenshot += 1;
22+
}
23+
}

0 commit comments

Comments
 (0)