Skip to content

Colour the failure message when the terminal supports it #265

Description

@pftg

Follow-up to #264, which made the failure message legible. Colour is the next increment and is deliberately not in 2.0 — the structure had to land first, and colour on top of the old unlabelled-paths format would have been decoration on something unreadable.

Current output (after #264)

Screenshot does not match for 'changed': the change spans 100 of 6400 px (1.56% of the 80x80 image)
  changed region: [20.0,15.0,30.0,25.0] (left,top,right,bottom edges)
  judged against: no tolerance thresholds configured (any difference fails)
  baseline:           screenshots/changed.base.png
  actual:             screenshots/changed.png
  baseline annotated: screenshots/changed.base.diff.png
  actual annotated:   screenshots/changed.diff.png
  heatmap:            screenshots/changed.heatmap.diff.png

Readable, but uniform. Everything has the same visual weight, so the eye has no entry point — and this block sits directly above ~19 absolute backtrace frames.

What colour would carry

Not decoration — three specific jobs:

  • Separate the block from the backtrace. Half the original "reads as noise" complaint was that the artifact block was indistinguishable from stack frames. Relative paths helped (feat: make the failure message legible #264); dimming the labels would finish it.
  • Rank the numbers. The percentage is the number a human judges first; the raw pixel count is supporting detail.
  • Distinguish the artifact kinds. baseline vs actual is the one pairing a reader has to hold in their head, and colour does that faster than alignment.

Requirements

  • Respect NO_COLORno-color.org is the de-facto standard; presence of the variable, whatever its value, disables colour
  • Only when the stream is a TTY. $stderr.tty? — CI logs, files and pipes must stay plain. There is currently no tty?/isatty/NO_COLOR/escape-sequence handling anywhere in lib/ (grepped), so this is greenfield
  • Honour TERM=dumb
  • A config knob to force on/off, for users whose CI does render colour (GitHub Actions does) and who want it
  • No new dependency. Bare ANSI codes are a few lines; rainbow/pastel/colorize are not worth a runtime dep for this
  • The HTML reporter and the [snap_diff] N verified… summary line are separate surfaces — decide explicitly whether the summary gets colour too, rather than doing it by accident
  • Guard tests both directions: colour present on a TTY, absent when piped, when NO_COLOR is set, and when TERM=dumb. The absent-cases are the ones that break CI logs, so they matter more than the present-case

Accessibility

Colour must be additive, never load-bearing. Every distinction it makes must already be readable in the plain text — which is true of the current format, and must stay true. Around 8% of men have a red-green colour vision deficiency, and red/green is the obvious pairing for a diff tool.

Related: research/competitive-landscape.md records that colour-blind accessibility of diff artefacts was not assessed for any tool surveyed, and that none was observed documenting a colour-blind-safe palette. That gap applies to our own .diff.png annotations (currently a red rectangle) as much as to terminal output — worth a separate issue if anyone wants to take it on.

Prior art worth checking before implementing

RSpec, Minitest and RuboCop all colour test output and all handle the TTY/NO_COLOR/--no-color matrix already. Read how they detect rather than re-deriving it — RSpec in particular has had years of bug reports about colour leaking into CI logs.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions