Skip to content

Instantly share code, notes, and snippets.

Last active April 28, 2024 03:10
Show Gist options
  • Save stevenosse/b191d56cb4b75ed8012c3d04c1d80448 to your computer and use it in GitHub Desktop.
Save stevenosse/b191d56cb4b75ed8012c3d04c1d80448 to your computer and use it in GitHub Desktop.
testWidgets screenshot
/// Originally published on:
/// Inspired by
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
extension TestScreenshotUtil on WidgetTester {
Future<void> takeScreenshot({required String name}) async {
final liveElement = binding.renderViewElement!;
late final Uint8List bytes;
await binding.runAsync(() async {
final image = await _captureImage(liveElement);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
if (byteData == null) {
return 'Could not take screenshot';
bytes = byteData.buffer.asUint8List();
final directory = Directory('./screenshots');
if (!directory.existsSync()) {
final file = File('./screenshots/$name.png');
Future<ui.Image> _captureImage(Element element) async {
assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) {
// ignore: unnecessary_cast
renderObject = renderObject.parent! as RenderObject;
final OffsetLayer layer = renderObject.debugLayer! as OffsetLayer;
final ui.Image image = await layer.toImage(renderObject.paintBounds);
if (element.renderObject is RenderBox) {
final expectedSize = (element.renderObject as RenderBox?)!.size;
if (expectedSize.width != image.width || expectedSize.height != image.height) {
// ignore: avoid_print
'Warning: The screenshot captured of ${element.toStringShort()} is '
'larger (${image.width}, ${image.height}) than '
'${element.toStringShort()} (${expectedSize.width}, ${expectedSize.height}) itself.\n'
'Wrap the ${element.toStringShort()} in a RepaintBoundary to be able to capture only that layer. ',
return image;
Copy link

Where should I put this code to?

Copy link

Where should I put this code to?

You could create an utils folder under your testdirectory. Then in your widget test, you'll be able to call the method like this:

await tester.takeScreenshot(name: 'my_test_name');

The file will be located in $PROJECT_DIR/screenshots

Copy link

Got it, thanks Steven!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment