rastrillo / fiesta Public

Drive the visible copy of the controls, now there are two

Every gallery page carries two copies of the theme and scheme controls since the sidebar shell: the pinned bar's and the phone's display settings menu's, one of them hidden at any width. chooseScheme clicked [rst-scheme] > summary with chromedp.Click, which waits for the first match to be visible, and the first is the display settings copy, display: none at 1280px. TestTheSchemeMenuRepaintsTheFrames waited out its three minutes on it after 'field: 7 frames loaded and painted' (reproduced at 992b61e: context deadline exceeded, 184s; the page has two [rst-scheme] > summary, the first 0px wide and not visible, the second in .ds-top__controls).

chooseScheme now finds the copy that checkVisibility() says is shown and keeps every query inside it (chromedp.FromNode): the summary clicked, the button waited for and clicked. A page with no visible copy fails by name rather than by timeout. TestTheSchemeMenuRepaintsTheFrames passes in 4s. No other helper in the gallery's a11y, keyboard, pages_a11y, gallery or prose tests picks the first of a duplicated control: the keyboard walks follow focus and the untagged tests read markup, not controls.

Gated with make ci in a detached /var/tmp worktree at 992b61e with only this file copied in, every role green.
Human

Prompt

Fix chooseScheme (and any other helper in a11y_browser_test.go, keyboard_browser_test.go, pages_a11y_browser_test.go, gallery_test.go or prose_test.go that selects the first copy of a duplicated control) to act on the visible copy. Confirm the cause by reproduction before fixing.

From this commit's own message. The prompt ledger has no entries for it — which is what a squashed, rebased or amended commit looks like, and what every commit looks like in a repo without a ledger.

Summary

chooseScheme acts on the visible copy of the scheme menu, so TestTheSchemeMenuRepaintsTheFrames no longer times out on the hidden display settings copy.
Agent notes
internal/www/landing_browser_test.go uses the same bare selector on the landing page, which carries one copy; left alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 8da33b898ac5185b60157ecb1143802f8d337a2a parent 992b61e
1 file changed, +21 −5
  • internal/gallery/a11y_browser_test.go +21 −5

CI passed — run details

CI log
=== gofmt ===
=== no-rastrillo ===
go test -run '^(TestFiestaNeverImportsRastrillo|TestThePublicPackagesLinkNoBrowser)$' -count=1 .
ok  	amadan.net/rastrillo/fiesta	0.120s
=== size ===
go test ./internal/build -run '^TestTheOneLinkIsUnder25KiBGzipped$' -count=1 -v
=== RUN   TestTheOneLinkIsUnder25KiBGzipped
    build_test.go:138: fiesta-plain.css: 152856 bytes, 22303 bytes gzipped (21.8 KiB of the 25.0 KiB limit)
    build_test.go:138: fiesta-signal.css: 152951 bytes, 22414 bytes gzipped (21.9 KiB of the 25.0 KiB limit)
    build_test.go:138: fiesta.css: 155770 bytes, 23018 bytes gzipped (22.5 KiB of the 25.0 KiB limit)
--- PASS: TestTheOneLinkIsUnder25KiBGzipped (0.02s)
PASS
ok  	amadan.net/rastrillo/fiesta/internal/build	0.022s
=== suite ===
--- shard 0 of 15 ---
==> shard 0 of 15: make root
go build ./...
go vet ./...
FIESTA_TEST_REQUIRE_NODE=1 FIESTA_TEST_REQUIRE_GIT=1 go test -count=1 ./...
ok  	amadan.net/rastrillo/fiesta	1.148s
ok  	amadan.net/rastrillo/fiesta/check	6.345s
ok  	amadan.net/rastrillo/fiesta/cmd/fiesta	113.626s
ok  	amadan.net/rastrillo/fiesta/example	0.198s
ok  	amadan.net/rastrillo/fiesta/internal/axe	0.195s
ok  	amadan.net/rastrillo/fiesta/internal/build	1.660s
ok  	amadan.net/rastrillo/fiesta/internal/codeview	0.059s
ok  	amadan.net/rastrillo/fiesta/internal/gallery	99.632s
?   	amadan.net/rastrillo/fiesta/internal/harness	[no test files]
ok  	amadan.net/rastrillo/fiesta/internal/markup	0.018s
ok  	amadan.net/rastrillo/fiesta/internal/nodetest	0.473s
ok  	amadan.net/rastrillo/fiesta/internal/site	3.588s
ok  	amadan.net/rastrillo/fiesta/internal/tokens	0.017s
ok  	amadan.net/rastrillo/fiesta/internal/www	94.288s
--- shard 1 of 15 ---
==> shard 1 of 15: make staticcheck
go run honnef.co/go/tools/cmd/staticcheck@v0.8.2 -tags browser ./...
--- shard 2 of 15 ---
==> shard 2 of 15: make govulncheck
go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./...
=== Symbol Results ===

No vulnerabilities found.

