golden_screenshot
Utilities to automate screenshot generation using Flutter's golden tests.
The generated screenshots are suitable for the App Store, Play Store, F-Droid, Flathub (Linux), etc,
and are saved in a Fastlane-compatible directory structure (e.g. metadata/en-US/images/phoneScreenshots/1_home.png
) by default.
See lib/src/screenshot_device.dart
for the default list of devices,
or have a look at Customization to customize the devices, frames, and location of the screenshots.
Getting started
In your pubspec.yaml
file, add golden_screenshot
as a dev_dependency
before running flutter pub get
:
dev_dependencies:
flutter_test:
sdk: flutter
golden_screenshot: ^x.y.z # Replace x.y.z with the latest version
Then create a file in your test
directory (e.g. test/screenshot_test.dart
) and use
example/test/screenshots_test.dart
as a template to create your own tests.
The main portion might look something like this:
_testGame(
goldenFileName: '1_home',
child: const HomePage(),
);
_testGame(
gameSave: inProgressGameSave,
frameColors: playPageFrameColors,
goldenFileName: '2_play',
child: const PlayPage(),
);
_testGame(
goldenFileName: '4_shop',
child: const ShopPage(),
);
_testGame(
goldenFileName: '5_tutorial',
child: const TutorialPage(),
);
_testGame(
goldenFileName: '6_settings',
child: const SettingsPage(),
);
If you're familiar with golden tests in Flutter, you'll notice some differences...
We use testGoldens
instead of testWidgets
to create the tests, which enables
shadows inside golden files. By default, Flutter disables them since
shadows are rendered ever-so-slightly differently every time,
but we handle this by using a fuzzy comparator.
Additionally, instead of using expectLater
, we use tester.expectScreenshot
:
// OLD
await expectLater(find.byType(HomePage), matchesGoldenFile('path/to/1_home'));
// NEW
await tester.expectScreenshot(device, '1_home');
tester.expectScreenshot
internally enables a fuzzy comparator which allows for
small (0.1% configurable) differences between the expected and actual image,
whereas Flutter typically expects every pixel to be exactly the same.
Usage
Once you have created your test file, run the following command to generate the screenshots:
flutter test test/screenshot_test.dart --update-goldens
Customization
Custom devices
If you don't want to use the default set of devices (GoldenScreenshotDevices
),
you can create your own set of devices by creating an enum containing
ScreenshotDevice
instances.
See GoldenScreenshotDevices for what your enum should look like.
enum MyScreenshotDevices {
phone(ScreenshotDevice(
platform: TargetPlatform.android,
resolution: Size(1440, 3120),
pixelRatio: 10 / 3,
goldenSubFolder: 'phoneScreenshots/',
frameBuilder: ScreenshotFrame.android,
)),
tablet(ScreenshotDevice(
platform: TargetPlatform.android,
resolution: Size(2732, 2048),
pixelRatio: 2,
goldenSubFolder: 'tenInchScreenshots/',
frameBuilder: MyTabletFrame.new,
));
const GoldenScreenshotDevices(this.device);
final ScreenshotDevice device;
}
Custom frames
You can create your own frames by creating a widget whose contructor
has the same signature as ScreenshotFrame
's constructor,
i.e. has the type ScreenshotFrameBuilder
.
You can then pass your frame's constructor to the ScreenshotDevice
's frameBuilder
parameter as above.
class MyTabletFrame extends StatelessWidget {
const MyTabletFrame({
super.key,
required this.device,
this.frameColors,
required this.child,
});
final ScreenshotDevice device;
final ScreenshotFrameColors? frameColors;
final Widget child;
@override
Widget build(BuildContext context) {
// Your frame implementation
}
}
Custom screenshot directory
By default, the screenshots are saved in ../metadata/\$localeCode/images/
.
The ../
is because this path is relative to the test
directory.
You can change this by setting ScreenshotDevice.screenshotsFolder
to something else. This path should end with a slash too.
void main() {
ScreenshotDevice.screenshotsFolder = 'path/to/screenshots/';
testGoldens('...', (tester) async {
Libraries
- golden_screenshot
- Utilities to automate screenshot generation using Flutter's golden tests.