ff_golden_presenter 1.0.4 copy "ff_golden_presenter: ^1.0.4" to clipboard
ff_golden_presenter: ^1.0.4 copied to clipboard

Collect, optimize, and publish golden test images as a searchable HTML report.

FF Golden Presenter #

ff_golden_presenter on pub.dev · ff_golden runner · Documentation · GitHub

FF Golden Presenter is the reporting companion to the ff_golden runner. It turns Flutter and Dart golden test images into a searchable, portable HTML report. It can also collect screenshots into an isolated staging directory, optimize PNG files, and produce the complete publication artifact in one command.

The generated page has no runtime dependencies. Open it locally, attach the whole directory to CI, or serve it as a static site. It includes scenario navigation, search and variant filters, remembered light/dark themes, responsive cards, a keyboard-friendly lightbox, and relative image URLs.

Quick start #

Add FF Golden Presenter to the Flutter or Dart project that owns the golden tests as a project-local development dependency:

flutter pub add --dev ff_golden_presenter

Use dart pub add --dev ff_golden_presenter in a pure Dart project. Commit the application pubspec and lockfile so developers and CI resolve the same version.

Build a publication directory from the conventional test/screens tree:

dart run ff_golden_presenter build \
  --input test/screens \
  --manifest build/ff_golden \
  --output-directory build/golden-report \
  --profile balanced \
  --clean

The result is self-contained:

