install
source · Clone the upstream repo
git clone https://github.com/bruhmoment654/karto4ki
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/bruhmoment654/karto4ki "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude" ~/.claude/skills/bruhmoment654-karto4ki-claude && rm -rf "$T"
manifest:
.claude/ZOLOTO-SKILL.mdsource content
Zoloto — Golden Testing Library for Flutter
A convenient wrapper over Flutter golden tests. Automates multi-platform and multi-device golden testing: manages device configurations, themes, localization, fonts, and CI environments.
Package:
zoloto
Package dependencies: flutter_test, meta, octo_image
Quick Start
1. Setting up flutter_test_config.dart
Create
flutter_test_config.dart in the test directory root:
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:zoloto/zoloto.dart'; Future<void> testExecutable(FutureOr<void> Function() testMain) async { return Zoloto.runWithConfiguration( () async { TestWidgetsFlutterBinding.ensureInitialized(); await loadAppFonts(); await testMain(); }, config: ZolotoConfig( testCases: [ ZolotoTestCase( name: 'pixel_4', size: const Size(360, 760), theme: ZolotoTestingTheme( brightness: Brightness.light, backgroundColor: Colors.white, data: ThemeData.light(), mode: ThemeMode.light, ), ), ZolotoTestCase( name: 'iphone_14', size: const Size(390, 844), safeArea: const EdgeInsets.only(top: 47, bottom: 34), theme: ZolotoTestingTheme( brightness: Brightness.dark, backgroundColor: Colors.black, data: ThemeData.dark(), mode: ThemeMode.dark, ), ), ], // Dependencies wrapper (providers, DI, etc.) dependenciesWrapper: (child) => ProviderScope(child: child), ), ); }
2. Writing a golden test for a widget
import 'package:zoloto/zoloto.dart'; void main() { Zoloto.zolotoTestWidget<MyButton>( widgetBuilder: (context, testCase) => MyButton(onPressed: () {}), ); }
The golden file name is generated automatically from the type
T (MyButton -> my_button.png).
3. Test with custom name and state
Zoloto.zolotoTestWidget<MyButton>( widgetBuilder: (context, testCase) => MyButton( onPressed: () {}, isLoading: true, ), screenState: 'loading', // -> my_button_loading.png );
4. Full-screen test
Zoloto.zolotoTest( 'home_screen', widgetBuilder: (context, tester, testCase) { return HomeScreen(); }, setUp: (context, testCase) { // Mock setup for each testCase }, );
5. Controlling golden height
// Height based on device size (default) testHeight: TestHeight.basedOnDevice() // Height based on content (for scrollable lists) testHeight: TestHeight.basedOnContent( additionalInsets: EdgeInsets.only(top: 50, bottom: 50), ) // Fixed height testHeight: TestHeight.fixed(1200)
6. Advanced test via multiScreenGolden
testWidgets('animated widget', (tester) async { await Zoloto.multiScreenGolden( tester, 'animated_widget', widgetBuilder: (context, testCase) => AnimatedWidget(), customPump: (tester) async { await tester.pumpAndSettle(Duration(milliseconds: 500)); }, ); });
API Reference
Zoloto (main class)
| Method | Description |
|---|---|
| Runs tests with configuration via Zone |
| Full-screen golden test |
| Single widget golden test (name auto-generated from ) |
| Low-level multi-screen golden |
| Get current from Zone |
ZolotoConfig (configuration)
const ZolotoConfig({ required List<ZolotoTestCase> testCases, // Device list Widget Function(Widget)? dependenciesWrapper, // Dependencies wrapper ComparatorFactory comparatorFactory, // Comparator factory (default tolerance 10%) WidgetWrapperFactory appWrapperFactory, // Wrapper for platform tests WidgetWrapperFactory ciWrapperFactory, // Wrapper for CI (Ahem font) FileNameFactory fileNameFactory, // Golden file name factory TestCaseFileNameFactory testCaseFileNameFactory, // File name factory with device suffix PrimeAssets primeAssets, // Asset precaching bool shouldLoadFonts = true, // Load custom fonts bool enableRealShadows = true, // Render real shadows bool skipGoldenAssertion = false, // Skip golden comparison bool skipPlatformTests = false, // CI tests only })
Factory typedefs:
ComparatorFactory = LocalFileComparator Function(Uri testFile)WidgetWrapperFactory = WidgetWrapper Function(ZolotoTestCase testCase)FileNameFactory = String Function(String name)TestCaseFileNameFactory = String Function(String name, ZolotoTestCase testCase, bool isCi)PrimeAssets = Future<void> Function(WidgetTester tester)
ZolotoTestCase (device configuration)
const ZolotoTestCase({ required Size size, // Screen size (logical pixels) required String name, // Identifier ("pixel_4", "iphone_14") required ZolotoTestingTheme theme, // Theme double pixelRatio = 1.0, // Pixel density double textScale = 1.0, // Text scale EdgeInsets safeArea = EdgeInsets.zero, // SafeArea TargetPlatform platform = TargetPlatform.android, Iterable<LocalizationsDelegate>? localeOverrides, Iterable<Locale>? localizations, void Function()? setup, // Called before each use })
Has a
copyWith(...) method for creating copies with modified fields.
ZolotoTestingTheme (theme)
const ZolotoTestingTheme({ required ThemeData data, // Flutter ThemeData required ThemeMode mode, // light / dark / system required Brightness brightness, // Brightness required Color backgroundColor, // Golden file background })
TestHeight (golden height)
Sealed class with three variants:
| Variant | Description |
|---|---|
| Height from (default) |
| Content-adaptive (for scrollable views) |
| Fixed height |
WidgetTester Extensions
| Method | Description |
|---|---|
| Precaches images |
| Applies device settings, runs body, resets |
| Applies device settings |
| Resets device settings |
| Sets SafeArea |
Font Utilities
| Function / Constant | Description |
|---|---|
| Loads all fonts from FontManifest.json |
| Constant — CI font |
| Extension — returns style with Ahem font |
TestAssetBundle
Custom AssetBundle for tests — bypasses the 10KB asset size limit.
DefaultAssetBundle( bundle: TestAssetBundle(), child: widget, )
ZolotoFileComparator
Golden file comparator with tolerance threshold.
ZolotoFileComparator(testFile, toleranceThreshold: 0.1) // 10% by default
Network Image Mocks
| Class / Constant | Description |
|---|---|
| HTTP client mock, returns transparent PNG |
| HTTP request mock |
| HTTP response mock |
| Transparent 1x1 PNG in bytes |
Pump Utilities
| Function | Description |
|---|---|
| Returns PumpAction that pumps n times |
| Pumps once |
| |
| Precaches Image, FadeInImage, DecoratedBox, OctoImage |
| Pumps twice |
Golden File Structure
By default golden files are generated in:
goldens/ ├── ci/ <- CI tests (Ahem font, platform-independent) │ ├── pixel_4/ │ │ └── my_widget.png │ └── iphone_14/ │ └── my_widget.png ├── macos/ <- Platform-specific (macOS) │ ├── pixel_4/ │ │ └── my_widget.png │ └── iphone_14/ │ └── my_widget.png ├── linux/ <- Platform-specific (Linux) └── windows/ <- Platform-specific (Windows)
Important Notes
- Zone configuration —
is passed via Dart Zone, available globally throughZolotoConfigZoloto.configuration - Ahem font — CI tests use the Ahem font (black squares) so goldens are identical across all platforms
- Tolerance 10% — by default 10% difference between golden and result is allowed
- loadAppFonts() — must be called before tests to load custom fonts
- dependenciesWrapper — use it to wrap with DI containers, providers, etc.
- skipPlatformTests: true — if only CI goldens are needed (saves time)
- TestAssetBundle — automatically wrapped in
, bypasses 10KB limitdefaultAppWrapper