snaptest 0.1.0
snaptest: ^0.1.0 copied to clipboard
Snap photos in your widget tests.
Snaptest #
See what your widgets look like during testing.
[Title banner]
Snaptest is simple: call snap() in any widget test to save a screenshot of what's currently on screen. Perfect for debugging, documentation, and visual regression testing.
Installation 💻 #
dart pub add dev:snaptest
The Basics 🚀 #
Just call snap() to see your screen #
Add one line to any widget test to see what it looks like:
import 'package:flutter_test/flutter_test.dart';
import 'package:snaptest/snaptest.dart';
testWidgets('My widget test', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
// That's it! Screenshot saved to .snaptest/
await snap();
});
The screenshot gets saved as a PNG file in .snaptest/ using your test name. Great for debugging failing tests or documenting what your widgets actually look like.
Configure your .gitignore #
**/.snaptest/ # Screenshots (usually not committed)
Level Up: Real Rendering 📱 #
By default, snaptest creates simplified screenshots (blocked text, no images/shadows) for consistency. But you can enable real rendering to see exactly what users see:
testWidgets('Real rendering example', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
await snap(
settings: SnaptestSettings.full([
Devices.ios.iPhone16Pro,
Devices.android.samsungGalaxyS20,
]),
);
});
This creates beautiful screenshots with:
- ✅ Real text rendering
- ✅ Actual images
- ✅ Shadows and effects
- ✅ Device frames around the content
- ✅ Multiple device sizes
Perfect for documentation, design reviews, or showing stakeholders what the app actually looks like.
Level Up: Golden File Testing 🎯 #
Want automated visual regression testing? Enable golden comparison to catch unintended UI changes:
testWidgets('Golden comparison test', (tester) async {
await tester.pumpWidget(const MaterialApp(home: LoginScreen()));
await snap(
matchToGolden: true,
settings: SnaptestSettings.full([Devices.ios.iPhone16Pro]),
);
});
This does both:
- Saves a beautiful screenshot with real rendering and device frames to
.snaptest/ - Compares against golden files to fail the test if UI changes unexpectedly
When golden tests fail due to intentional changes, update them:
flutter test --update-goldens
All the Options 🛠️ #
Multiple screenshots per test #
testWidgets('User flow', (tester) async {
await tester.pumpWidget(const MaterialApp(home: MyPage()));
await snap('initial_state');
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
await snap('after_tap');
});
Capture specific widgets #
await snap(
name: 'just_the_card',
from: find.byKey(const Key('my-card')),
);
Global settings for all tests #
void main() {
setUpAll(() {
SnaptestSettings.global = SnaptestSettings.full([
Devices.ios.iPhone16Pro,
]);
});
// All snap() calls now use iPhone 16 Pro with real rendering
}
All snap() parameters #
await snap(
name: 'custom_name', // Custom filename
from: find.byKey(key), // Specific widget to capture
settings: SnaptestSettings(), // Override global settings
pathPrefix: 'screenshots/', // Custom directory (default: '.snaptest/')
goldenPrefix: 'goldens/', // Golden files directory (default: 'goldens/')
appendDeviceName: false, // Don't append device name to filename
matchToGolden: true, // Enable golden file comparison
);
Settings Reference 📋 #
SnaptestSettings options: #
devices: List of devices to test on (default:[WidgetTesterDevice()])blockText: Whether to block text rendering for consistency (default:true)renderImages: Whether to render actual images (default:false)renderShadows: Whether to render shadows (default:false)includeDeviceFrame: Whether to include device frame around content (default:false)
Convenience constructors: #
SnaptestSettings(): Default settings - blocked text, no images/shadows/framesSnaptestSettings.full(devices): Real rendering - actual text, images, shadows, and device frames
Helper Scripts 🔧 #
Clean all screenshots:
dart run snaptest:clean
Assemble screenshots into a single directory:
dart run snaptest:assemble
Font Limitations ⚠️ #
Due to Flutter's test environment limitations:
- iOS system fonts are replaced with Roboto for consistency
- Google Fonts only work if bundled as local assets (not fetched remotely)
- Custom fonts must be included in your
pubspec.yaml
This ensures consistent screenshots across environments, but may differ slightly from your actual app.