build/golden-report/
├── index.html
└── feature/golden/scenario/*.png

--manifest accepts a schema-v1/v2 ff_golden.run file or a directory of runner shards. The default is build/ff_golden; a missing default is harmless. When manifests are present, the report exposes authoritative capture, device, theme, locale, text-scale, direction, platform, brightness, contrast, status, duration, and failure information as searchable badges and filters.

build always optimizes the copied files, never the source goldens. The balanced profile uses pngquant when available and falls back to ImageMagick. Check the machine before the first run:

dart run ff_golden_presenter doctor --profile balanced

To install the compatible tool reported for macOS, Linux, or Windows, opt in explicitly:

dart run ff_golden_presenter doctor --profile balanced --install-tools

No optimizer is required when byte-for-byte copies are preferred:

dart run ff_golden_presenter build --profile none --clean

The equivalent manual dependency is:

dev_dependencies:
  ff_golden_presenter: ^1.0.4

For an unreleased repository revision, use the package Git source and path: packages/ff_golden_presenter. For a local checkout, use path: ../golden/packages/ff_golden_presenter.

Renaming from golden_presenter #

The package and primary executable are now named ff_golden_presenter to match the Flutter Files infrastructure family such as ff_bloc:

import 'package:ff_golden_presenter/ff_golden_presenter.dart';
dart run ff_golden_presenter build

This is a package-name migration, so update all three surfaces together: the dev_dependency key, package: imports, and dart run command. Dart resolves dart run golden_presenter as the old package name; an executable alias inside the renamed package cannot transparently preserve that command.

See MIGRATION.md for the complete presenter procedure. After bootstrapping the new dependency, the CLI can preview, apply, and verify the deterministic parts:

dart run ff_golden_presenter migrate --project .
dart run ff_golden_presenter migrate --project . --apply
dart run ff_golden_presenter migrate --project . --check

Actions #

Run dart run ff_golden_presenter --help for the action list and <action> --help for all flags.

Action Purpose
build Collect images, optimize staged PNG files, and create index.html.
collect Copy supported images recursively while preserving relative paths.
optimize Optimize PNG files already in a staging directory. Requires --in-place.
report Generate only the HTML file from an existing image tree.
doctor Detect compatible tools and print a platform-specific install command.
migrate Preview/apply safe package renames and report manual migration work.
clean-failures Delete generated comparison images below failures directories.

The original report-only invocation remains compatible:

dart run ff_golden_presenter \
  --input test \
  --output golden-report.html \
  --title "My app golden tests"

It is equivalent to dart run ff_golden_presenter report .... With no arguments it scans test/ and writes golden-report.html.

Publication flags #

The main build options are:

Option Default Purpose
-i, --input <directory> test/screens Source screenshots copied recursively.
-o, --output-directory <directory> build/golden-report Isolated publication directory.
--report-file <filename> index.html HTML file inside the publication directory.
-p, --profile <name> balanced none, lossless, balanced, or small.
--backend <name> auto auto, pngquant, oxipng, or imagemagick.
-j, --jobs <count> CPU count Maximum concurrent optimizer processes.
--clean off Remove the guarded output directory before copying.
--install-tools off Install a compatible missing optimizer.
--dry-run off Inspect the pipeline without writing or installing.
--title <text> Golden test report Heading displayed in the report.
--primary-color <color> built-in theme Accent color as CSS hex or Flutter 0xAARRGGBB.
--favicon <file> none PNG, SVG, ICO, JPEG, WebP, or GIF favicon embedded in the HTML.
--header-link <label=url> none Project navigation link displayed in the header; repeatable.
-g, --golden-directory <name> golden Directory marker used to discover scenarios.
--extensions <list> png,jpg,jpeg,webp,svg Image extensions copied and included.
--manifest <path> build/ff_golden Runner manifest file or shard directory; repeatable.
--[no-]support-attribution on Show or remove the ASO.dev support attribution in the report footer.

--clean refuses dangerous targets such as the filesystem root, home, repository root, input directory, or an ancestor of the input. Existing output is otherwise left intact unless the flag is passed.

Both build and report accept the same optional visual customization flags. For example, an ASO.dev report can reuse the Flutter project color and web favicon while linking back to the product and its blog:

dart run ff_golden_presenter build \
  --input test/screens \
  --output-directory goldens \
  --report-file index.html \
  --profile balanced \
  --clean \
  --title "ASO.dev Golden Tests" \
  --primary-color 0xFF18BFFB \
  --favicon apps/aso/web/favicon.png \
  --header-link "Home=https://aso.dev/" \
  --header-link "Blog=https://aso.dev/blog/"

--primary-color accepts #RGB, #RRGGBB, #RRGGBBAA, bare RRGGBB, and Flutter's 0xAARRGGBB notation. Each --header-link uses the first = as the label/URL separator, so query parameters remain intact. External http and https links open in a new tab; relative links remain in the current tab. Unsafe schemes such as javascript: are rejected. The favicon is encoded as a data URL inside the generated HTML, so no extra icon file needs to be copied to the publication directory.

Cleaning failure images #

Flutter's local golden comparator writes diagnostic PNGs into failures directories. Preview and remove those generated images explicitly:

dart run ff_golden_presenter clean-failures \
  --input test/screens \
  --dry-run

dart run ff_golden_presenter clean-failures \
  --input test/screens

The command deletes only configured image extensions below directories named exactly failures. It does not follow symlinks, remove non-image diagnostics, or touch files elsewhere. Filesystem root and home-directory inputs are rejected. Pass --extensions png,jpg,jpeg,webp to change the default PNG-only selection.

Published reports include a visible “Made by the ASO.dev team” footer by default. The link is marked as sponsored and includes a referral source. Projects that require an unbranded report can pass --no-support-attribution; the FF Golden Presenter generator credit remains intact.

The generated <head> also includes description, Open Graph, and Twitter card metadata derived from the report title and catalog size.

Optimization profiles #

Profile Preferred backend Behavior
none none Copies images without changing them.
lossless oxipng Pixel-lossless PNG recompression; ImageMagick is the fallback.
balanced pngquant High-quality 75-95 quantization for normal publication.
small pngquant Stronger 55-80 quantization and slower compression.

Optimized output replaces a staged file only when it is smaller. Other formats are copied but not changed. To force a backend, pass --backend; incompatible combinations such as lossless + pngquant fail with a clear error.

Standalone optimization is intentionally explicit because it changes files:

dart run ff_golden_presenter optimize \
  --input build/golden-report \
  --profile lossless \
  --in-place

Use optimize --dry-run to inspect the PNG count without changing anything.

Tool support #

All processes are launched directly rather than through a shell, so paths and arguments work consistently on macOS, Linux, and Windows.

Platform Automatic installation used by --install-tools
macOS Homebrew packages for pngquant, oxipng, or ImageMagick; Cargo is an oxipng fallback.
Linux apt-get, dnf, or pacman for pngquant/ImageMagick; Cargo for oxipng.
Windows ImageMagick through winget; Cargo for oxipng. pngquant can also be installed manually.

doctor prints the exact command it would use and official manual-install links when no supported package manager is found. See the upstream installation pages for pngquant, oxipng, ImageMagick, and Windows Package Manager.

Expected directory and filename structure #

FF Golden Presenter collects every configured image format under --input, but the report includes only files below a directory named golden:

test/
└── screens/
    └── authentication/
        └── golden/
            └── sign_in/
                ├── iphone_15[light](en-US).png
                └── iphone_15[dark](en-US).png

The golden marker is removed from the displayed breadcrumb. The example becomes the authentication / sign_in scenario when test/screens is the input.

Runner variants use this filename convention by default:

[capture.]device[theme](locale){text-scale}{direction}{platform}{brightness}{contrast}.extension

Only device is required. Dots in device names, such as iPadPro12.9, are preserved. A filename alone cannot distinguish a dotted device from the optional multi-shot prefix, so ff_golden.run metadata is authoritative for capture names. Without a manifest, the complete prefix before the first structured suffix is treated as the device. Custom --device-pattern, --theme-pattern, and --locale-pattern values use Dart RegExp syntax and must contain a capture group.

Demo #

The repository contains a deterministic catalog under example/goldens. Regenerate the checked-in example/report.html:

Open the live FF Golden demo, rebuilt and deployed to GitHub Pages from the master branch.

./tool/generate_demo.sh

To exercise the full staging pipeline without an external optimizer:

dart run ff_golden_presenter build \
  --input example/goldens \
  --output-directory build/demo \
  --profile none \
  --clean \
  --title "FF Golden Presenter demo"

Docker publication #

The repository includes a multi-stage Dockerfile. Its generator stage creates the complete report, while the runtime stage contains only the static files and an unprivileged nginx server listening on port 8080.

Run the demo locally with one command:

docker compose up --build

Open http://localhost:8080. The image also exposes /healthz for container health checks.

For a Flutter project, copy Dockerfile, .dockerignore, and docker/nginx.conf, then build with project-specific arguments:

docker build \
  --build-arg SDK_IMAGE=ghcr.io/cirruslabs/flutter:stable \
  --build-arg "PUB_GET_COMMAND=flutter pub get" \
  --build-arg GOLDEN_INPUT=test/screens \
  --build-arg OPTIMIZATION_PROFILE=balanced \
  --build-arg INSTALL_TOOLS=true \
  --tag my-app-golden-report .

docker run --rm --publish 8080:8080 my-app-golden-report

Available build arguments:

Argument Default Purpose
SDK_IMAGE dart:stable SDK used by the generator stage.
PUB_GET_COMMAND dart pub get Dependency command; use flutter pub get for Flutter projects.
GOLDEN_INPUT example/goldens Screenshot directory inside the build context.
REPORT_TITLE FF Golden Presenter demo Generated page title.
OPTIMIZATION_PROFILE none Publication optimization profile.
OPTIMIZATION_BACKEND auto Explicit or automatically resolved optimizer.
OPTIMIZATION_JOBS 4 Concurrent optimization processes.
INSTALL_TOOLS false Allow the generator stage to install its optimizer.

The final image does not contain Dart, Flutter, package caches, source code, or optimizer binaries. The nginx configuration disables server-version disclosure, adds basic security headers, avoids caching index.html, and gives images a short cache lifetime.

CI/CD templates #

Copy-ready templates live under example/ci:

  • GitHub Pages builds the report and deploys it with the official Pages artifact flow.
  • GitHub Container Registry builds the Dockerfile and publishes commit plus latest tags to GHCR.
  • GitLab Pages publishes the generated public/ directory.
  • GitLab Container Registry builds and pushes commit plus latest container tags.

The templates target Flutter repositories and test/screens by default. For pure Dart projects, switch their setup step or SDK image as explained in the accompanying example/ci/README.md.

Migrating a project shell script #

A project no longer needs to copy files, check pngquant, or globally activate the package itself. Replace a pipeline like scripts/_build_golden.sh with the project-local command:

dart run ff_golden_presenter clean-failures --input test/screens

dart run ff_golden_presenter build \
  --input test/screens \
  --output-directory goldens \
  --report-file index.html \
  --profile balanced \
  --clean

Use --install-tools only on machines where the job is allowed to change system packages. For immutable CI images, run doctor and install the printed dependency in the image setup instead.

Legacy --path, -p, and --test-path remain accepted by the default/report-only command. New actions use -p for the optimization profile.

Use in CI #

Run the command after golden tests and upload the entire output directory as one artifact:

- name: Build golden publication
  run: >-
    dart run ff_golden_presenter build
    --input test/screens
    --output-directory build/golden-report
    --profile balanced
    --clean
- uses: actions/upload-artifact@v4
  with:
    name: golden-report
    path: build/golden-report

Project-local installation #

Keep the executable in project dev_dependencies. This makes the version part of the application lockfile and keeps local development and CI on the same toolchain. A global activation is intentionally not part of the supported repository workflow.

Development #

flutter pub get
cd packages/ff_golden_presenter
dart format --output=none --set-exit-if-changed .
dart analyze
flutter test
./tool/generate_demo.sh

The workspace contains the Flutter-based ff_golden package, so repository scripts use the Flutter-aware Pub runner. Consumer projects still invoke the installed executable with dart run ff_golden_presenter as shown above.

The public library entrypoint is package:ff_golden_presenter/ff_golden_presenter.dart; CLI implementation details live under lib/src/.

Project support #

FF Golden Presenter is part of the Flutter Files infrastructure and is developed with support from ASO.dev.

2
likes
0
points
283
downloads

Documentation

Documentation

Publisher

verified publisheraso.dev

Weekly Downloads

Collect, optimize, and publish golden test images as a searchable HTML report.

Homepage
Repository (GitHub)
View/report issues

Topics

#cli #docker #golden-tests #html #image-optimization

License

unknown (license)

Dependencies

args, path

More

Packages that depend on ff_golden_presenter