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; | |
} | |
} |
Where should I put this code to?
Hi
You could create an utils
folder under your test
directory. 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
Got it, thanks Steven!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where should I put this code to?