wiser-technology-solutions/rx_bloc/golden-test

Claude Code and agent skill by wiser-technology-solutions/rx_bloc

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Create Golden tests for an existing feature - Deterministic, convention-compliant golden test generation for feature pages

Install

npx vskill@latest install wiser-technology-solutions/rx_bloc/golden-test

SKILL.md

Create Golden Tests for a Feature

This skill guides the AI agent in creating golden tests for Flutter feature pages, adhering strictly to the established architecture and patterns.

Reference implementation: test/feature_profile/ — this is the canonical example

Inputs Required

To successfully execute this skill, the following inputs MUST be provided:

  1. Feature name: A feature name or its project path (e.g., feature_profile or lib/feature_profile)

Core Principle

Convention conformance > Visual coverage > Quantity

Every golden test must follow the exact patterns from the reference implementation. The agent must understand the infrastructure before generating any test.

Scope

Golden tests cover whole pages/screens only.

  • One golden test file per page
  • Placed in test/feature_<name>/view/
  • Individual UI components do NOT require separate golden tests

Infrastructure Overview

Package

The project uses the Alchemist package (package:alchemist/alchemist.dart).

Global Config: test/flutter_test_config.dart
  • File path resolution: Strips _light / _dark suffix from the scenario name and routes the .png into goldens/light_theme/ or goldens/dark_theme/
  • Comparator: ProcreditFileComparator with 0% tolerance
  • MaterialApp wrapper: Wraps with ProI18n, I18n, GlobalMaterialLocalizations and DesignSystem.fromBrightness(Brightness.light) theme
  • Default locale: Locale('bg')

You never specify a path to goldens/ manually. The scenario name + theme enum determine the output path automatically.

Theme Enum: test/helpers/enums/app_themes.dart
dart
enum Themes {
light,
// dark, (currently disabled)
}
Default Devices: test/helpers/golden_helper.dart

Every golden renders across 7 devices:

DeviceSizePixel RatioSafe Area
iPhone SE (2nd gen)375×6672.0top: 20
Google Pixel 4a412×7321.0none
iPhone 13 mini375×8123.0top: 44, bottom: 34
Google Pixel 5393×8512.75top: 24, bottom: 48
Samsung Galaxy S20412×9153.0top: 24, bottom: 48
Samsung Galaxy Tab S61280×8002.0top: 24, bottom: 48
Apple iPad Pro 12.91024×13662.0top: 24, bottom: 34

Directory Structure (MANDATORY)

test/feature_<name>/
├── factory/ # Widget factories for golden tests
│ └── <page_name>_factory.dart
├── mock/ # Mockito mock factories + generated files
│ ├── <bloc_name>_mock.dart
│ └── <bloc_name>_mock.mocks.dart # Auto-generated by build_runner
└── view/ # Golden test files + generated images
├── goldens/
│ └── light_theme/
│ └── <scenario_name>.png # Auto-generated by --update-goldens
└── <page_name>_golden_test.dart
  • NEVER manually create or move .png files
  • Dark theme images go in goldens/dark_theme/ (when enabled)

File Naming Conventions (MANDATORY)

ArtifactPatternExample
Golden test file<page_snake_case>_golden_test.dartprofile_golden_test.dart
Factory file<page_snake_case>_factory.dartprofile_factory.dart
Mock file<bloc_snake_case>_mock.dartprofile_mock.dart
Generated mock<bloc_snake_case>_mock.mocks.dartprofile_mock.mocks.dart
Golden image<scenario_name>.png (auto-resolved)profile_success.png

Scenario Naming (MANDATORY)

The scenario name passed to Scenario(name: '...') becomes the golden filename.

Format:
<page_prefix>_<state>[_<variant>]
Rules:
  • Always snake_case
  • Start with the page prefix (e.g., profile_, branch_network_page_)
  • End with the state/variant (e.g., _success, _loading, _error)
  • Must be unique across the test file
  • The _light / _dark suffix is appended automatically — never add it yourself
