From 696a5633c87c0451a12664ba3472acfa32037a4e Mon Sep 17 00:00:00 2001 From: Moshe Immerman Date: Tue, 28 Jul 2026 16:18:39 +0300 Subject: [PATCH] fix(parsers): Render warned test nodes with warning status Keep warned nodes visually consistent with summary status while preserving failure precedence over warnings. --- testrunner/parsers/failure_format_test.go | 38 +++++++++++++++++++++++ testrunner/parsers/types.go | 6 ++++ 2 files changed, 44 insertions(+) diff --git a/testrunner/parsers/failure_format_test.go b/testrunner/parsers/failure_format_test.go index 97be9938b..6fee2ce24 100644 --- a/testrunner/parsers/failure_format_test.go +++ b/testrunner/parsers/failure_format_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/flanksource/clicky" + "github.com/flanksource/clicky/api/icons" ) func TestParseFailureDetail_GomegaToHavePrefix(t *testing.T) { @@ -230,6 +231,43 @@ func TestPrettyUsesFailureDetailSummary(t *testing.T) { } } +// TestPrettyRendersWarnedNodeAmber guards the case a warned node used to fall +// through to the default (pass) branch: a green check rendered right next to the +// node's warning message, contradicting both the amber summary counter and the +// Warned doc contract. +func TestPrettyRendersWarnedNodeAmber(t *testing.T) { + test := Test{ + Name: "trace[watch]", + Warned: true, + Message: "start watch trace: deployment not found", + } + + rendered := clicky.MustFormat(test.Pretty()) + if strings.Contains(rendered, icons.Pass.Unicode) { + t.Errorf("a warned node must not render the pass icon, got %q", rendered) + } + if !strings.Contains(rendered, icons.Warning.Unicode) { + t.Errorf("expected the warning icon, got %q", rendered) + } + if !strings.Contains(rendered, "deployment not found") { + t.Errorf("expected the warning message, got %q", rendered) + } +} + +// TestPrettyFailedWinsOverWarned pins the precedence Sum() uses: a node that is +// both failed and warned is a failure, and must render red. +func TestPrettyFailedWinsOverWarned(t *testing.T) { + test := Test{Name: "step", Failed: true, Warned: true, Message: "boom"} + + rendered := clicky.MustFormat(test.Pretty()) + if !strings.Contains(rendered, icons.Fail.Unicode) { + t.Errorf("a failed node stays red even when warned, got %q", rendered) + } + if strings.Contains(rendered, icons.Warning.Unicode) { + t.Errorf("a failure must not be downgraded to a warning, got %q", rendered) + } +} + func TestPrettyFallsBackToRawMessageWhenNoDetail(t *testing.T) { test := Test{ Name: "weird", diff --git a/testrunner/parsers/types.go b/testrunner/parsers/types.go index c1f76376e..5c46870f6 100644 --- a/testrunner/parsers/types.go +++ b/testrunner/parsers/types.go @@ -247,6 +247,12 @@ func (t Test) Pretty() api.Text { case t.Failed: s = s.Append(icons.Fail, "text-red-500") textStyle = "text-red-500" + // A warned node completed with a non-blocking problem. Without this branch it + // falls through to the pass icon and renders a green check next to its warning + // message — the summary line counts it amber, so the tree must agree. + case t.Warned: + s = s.Append(icons.Warning, "text-amber-500") + textStyle = "text-amber-500" default: s = s.Add(icons.Pass) }