Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Last active April 12, 2024 13:44
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save PlugFox/7b75cd76b6ae7839cf53de3d1ea3872c to your computer and use it in GitHub Desktop.
Save PlugFox/7b75cd76b6ae7839cf53de3d1ea3872c to your computer and use it in GitHub Desktop.
Flutter integration test screenshots (including Windows)
import 'dart:io' as io;
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'src/util/screenshot.dart';
void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('End-to-end_tests', () {
setUp(() async {
//await $initializeApp();
});
tearDown(() async {
//await $disposeApp();
});
testWidgets('App', (tester) async {
// Prepare for screenshot.
final shot = screenshot(tester);
io.Directory('integration_test/screenshots').createSync(recursive: true);
// Build our app and trigger a frame.
await tester.pumpWidget(const App());
// ...
final appScreenshot = await shot();
io.File('integration_test/screenshots/app.png').writeAsBytesSync(appScreenshot);
});
});
}
import 'dart:io' as io;
import 'dart:typed_data' as td;
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart' show RenderRepaintBoundary;
import 'package:flutter/widgets.dart' show WidgetsApp;
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
/// The [_$pixelRatio] describes the scale between the logical pixels and the
/// size of the output image. It is independent of the
/// [dart:ui.FlutterView.devicePixelRatio] for the device, so specifying 1.0
/// (the default) will give you a 1:1 mapping between logical pixels and the
/// output pixels in the image.
const double _$pixelRatio = 1.0;
/// Returns a function that takes a screenshot of the current state of the app.
Future<List<int>> Function([String? name]) screenshot(
WidgetTester tester, [
IntegrationTestWidgetsFlutterBinding? binding,
]) =>
([String? name]) async {
await tester.pump();
if (binding != null && name != null && (io.Platform.isAndroid || io.Platform.isIOS)) {
if (io.Platform.isAndroid) await binding.convertFlutterSurfaceToImage();
return await binding.takeScreenshot(name);
} else {
final element = tester.firstElement(find.byType(WidgetsApp));
RenderRepaintBoundary? boundary;
element.visitAncestorElements((element) {
final renderObject = element.renderObject;
if (renderObject is RenderRepaintBoundary) boundary = renderObject;
return true;
});
if (boundary == null) throw StateError('No RenderRepaintBoundary found');
final image = await boundary!.toImage(pixelRatio: _$pixelRatio);
final bytes = await image.toByteData(format: ui.ImageByteFormat.png);
if (bytes is! td.ByteData) throw StateError('Error converting image to bytes');
return bytes.buffer.asUint8List();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment