Skip to content

fix(a11y): contrast --fail-only reports failure count as total, add sampled field - #167

Merged
ractive merged 1 commit into
mainfrom
iter-127/a11y-contrast-fail-only-total
Jul 19, 2026
Merged

fix(a11y): contrast --fail-only reports failure count as total, add sampled field#167
ractive merged 1 commit into
mainfrom
iter-127/a11y-contrast-fail-only-total

Conversation

@ractive

@ractive ractive commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • Honest total: under --fail-only, the a11y contrast envelope's top-level total reported the in-page JS summary.total sample size (e.g. 4 or 500) instead of the number of returned failures (0 or 447). The total_count.max(total) conflation in a11y_contrast::run mixed two populations (sampled elements vs returned failures). total now counts returned results: post-filter/pre-limit failures under --fail-only, all checks otherwise.
  • --limit no longer shrinks total: a --limit truncates results (with truncated: true) but total still reports the full failure count.
  • New sampled field: the JS sample size (elements examined) moves to its own top-level sampled key, so total == sampled without --fail-only and the envelope shape stays stable across flag combinations. meta.summary (aa_pass/aa_fail/capped) is untouched.
  • Extracted apply_fail_only_filter as a pure, testable helper; help text (args.rs) documents total vs sampled with a backward-compat note that total previously reported the sample size.

Discovered in dogfooding-session-61; plan: kb/iterations/iteration-127-a11y-contrast-fail-only-total.md.

Test plan

  • Unit: fail_only_all_passing_reports_zero_total_and_sample_size (sampled=4, failures=0 → total==0, results==[], sampled==4)
  • Unit: fail_only_reports_failure_count_not_sample_size (sampled=500, failures=447 → total==447, sampled==500)
  • Unit: without_fail_only_total_equals_sampled, fail_only_filter_uses_large_threshold_for_large_text
  • e2e: a11y_contrast_fail_only_filters_passing_checks updated (total==0, sampled==2); new a11y_contrast_without_fail_only_total_equals_sampled
  • Live (PASS against real Firefox): live_a11y_contrast_fail_only_total_zero, live_a11y_contrast_fail_only_total_counts_failures, live_a11y_contrast_limit_keeps_total
  • cargo fmt / cargo clippy --workspace --all-targets -- -D warnings / cargo test --workspace -q clean
  • cargo run -p xtask -- check-iteration-ready 10/10 PASS

🤖 Generated with Claude Code## Claims vs code
<generated 2026-07-19T16:16:44Z by ralph-loop>

No claims extracted from commit messages.

…ampled

Under --fail-only the envelope's top-level `total` reported the JS
`summary.total` sample size (e.g. 4 or 500) instead of the actual number
of returned failures (0 or 447), so any consumer asserting "page has N
contrast failures" got a lie. The `total_count.max(total)` conflation in
a11y_contrast::run mixed two populations (sampled elements vs returned
failures).

- `total` now counts returned results: post-filter/pre-limit failures
  under --fail-only, all checks otherwise. A --limit truncates `results`
  but `total` still reports the full count (with truncated: true).
- New top-level `sampled` field carries the JS sample size (elements
  examined), so total == sampled without --fail-only and the shape stays
  stable across flag combinations. meta.summary is untouched.
- Extracted apply_fail_only_filter as a pure, testable helper.
- Help text (args.rs) documents total vs sampled with a backward-compat
  note that total previously reported the sample size.

Tests: unit tests pinning sampled=4/failures=0 -> total=0 and
sampled=500/failures=447 -> total=447; e2e parity test for
total==sampled without --fail-only; three live AC tests
(live_a11y_contrast_fail_only_total_zero,
live_a11y_contrast_fail_only_total_counts_failures,
live_a11y_contrast_limit_keeps_total) all PASS against real Firefox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ractive
ractive merged commit ac3cd30 into main Jul 19, 2026
10 checks passed
@ractive
ractive deleted the iter-127/a11y-contrast-fail-only-total branch July 19, 2026 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant