// SPDX-License-Identifier: AGPL-3.0-or-later package web import ( "bytes" "strings" "testing" "github.com/a-h/templ" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func renderToString(t *testing.T, c templ.Component) string { t.Helper() var b bytes.Buffer require.NoError(t, c.Render(t.Context(), &b)) return b.String() } // A live banner is the content of a status region that stays in the page: the // empty slot of the page and the fragment of the stream are the same element // (same id, role and marker), so that ermiteLive can replace the children and // leave the region where a screen reader watches it. func TestLiveSlotsAreStableStatusRegions(t *testing.T) { t.Parallel() for _, tt := range []struct { name string c templ.Component id string text string }{ {"empty commits slot", LiveSlot("commits-head"), "commits-head", ""}, {"empty mr slot", LiveSlot("mr-notice"), "mr-notice", ""}, {"commits banner", CommitsBanner("2 new commits — reload", "/x/commits/main"), "commits-head", "2 new commits — reload"}, {"mr notice", MRNotice("a comment was added — reload", "/x/merge-requests/1"), "mr-notice", "a comment was added — reload"}, } { t.Run(tt.name, func(t *testing.T) { t.Parallel() got := renderToString(t, tt.c) assert.True(t, strings.HasPrefix(got, `
`), got) if tt.text == "" { assert.True(t, strings.HasSuffix(got, "data-slot>
"), "an empty slot has no child: %s", got) } else { assert.Contains(t, got, tt.text) } assert.True(t, strings.HasSuffix(got, ""), got) }) } } // The header's refs button is a link to the refs page, which the script turns // into the dialog; the filters and the buttons that need scripts are marked. func TestShellDegradesWithoutScripts(t *testing.T) { t.Parallel() l := Layout{Repo: "demo", Ref: "main", Short: "abc1234", Assets: Assets{}} got := renderToString(t, Header(l)) assert.Contains(t, got, `