Examples:
Scenario NameMeaning
profile_successdefault success state
profile_success_toggledsuccess with biometrics/notifications enabled
profile_loadingloading state
profile_errorerror state

Step-by-Step Execution Plan

1. Analysis Phase (Before Generating)

Before generating golden tests for any feature, the agent MUST:

  • [ ] Read lib/feature_<name>/views/ to identify the page and its UI states
  • [ ] Read lib/feature_<name>/di/ to identify all provider dependencies
  • [ ] Read lib/feature_<name>/blocs/ to identify all BLoC state streams
  • [ ] Read test/feature_<name>/ to inventory existing test coverage
  • [ ] Check test/mocks/stubs.dart for available test data
  • [ ] Check test/mocks/ and test/base/ for existing shared mock factories
  • [ ] Verify all required mocks exist or plan their creation
  • [ ] Enumerate all scenarios following the naming convention
2. Create BLoC Mock Factories

In test/feature_<name>/mock/<bloc>_mock.dart:

dart
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:procredit/<feature>/blocs/<bloc>.dart';
import 'package:rx_bloc/rx_bloc.dart';
import 'package:rxdart/rxdart.dart';
import '<bloc>_mock.mocks.dart';
@GenerateMocks([<Bloc>BlocStates, <Bloc>BlocEvents, <Bloc>BlocType])
<Bloc>BlocType <bloc>MockFactory({
Result<MyDomainModel>? dataResult,
bool? someToggle,
// ... all state parameters
}) {
final blocMock = Mock<Bloc>BlocType();
final eventsMock = Mock<Bloc>BlocEvents();
final statesMock = Mock<Bloc>BlocStates();
when(blocMock.events).thenReturn(eventsMock);
when(blocMock.states).thenReturn(statesMock);
// Wire each state stream
when(statesMock.dataResult).thenAnswer(
(_) => dataResult != null ? Stream.value(dataResult) : const Stream.empty(),
);
when(statesMock.someToggle).thenAnswer(
(_) => someToggle != null ? Stream.value(someToggle) : const Stream.empty(),
);
// ... wire all remaining states ...
return blocMock;
}
Critical Mock Rules:
  • @GenerateMocks goes in the mock file, never in the test or factory file
  • Every state exposed by the BLoC's States class must be wired (prevents MissingStubError)
  • Null/absent parameters should emit const Stream.empty()
  • Run dart run build_runner build after creating/modifying mock files
Stream wiring conventions:
Stream typePattern
Simple fire-once (errors, loading)Stream.value(x) or const Stream.empty()
States needing replay (dialogs, toggles).publishReplay(maxSize: 1)..connect()
States needing sharing.share() or .shareReplay(maxSize: 1)
3. Create Widget Factory

In test/feature_<name>/factory/<page>_factory.dart:

dart
import 'package:flutter/material.dart';
import 'package:flutter_rx_bloc/flutter_rx_bloc.dart';
import 'package:procredit/<feature>/blocs/<bloc>.dart';
import 'package:procredit/<feature>/views/<page>.dart';
import 'package:provider/provider.dart';
import 'package:rx_bloc/rx_bloc.dart';
import '../mock/<bloc>_mock.dart';
Widget <page>Factory({
Result<MyDomainModel>? dataResult,
bool? someToggle,
// ... all state parameters
}) => Scaffold(
body: MultiProvider(
providers: [
RxBlocProvider<MyFeatureBlocType>.value(
value: myFeatureMockFactory(
dataResult: dataResult,
someToggle: someToggle,
),
),
// ... all required providers
],
child: const <Page>(),
),
);
Critical Factory Rules:
  • Use expression body (=> Scaffold(...)) — no block body, no local variables
  • Accept optional/named parameters for each UI state dimension
  • Parameters map 1:1 to BLoC state streams
  • Wrap the page in Scaffold body
  • Provide all required BLoC providers via MultiProvider + RxBlocProvider<T>.value
