Skip to content
quarry Artifact [2e97a2cd7b]
Login

Artifact [2e97a2cd7b]

Artifact 2e97a2cd7b84b2e178da212cf79ef6f820cbc63ebe5994a1d282c90bbe73975c:


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 := 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 := 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")
	}
}