Your code is affected by 0 vulnerabilities.
This scan also found 2 vulnerabilities in packages you import and 5
vulnerabilities in modules you require, but your code doesn't appear to call
these vulnerabilities.
Use '-show verbose' for more details.
--- shard 3 of 15 ---
==> shard 3 of 15: make gitleaks
go run github.com/zricethezav/gitleaks/v8@v8.30.1 git --no-banner --redact --log-opts='--full-history --diff-filter=tuxdb HEAD' .
2:40AM INF Unknown SCM platform. Use --platform to include links in findings. host=amadan.net
2:40AM INF 1 commits scanned.
2:40AM INF scanned ~6227083 bytes (6.23 MB) in 4.34s
2:40AM INF no leaks found
--- shard 4 of 15 ---
==> shard 4 of 15: make browser.internal.harness
./hack/gotest.sh browser 'internal.harness'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
ok  	amadan.net/rastrillo/fiesta/internal/harness	13.597s
--- shard 5 of 15 ---
==> shard 5 of 15: make browser.check~1of3
./hack/gotest.sh browser 'check~1of3'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 1 of 3 of ./check/ runs 95 of 286 tests
ok  	amadan.net/rastrillo/fiesta/check	264.426s
--- shard 6 of 15 ---
==> shard 6 of 15: make browser.check~2of3
./hack/gotest.sh browser 'check~2of3'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 2 of 3 of ./check/ runs 95 of 286 tests
ok  	amadan.net/rastrillo/fiesta/check	281.725s
--- shard 7 of 15 ---
==> shard 7 of 15: make browser.check~3of3
./hack/gotest.sh browser 'check~3of3'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 3 of 3 of ./check/ runs 96 of 286 tests
ok  	amadan.net/rastrillo/fiesta/check	287.821s
--- shard 8 of 15 ---
==> shard 8 of 15: make browser.internal.gallery~1of4
./hack/gotest.sh browser 'internal.gallery~1of4'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 1 of 4 of ./internal/gallery/ runs 1 of 104 tests
ok  	amadan.net/rastrillo/fiesta/internal/gallery	161.212s
--- shard 9 of 15 ---
==> shard 9 of 15: make browser.internal.gallery~2of4
./hack/gotest.sh browser 'internal.gallery~2of4'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 2 of 4 of ./internal/gallery/ runs 32 of 104 tests
ok  	amadan.net/rastrillo/fiesta/internal/gallery	137.641s
--- shard 10 of 15 ---
==> shard 10 of 15: make browser.internal.gallery~3of4
./hack/gotest.sh browser 'internal.gallery~3of4'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 3 of 4 of ./internal/gallery/ runs 35 of 104 tests
ok  	amadan.net/rastrillo/fiesta/internal/gallery	109.818s
--- shard 11 of 15 ---
==> shard 11 of 15: make browser.internal.gallery~4of4
./hack/gotest.sh browser 'internal.gallery~4of4'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 4 of 4 of ./internal/gallery/ runs 36 of 104 tests
ok  	amadan.net/rastrillo/fiesta/internal/gallery	124.129s
--- shard 12 of 15 ---
==> shard 12 of 15: make browser.internal.gallery.history
./hack/gotest.sh browser 'internal.gallery.history'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
ok  	amadan.net/rastrillo/fiesta/internal/gallery/history	29.302s
--- shard 13 of 15 ---
==> shard 13 of 15: make browser.internal.www~1of2
./hack/gotest.sh browser 'internal.www~1of2'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 1 of 2 of ./internal/www/ runs 17 of 34 tests
ok  	amadan.net/rastrillo/fiesta/internal/www	166.176s
--- shard 14 of 15 ---
==> shard 14 of 15: make browser.internal.www~2of2
./hack/gotest.sh browser 'internal.www~2of2'
gotest: on DOCS-T1, driving the harness's own choice (/usr/bin/chromium)
gotest: slice 2 of 2 of ./internal/www/ runs 17 of 34 tests
ok  	amadan.net/rastrillo/fiesta/internal/www	150.113s
diff --git a/internal/gallery/a11y_browser_test.go b/internal/gallery/a11y_browser_test.go
index 732cb79..8f3424a 100644
--- a/internal/gallery/a11y_browser_test.go
+++ b/internal/gallery/a11y_browser_test.go
@@ -44,6 +44,7 @@ import (
"testing"
"time"
+ "github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/emulation"
"github.com/chromedp/cdproto/runtime"
"github.com/chromedp/chromedp"
@@ -439,14 +440,29 @@ func luminance(t *testing.T, rgb string) float64 {
}
// chooseScheme picks one scheme from the header's menu, as a reader
-// would: open the menu, press the button.
+// would: open the menu, press the button. A page carries two copies of
+// the menu, the pinned bar's and the phone's display settings', and
+// one of them is hidden at any width, so the drive finds the visible
+// copy and keeps every query inside it; chromedp.Click on the bare
+// selector waits on the first copy in the document, the hidden one at
+// a desktop width.
func chooseScheme(t *testing.T, ctx context.Context, scheme string) {
t.Helper()
- btn := fmt.Sprintf(`[rst-scheme] input[value=%q] ~ button`, scheme)
+ var menus []*cdp.Node
+ var at int
mustRun(t, ctx,
- chromedp.Click(`[rst-scheme] > summary`, chromedp.ByQuery),
- chromedp.WaitVisible(btn, chromedp.ByQuery),
- chromedp.Click(btn, chromedp.ByQuery),
+ chromedp.Nodes(`[rst-scheme]`, &menus, chromedp.ByQueryAll),
+ chromedp.Evaluate(`[...document.querySelectorAll("[rst-scheme]")].findIndex(m => m.checkVisibility())`, &at),
+ )
+ if at < 0 || at >= len(menus) {
+ t.Fatalf("none of the %d copies of the scheme menu is visible", len(menus))
+ }
+ menu := chromedp.FromNode(menus[at])
+ btn := fmt.Sprintf(`input[value=%q] ~ button`, scheme)
+ mustRun(t, ctx,
+ chromedp.Click(`summary`, chromedp.ByQuery, menu),
+ chromedp.WaitVisible(btn, chromedp.ByQuery, menu),
+ chromedp.Click(btn, chromedp.ByQuery, menu),
)
}