Factory MUST NEVER:
  • Import package:mockito/mockito.dart
  • Import ../../mocks/stubs.dart
  • Contain when() / thenAnswer() / thenReturn() calls
  • Instantiate real services
  • Contain any stubbing logic
4. Create Golden Test File

In test/feature_<name>/view/<page>_golden_test.dart:

dart
import 'package:procredit/base/models/...'; // Domain model imports as needed
import 'package:rx_bloc/rx_bloc.dart';
import '../../helpers/golden_helper.dart';
import '../../helpers/models/scenario.dart';
import '../../mocks/stubs.dart';
import '../factory/<page>_factory.dart';
void main() {
runGoldenTests([
generateDeviceBuilder(
widget: <page>Factory(
dataResult: Result.success(Stubs.mockModel),
),
scenario: Scenario(name: '<page>_success'),
),
generateDeviceBuilder(
widget: <page>Factory(
dataResult: Result.loading(),
),
scenario: Scenario(name: '<page>_loading'),
),
generateDeviceBuilder(
widget: <page>Factory(
dataResult: Result.error(Stubs.error),
),
scenario: Scenario(name: '<page>_error'),
),
]);
}
Key API:
  • runGoldenTests(List<ScenarioBuilder>) — iterates over all Themes.values, calls goldenTest for each scenario+theme
  • generateDeviceBuilder(widget:, scenario:) — renders the widget across all 7 default devices
  • Optional parameters: customPumpBeforeTest, customDeviceHeight, locale
setUp() usage:

If the page requires global setup (e.g., isTest = true, VisibilityDetectorController), add a setUp() block before runGoldenTests:

dart
void main() {
setUp(() {
isTest = true;
});
runGoldenTests([...]);
}

Test Data Rules

ALL test data MUST come from test/mocks/stubs.dart

This includes:

  • Model instances (e.g., Stubs.profile, Stubs.error)
  • Strings, numbers, IDs
  • Lists and collections
Also use:
  • ProfileModel.withDefaults() for default profile data
  • Result.success(data), Result.loading(), Result.error(Stubs.error) for state wrappers
  • LoadingWithTag(loading: true) for loading states
Forbidden:
  • Inline model construction in test or factory files
  • Hardcoded literals in test or factory files
  • If new data is needed, add it to stubs.dart first

State Coverage Matrix

For every page, the agent MUST enumerate and cover:

DimensionValues
Data statesuccess, loading, error, empty (if applicable)
Interaction stateexpanded/collapsed, toggled on/off, selected/unselected
Edge casesmissing optional data, overlay/modal visible
Themelight (+ dark when enabled in Themes enum)
Localebg (default); add others only if layout visually differs

Create one generateDeviceBuilder call per unique combination that produces a visually distinct render.

Do NOT create scenarios for combinations that render identically.

Forbidden Actions

  • NEVER manually create, rename, or move .png golden files
  • NEVER use @GenerateMocks inside a test file or factory file
  • NEVER put when() / thenAnswer() / thenReturn() calls inside a factory file
  • NEVER import package:mockito/mockito.dart in a factory file
  • NEVER import stubs.dart in a factory file
  • NEVER instantiate real services inside a factory file
  • NEVER use block body ({ return ... }) in a factory — use expression body (=>)
  • NEVER define test data inline in test files
  • NEVER add _light or _dark suffix to scenario names
  • NEVER skip wiring a state stream in the mock factory

Reference: Key Import Paths

In golden test files:
dart
import '../../helpers/golden_helper.dart';
import '../../helpers/models/scenario.dart';
import '../../mocks/stubs.dart';
import '../factory/<page>_factory.dart';
import 'package:rx_bloc/rx_bloc.dart'; // Result, LoadingWithTag
In factory files (NO mockito, NO stubs):

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
67
Repository forks
20
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/wiser-technology-solutions/rx_bloc/golden-test/badge)](https://verified-skill.com/skills/wiser-technology-solutions/rx_bloc/golden-test)

Something wrong with this skill or its page? Tell us.