package web
import (
"strings"
"testing"
)
// One language per control family. An underline means TAB and nothing
// else: when a section tab, a view toggle and a sidebar facet all wore
// the accent, the page gave the eye no way to tell them apart.
func TestSelectionSpeaksOneLanguagePerFamily(t *testing.T) {
rule := func(sel string) string {
i := strings.Index(sheet, sel)
if i < 0 {
t.Fatalf("no rule for %s", sel)
}
end := strings.Index(sheet[i:], "}")
if end < 0 {
t.Fatalf("unterminated rule for %s", sel)
}
return sheet[i : i+end]
}
// Toggles and facets carry no accent and no underline.
for _, sel := range []string{
"nav.seg-box a.here {", "nav.scopes a.here {",
"nav.toggle a.here {", ".t-rail a.here {", ".w-rail a.here {",
} {
body := rule(sel)
if strings.Contains(body, "--accent") {
t.Errorf("%s uses the accent; that is reserved for tabs and actions:\n%s", sel, body)
}
if strings.Contains(body, "inset") {
t.Errorf("%s draws an edge; underlines mean tab:\n%s", sel, body)
}
// Selection must not rest on colour alone (WCAG 1.4.1): a fill
// AND weight, so it survives greyscale.
if !strings.Contains(body, "font-weight: 600") {
t.Errorf("%s carries no weight, so selection is colour-only:\n%s", sel, body)
}
if !strings.Contains(body, "background:") {
t.Errorf("%s carries no fill:\n%s", sel, body)
}
}
// Segmented buttons wear the branch selector's chip, which is the
// base button fill — so a toggle looks like a button, not a tab.
if body := rule("nav.seg-box a.here {"); !strings.Contains(body, "var(--code-bg)") {
t.Errorf("a selected segment is not the button fill:\n%s", body)
}
// Tabs keep the underline.
if !strings.Contains(sheet, "nav.tabs a.here .ink") {
t.Error("tabs lost their ink underline")
}
}
// The selected state was visual only: .here is a class, and a screen
// reader got no indication which view was active.
func TestSelectedLinksAnnounceThemselves(t *testing.T) {
// Every visually-selected link must ANNOUNCE that state. Two ways
// are correct, and which one depends on what the control is: a link
// that says "you are here" carries aria-current; a two-state toggle
// carries aria-pressed, because "pressed" is what it is and
// "current" would be a lie about a control that does not navigate.
if n := strings.Count(baseHTML, `class="here"`); n > 0 {
bare := strings.Count(baseHTML, `class="here"`) -
strings.Count(baseHTML, `class="here" aria-current=`) -
strings.Count(baseHTML, `class="here" role="button" aria-pressed=`)
if bare > 0 {
t.Errorf("%d selected links announce neither aria-current nor aria-pressed", bare)
}
_ = n
}
// A tab navigates to another section; a toggle re-renders this one.
if !strings.Contains(baseHTML, `aria-current="page"`) {
t.Error("no tab announces itself as the current page")
}
}