Last active
April 28, 2024 03:10
-
-
Save stevenosse/b191d56cb4b75ed8012c3d04c1d80448 to your computer and use it in GitHub Desktop.
testWidgets screenshot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Originally published on: https://gist.github.com/stevsct/fc84fee8bcc3271e2295d99d7c7ae49d | |
/// | |
/// Inspired by https://pub.dev/packages/spot | |
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(); | |
image.dispose(); | |
}); | |
final directory = Directory('./screenshots'); | |
if (!directory.existsSync()) { | |
directory.createSync(); | |
} | |
final file = File('./screenshots/$name.png'); | |
file.writeAsBytesSync(bytes); | |
} | |
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; | |
} | |
assert(!renderObject.debugNeedsPaint); | |
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 | |
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Got it, thanks Steven!