Display

Test Results

A four-state test report with derived progress, expandable suites, and readable failure stacks.

Preview in your theme

Loading preview…

"use client"

import * as React from "react"
import {
  AlertCircle,
  CheckCircle2,
  ChevronRight,
  CircleDashed,
  CircleMinus,
  FlaskConical,
  LoaderCircle,
  RotateCcw,
  XCircle,
} from "lucide-react"

Installation

npx shadcn@latest add https://ui.zyeon.ai/r/test-results.json

Prompt

Build a React + TypeScript + Tailwind "TestResults" component with
lucide-react icons and a zod contract.

Contract
- The zod schema is the single source of truth:
  { status: "loading" | "empty" | "error" | "ready"; heading: string;
    durationMs?: nonnegative number; errorMessage?: string;
    suites: { id, name, tests: { id, name,
      status: "passed" | "failed" | "skipped" | "running",
      durationMs?: nonnegative number,
      error?: { message, stack? } }[] }[] }.
- Export TestStatus, TestCaseResult, TestSuiteResult and TestResultsData from
  the contract. Component props extend inferred data with onRetry?: () => void,
  defaultExpandedSuiteIds?: string[], className and native section attributes.

Behavior
- Render four first-class branches: report-shaped loading skeleton, helpful
  empty panel, error panel with optional retry, and ready summary + suites.
- Derive status counts and the passed percentage from test cases rather than
  accepting duplicate summary data. When total === 0, return 0% and render the
  no-pass-rate message instead of a progressbar or pass claim; never divide by
  zero or display NaN.
- Failed suites start expanded unless the consumer provides explicit default
  suite ids. Every suite trigger is a real button with aria-expanded and
  aria-controls, keyboard focus, a screen-reader status label derived from the
  same status map as the visual icon, and a labelled region for its cases.
- The contract permits a suite with tests: []. Derive that suite as "No tests"
  with its own neutral icon and spoken label; never classify an empty suite as
  passed. Expanding it shows an explicit no-cases message.
- Show status, duration and optional failure details per case. Error stacks
  use a scrollable, focusable pre with preserved wrapping so long paths remain
  readable without breaking the card width.
- Respect prefers-reduced-motion for progress transitions, chevrons and the
  running spinner. Retry remains consumer-owned through onRetry.

Rendering & styling
- Use semantic tokens only: bg-card, bg-muted, text-muted-foreground,
  primary for passed/running emphasis, destructive for failures, border and
  ring. Do not hardcode status colors.
- Use cn() to merge className. Allow long suite, test and stack text to wrap;
  status chips and durations may wrap rather than forcing horizontal overflow.
- Give the progress track role=progressbar with a descriptive label,
  aria-valuemin=0, aria-valuemax=100 and the zero-safe percentage as
  aria-valuenow. Decorative icons are aria-hidden.

Customization levers
- Default disclosure: pass suite ids to open a targeted subset, or change the
  fallback from failure-first to all-collapsed without altering suite state.
- Summary density: remove status badges or duration while retaining the
  derived total and accessible progress label.
- Failure detail: add diff, stdout or retry metadata to the error object and
  render it beneath the message as sibling disclosure blocks.
- Status vocabulary: extend both the zod enum and the label/icon maps together
  if the runner distinguishes flaky, timed-out or cancelled cases.
- Layout: increase the stack max height for dedicated result pages, or reduce
  it for compact deployment checks; keep horizontal overflow inside the pre.

Concepts

  • Derived summary — counts and percentage come from the case array, so the header cannot disagree with the expanded evidence.
  • Zero-safe progress — a test report may legitimately contain no cases; omitting the rate in that boundary keeps the UI and ARIA semantics honest.
  • Empty is not passed — an empty suite and a report whose suites contain zero total cases get explicit no-test states, never a green check or a misleading completion percentage.
  • Failure-first disclosure — failed suites open by default, reducing the number of clicks between a red summary and its cause.
  • Accessible expansion — the button owns aria-expanded and aria-controls, while the revealed case list is a labelled region.
  • Status beyond color — every suite trigger announces its derived Passed, Failed, Skipped or Running label even though its compact visual cue is an icon.
  • Readable error evidence — stacks preserve line structure, wrap long tokens, scroll within a bounded area, and can receive keyboard focus.

On This Page