Skip to content

[Visual Test] Golden image is completely black, causing compare_visual_golden.sh to refuse comparison #962

Description

@MichaelFisher1997

The automated visual test workflow failed at the golden-image comparison step. The screenshot capture itself works correctly, but the comparison never runs because the baseline image is invalid.

What failed

scripts/compare_visual_golden.sh exits 1 with:

Golden screenshot is effectively black (mean 0); refusing an invalid visual comparison

The check at the top of the script (require_non_black_image) aborts before any RMSE comparison:

# scripts/compare_visual_golden.sh:22-28
require_non_black_image() {
    local image=$1
    local label=$2
    local mean
    mean=$(magick "$image" -colorspace RGB -format '%[fx:mean]' info:)
    if awk -v value="$mean" 'BEGIN { exit !(value <= 0.0001) }'; then
        printf '%s is effectively black (mean %s); refusing an invalid visual comparison\n' "$label" "$mean" >&2
        exit 1
    fi
}

Verified locally with ImageMagick:

$ magick docs/visual-test/golden/menu.png -colorspace RGB -format 'mean=%[fx:mean] max=%[fx:maxima] min=%[fx:minima]\n' info:
mean=0 max=0 min=0

The committed golden docs/visual-test/golden/menu.png (332 bytes, 1920x1080, 1-bit grayscale) is a fully-black PNG.

Why this trips the workflow

.github/workflows/visual-test.yml:99-105 runs the comparison unconditionally whenever screenshot.png exists:

- name: Compare against golden image
  id: golden_diff
  if: steps.check_screenshot.outputs.screenshot_exists == 'true'
  run: |
    nix shell nixpkgs#imagemagick -c bash scripts/compare_visual_golden.sh screenshot.png docs/visual-test/golden/menu.png visual-diff.png
  env:
    VISUAL_DIFF_RMSE_TOLERANCE: "0.015"

The script's pre-check refuses to compare against any image whose mean pixel value is <= 0.0001 (effectively black). The committed golden hits that guard, so the job exits 1 and failure() becomes true, which triggers the diagnose step (Run opencode failure diagnosis, line 148).

A locally produced screenshot.png (rendered with the same Lavapipe + Weston + ZIGCRAFT_SAFE_RENDER=1 setup the workflow uses) renders the menu UI correctly and has mean=0.00889345 — well above the guard — so the failure is not on the capture side, only on the baseline.

Additional observation

build-output.log was not present in the workspace when the diagnose agent ran (only weston.log, an empty logs/ directory, and the existing zig-out/ from prior builds). That points at the Run menu screenshot capture step in .github/workflows/visual-test.yml:73-87 failing before the tee in .github/actions/run-with-log/action.yml:33 could create the log file, or the log having been cleaned up between steps. Either way, the actual terminal failure the workflow surfaces is the golden-image guard above, not anything inside the screenshot capture pipeline.

Suggested fix

Regenerate the baseline so it is not all-black:

  1. Run the capture command locally (matches the workflow):
    mkdir -p /tmp/runtime-runner && chmod 700 /tmp/runtime-runner
    export XDG_RUNTIME_DIR=/tmp/runtime-runner WAYLAND_DISPLAY=headless \
           ZIGCRAFT_SAFE_RENDER=1 ZIGCRAFT_SMOKE_FRAMES=5 \
           VK_ICD_FILENAMES=$(nix build --no-link --print-out-paths nixpkgs#mesa.drivers)/share/vulkan/icd.d/lvp_icd.x86_64.json \
           VK_LAYER_PATH=$(nix build --no-link --print-out-paths nixpkgs#vulkan-validation-layers)/share/vulkan/explicit_layer.d \
           VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
           VK_LAYER_SETTINGS_PATH=$PWD/.github/vulkan/vk_layer_settings.txt
    devenv shell --profile graphics -- weston --socket=headless --backend=headless-backend.so --width=1280 --height=720 &
    devenv shell --profile graphics -- zig build run -Dscreenshot-path=docs/visual-test/golden/menu.png -Dskip-present=true
  2. Confirm the regenerated PNG is non-black (magick ... -format '%[fx:mean]' info: returns a positive value).
  3. Commit the new docs/visual-test/golden/menu.png.

If the regenerated golden is intentionally a blank output (e.g., ZIGCRAFT_SAFE_RENDER=1 + ZIGCRAFT_SKIP_WORLD_UPDATE already disables world passes and the menu preview can't seed before the capture timeout), then the test needs a different shape — either a UI-only render path that fills the frame, or skip the regression test under safe-render mode and add a non-safe-render variant for golden regeneration.

Reference

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdocumentationImprovements or additions to documentationhotfixvisual-testIssues from automated visual regression tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions