No zoom on the sign-in field either
The no-zoom rule lived in fichas.css, which only the app shell loaded, so the sign-in page — the plain layout, and the field every visit starts by tapping — still zoomed on iOS. TestNoZoomOnTap now covers both layouts and failed on sign-in at 14px before this.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 files changed,
+33
−23
internal/fichas/templates/layout.html+4 −0internal/fichastest/browser_test.go+29 −23
CI passed — run details
CI log
=== vet === go vet ./... === fmt === === test === go test ./... ? amadan.net/oficina/fichas/cmd/fichas [no test files] ok amadan.net/oficina/fichas/internal/fichas 1.525s ? amadan.net/oficina/fichas/internal/fichas/icons [no test files] ok amadan.net/oficina/fichas/internal/fichas/seal (cached) ok amadan.net/oficina/fichas/internal/fichastest 0.771s ? amadan.net/oficina/fichas/scripts/mockups [no test files] ? amadan.net/oficina/fichas/scripts/preview [no test files] ? amadan.net/oficina/fichas/scripts/writeestilo [no test files] === migration-check === go run github.com/carlosframework/rastrillo/cmd/rastrillo migration check rastrillo migration check: models and migrations agree
diff --git a/internal/fichas/templates/layout.html b/internal/fichas/templates/layout.html| index 2b86bfd..8e641bb 100644 |
| --- a/internal/fichas/templates/layout.html |
| +++ b/internal/fichas/templates/layout.html |
| @@ -12,6 +12,10 @@ |
| <link rel="stylesheet" href="{{asset "static/busy.css"}}"> |
| <link rel="stylesheet" href="{{asset "static/theme.css"}}"> |
| <link rel="stylesheet" href="{{asset "static/brand/brand.css"}}"> |
| +{{/* fichas.css here too, not only in the app shell: it carries the |
| + no-zoom-on-tap rule, and the sign-in field is the one every visit |
| + starts by tapping. TestNoZoomOnTap covers both layouts. */}} |
| +<link rel="stylesheet" href="{{asset "static/fichas.css"}}"> |
| <script defer src="{{asset "static/rastrillo.js"}}"></script> |
| <script defer src="{{asset "static/busy.js"}}"></script> |
| {{iconAssets}} |
diff --git a/internal/fichastest/browser_test.go b/internal/fichastest/browser_test.go| index 4643f5e..a732076 100644 |
| --- a/internal/fichastest/browser_test.go |
| +++ b/internal/fichastest/browser_test.go |
| @@ -192,28 +192,34 @@ func TestAnExpiredSessionIsNotADeadEnd(t *testing.T) { |
| // touch screen every text input must be at least 16px. Emulated as |
| // pointer: coarse, which is how the CSS decides. |
| func TestNoZoomOnTap(t *testing.T) { |
| - rig := browserApp(t, nil) |
| - var smallest float64 |
| - var coarse bool |
| - rig.Run( |
| - chromedp.Navigate(rig.Origin+"/cards/new"), |
| - chromedp.WaitVisible(`input[name="f_name"]`), |
| - // Touch emulation, then a reload so the page re-evaluates its media |
| - // queries. The first version used SetEmulatedMedia with a "pointer" |
| - // feature, which this Chromium does not emulate — the test measured |
| - // desktop styles while claiming to measure a phone's, and passing |
| - // or failing told us nothing. The coarse check below is what caught |
| - // that. |
| - emulation.SetTouchEmulationEnabled(true).WithMaxTouchPoints(5), |
| - chromedp.Reload(), |
| - chromedp.WaitVisible(`input[name="f_name"]`), |
| - chromedp.Evaluate(`matchMedia('(pointer: coarse)').matches`, &coarse), |
| - chromedp.Evaluate(`Math.min(...[...document.querySelectorAll('input:not([type=checkbox]):not([type=radio]):not([type=hidden]), select, textarea')].map(e => parseFloat(getComputedStyle(e).fontSize)))`, &smallest), |
| - ) |
| - if !coarse { |
| - t.Fatal("the touch-screen emulation did not apply; this test would measure desktop styles") |
| - } |
| - if smallest < 16 { |
| - t.Fatalf("a form control is %.1fpx on a touch screen; iOS will zoom when it is tapped", smallest) |
| + // Both layouts: the app shell, and sign-in — the plain column with |
| + // estilo's chrome, and the field every visit starts by tapping. |
| + for _, page := range []struct{ path, ready string }{ |
| + {"/cards/new", `input[name="f_name"]`}, |
| + {"/signin", `input[name="address"]`}, |
| + } { |
| + rig := browserApp(t, nil) |
| + var smallest float64 |
| + var coarse bool |
| + rig.Run( |
| + chromedp.Navigate(rig.Origin+page.path), |
| + chromedp.WaitVisible(page.ready), |
| + // Touch emulation, then a reload so the page re-evaluates its |
| + // media queries. SetEmulatedMedia's "pointer" feature is not |
| + // emulated by this Chromium: the first version measured |
| + // desktop styles while claiming a phone's. The coarse check |
| + // is what caught it. |
| + emulation.SetTouchEmulationEnabled(true).WithMaxTouchPoints(5), |
| + chromedp.Reload(), |
| + chromedp.WaitVisible(page.ready), |
| + chromedp.Evaluate(`matchMedia('(pointer: coarse)').matches`, &coarse), |
| + chromedp.Evaluate(`Math.min(...[...document.querySelectorAll('input:not([type=checkbox]):not([type=radio]):not([type=hidden]), select, textarea')].map(e => parseFloat(getComputedStyle(e).fontSize)))`, &smallest), |
| + ) |
| + if !coarse { |
| + t.Fatalf("%s: the touch-screen emulation did not apply; this would measure desktop styles", page.path) |
| + } |
| + if smallest < 16 { |
| + t.Errorf("%s: a form control is %.1fpx on a touch screen; iOS will zoom when it is tapped", page.path, smallest) |
| + } |
| } |
| } |