snaptest 0.1.0 copy "snaptest: ^0.1.0" to clipboard
snaptest: ^0.1.0 copied to clipboard

Snap photos in your widget tests.

Snaptest #

[Code Coverage] melos lints by lintervention

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:

  1. Saves a beautiful screenshot with real rendering and device frames to .snaptest/
  2. 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/frames
  • SnaptestSettings.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.