oficina / sheets Public

Test that Format's Set buttons fit their panel on touch (review #44, nit 2)

TestFormatMenuFitsOnTap opens Format at 320 and 390 wide under a coarse
pointer and checks each size row's Set button lies inside its panel and
that a tap at its centre lands on it. Without 48c1052's label rule it
fails at both widths (Set spans 225-263 in a panel ending at 245).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 477ea96fc76d90b798232e5f6d28c1ec61665ba9 parent 095b010
1 file changed, +54 −0
  • internal/sheets/zoom_browser_test.go +54 −0

CI passed — run details

CI log
amadan: .amadan/timeout: this job's budget is 15m0s (this runner allows up to 30m0s)
=== vet ===
CGO_ENABLED=0 go vet ./...
CGO_ENABLED=0 go vet -tags browser ./internal/sheets/
=== fmt ===
=== build ===
CGO_ENABLED=0 go build ./...
=== migrations ===
go tool rastrillo migration check
rastrillo migration check: models and migrations agree
=== go-test ===
CGO_ENABLED=0 go test -count=1 ./...
?   	amadan.net/oficina/sheets/cmd/sheets	[no test files]
ok  	amadan.net/oficina/sheets/internal/guardstest	0.084s
ok  	amadan.net/oficina/sheets/internal/sheets	14.824s
ok  	amadan.net/oficina/sheets/internal/sheets/calc	0.011s
ok  	amadan.net/oficina/sheets/internal/sheets/format	0.003s
ok  	amadan.net/oficina/sheets/internal/sheets/live	0.054s
ok  	amadan.net/oficina/sheets/internal/sheets/seal	0.003s
ok  	amadan.net/oficina/sheets/internal/sheets/sealtest	0.003s
ok  	amadan.net/oficina/sheets/internal/sheets/store	2.792s
ok  	amadan.net/oficina/sheets/internal/sheets/xlsx	0.292s
?   	amadan.net/oficina/sheets/tools/gencorpus	[no test files]
=== race ===
go test -race -count=1 ./internal/sheets/store/... ./internal/sheets/live/...
ok  	amadan.net/oficina/sheets/internal/sheets/store	46.207s
ok  	amadan.net/oficina/sheets/internal/sheets/live	1.059s
diff --git a/internal/sheets/zoom_browser_test.go b/internal/sheets/zoom_browser_test.go
index cdc1e3f..8ed823f 100644
--- a/internal/sheets/zoom_browser_test.go
+++ b/internal/sheets/zoom_browser_test.go
@@ -115,6 +115,60 @@ func TestNoZoomOnTap(t *testing.T) {
}
}
+// TestFormatMenuFitsOnTap: the Format menu's two size rows (label, a
+// number field, Set) are sized to the panel's 15rem. On a touch screen
+// the field is 16px type and the button is padded for a finger, and Set
+// hung 11-21px past the panel's edge, half of it off the menu, at every
+// width. sheets.css narrows the label column under a coarse pointer;
+// this measures the result at 320 and 390 wide: each Set button inside
+// its panel, and its centre landing on the button, not on whatever is
+// behind the menu.
+func TestFormatMenuFitsOnTap(t *testing.T) {
+ app, cookies := signIn(t)
+ sheet, _ := newSheet(t, app, cookies, "Format")
+ rig := harness.New(t, func(string) http.Handler { return app.Router() })
+ var set []chromedp.Action
+ for _, c := range cookies {
+ set = append(set, network.SetCookie(c.Name, c.Value).WithURL(rig.Origin+"/").
+ WithHTTPOnly(c.HttpOnly).WithSecure(c.Secure).WithSameSite(network.CookieSameSiteLax))
+ }
+ set = append(set, emulation.SetTouchEmulationEnabled(true).WithMaxTouchPoints(5))
+ rig.Run(set...)
+ for _, width := range []int64{320, 390} {
+ var coarse bool
+ var problems []string
+ ctx, cancel := context.WithTimeout(rig.Context(), 20*time.Second)
+ err := chromedp.Run(ctx,
+ emulation.SetDeviceMetricsOverride(width, 844, 1, true),
+ chromedp.Navigate(fmt.Sprintf("%s/sheets/%d", rig.Origin, sheet.ID)),
+ chromedp.Reload(),
+ chromedp.WaitVisible(`td[data-x="0"][data-y="0"]`),
+ chromedp.Evaluate(`matchMedia('(pointer: coarse)').matches`, &coarse),
+ chromedp.Evaluate(`[...document.querySelectorAll('[estilo-menubar-title]')].find(e => e.textContent.trim() === 'Format').click()`, nil),
+ chromedp.WaitVisible(`[data-size-form] button`),
+ chromedp.Evaluate(`[...document.querySelectorAll('[data-size-form] button')].flatMap(b => {
+ const r = b.getBoundingClientRect(), m = b.closest('[estilo-menu]').getBoundingClientRect()
+ const out = []
+ if (r.left < m.left || r.right > m.right || r.top < m.top || r.bottom > m.bottom)
+ out.push(b.closest('form').dataset.axis + ': Set spans ' + Math.round(r.left) + '-' + Math.round(r.right) + ', its panel ' + Math.round(m.left) + '-' + Math.round(m.right))
+ const hit = document.elementFromPoint(r.left + r.width / 2, r.top + r.height / 2)
+ if (!hit || !b.contains(hit)) out.push(b.closest('form').dataset.axis + ': a tap on Set lands on ' + (hit ? hit.tagName.toLowerCase() : 'nothing'))
+ return out
+ })`, &problems),
+ )
+ cancel()
+ if err != nil {
+ t.Fatalf("%dpx: %v", width, err)
+ }
+ if !coarse {
+ t.Fatalf("%dpx: the touch-screen emulation did not apply", width)
+ }
+ for _, p := range problems {
+ t.Errorf("%dpx: %s", width, p)
+ }
+ }
+}
+
// smallControls is a script listing each visible control matching sel
// whose computed font-size is under 16px, described well enough to find.
func smallControls(sel string) string {