package web
import (
"strings"
"testing"
)
// The run page's steps are the SAME <details class="d-row"> markup the
// landing's decision card draws. Those row rules were scoped to
// .l-decide, so the run page got none of them: padding 0, summary still
// display:list-item, and the browser's own disclosure triangle beside a
// status icon already saying the same thing.
//
// A rule that describes a ROW must not be scoped to one page that has
// rows.
func TestTheRowRulesAreNotScopedToOnePage(t *testing.T) {
for _, rule := range []string{
".d-row { display: block; padding:",
".d-row > summary { list-style: none;",
".d-row > summary::-webkit-details-marker { display: none; }",
} {
if !strings.Contains(sheetLiteral, rule) {
t.Errorf("FAIL: %q is missing — a row somewhere is drawing unstyled", rule)
} else {
t.Logf("ok: %s applies wherever a row is drawn", strings.TrimSpace(rule))
}
}
// Scoped copies are what caused this, so they must be gone.
for _, gone := range []string{
".l-decide .d-row { display: block; padding:",
".l-decide .d-row summary { list-style: none;",
} {
if strings.Contains(sheetLiteral, gone) {
t.Errorf("FAIL: %q is back — the run page loses it again", gone)
}
}
// What is genuinely the decision card's stays the decision card's.
if !strings.Contains(sheetLiteral, ".l-decide .d-row { border-bottom:") {
t.Error("FAIL: the decision card lost the divider between its rows")
} else {
t.Log("ok: the decision card keeps its own divider")
}
}
// The steps read as one list rather than a row of floating cards, and
// carry the affordance the hidden native triangle used to be.
func TestTheStepsAreOneListWithACaret(t *testing.T) {
data := pageData{Repo: "quarry", CIRunView: &ciRunView{
Anchor: "abc123abc123",
Steps: []ciStepView{
{ID: "test", Status: "completed", State: "pass", Duration: "19s"},
{ID: "fmt", Status: "completed", State: "pass", Duration: "2s"},
},
}}
var buf strings.Builder
if err := noHooks.template(ciRunPage).ExecuteTemplate(&buf, "run-steps", data); err != nil {
t.Fatal(err)
}
got := buf.String()
if !strings.Contains(got, `<div class="runsteps">`) {
t.Error("FAIL: the steps are not gathered into one list")
} else {
t.Log("ok: the steps are one list")
}
if n := strings.Count(got, `class="ic d-caret"`); n != 2 {
t.Errorf("FAIL: %d carets for 2 steps", n)
} else {
t.Log("ok: every step says it opens")
}
if !strings.Contains(sheetLiteral, ".runstep[open] .d-caret { transform: rotate(180deg); }") {
t.Error("FAIL: the caret does not turn, so it says the same thing open and shut")
} else {
t.Log("ok: the caret turns when the step opens")
}
// A run with no steps draws no empty list box.
var empty strings.Builder
if err := noHooks.template(ciRunPage).ExecuteTemplate(&empty, "run-steps",
pageData{Repo: "quarry", CIRunView: &ciRunView{Anchor: "abc"}}); err != nil {
t.Fatal(err)
}
if strings.Contains(empty.String(), "runsteps") {
t.Error("FAIL: a run with no steps still draws the list's border")
} else {
t.Log("ok: no steps, no empty box")
}
}