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>
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' .
[90m2:40AM[0m [32mINF[0m [1mUnknown SCM platform. Use --platform to include links in findings.[0m [36mhost=[0mamadan.net
[90m2:40AM[0m [32mINF[0m [1m1 commits scanned.[0m
[90m2:40AM[0m [32mINF[0m [1mscanned ~6227083 bytes (6.23 MB) in 4.34s[0m
[90m2:40AM[0m [32mINF[0m [1mno leaks found[0m
--- 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
Intent
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), |
| ) |
| } |