oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1//go:build browser
2
3package calendartest
4
5import (
6 "context"
7 "io"
8 "log/slog"
9 "net/http"
10 "path/filepath"
11 "testing"
12 "time"
13
14 "amadan.net/rastrillo/rastrillo/harness"
15 "github.com/chromedp/cdproto/emulation"
16 "github.com/chromedp/cdproto/network"
17 "github.com/chromedp/chromedp"
18
19 calendar "amadan.net/oficina/calendar/internal/calendar"
20)
21
22// TestQuickAddOnANarrowScreen: on a phone the quick-add panel stops
23// floating and drops into the page (calendar.css, max-width 40rem), and
24// at 390px it ran about 15px past the right edge of the screen — the
25// textarea's and the Add button's right ends were off the side, and the
26// page scrolled sideways. Every string check in the Go suite passes a
27// panel like that. This opens it at 320 and 390 and fails if anything
28// inside it reaches past the viewport, or the page grows wider than the
29// screen.
30func TestQuickAddOnANarrowScreen(t *testing.T) {
31 var app *calendar.App
32 rig := harness.New(t, func(origin string) http.Handler {
33 a, err := calendar.New(calendar.Config{
34 DBPath: filepath.Join(t.TempDir(), "calendar.db"),
35 Env: "development",
36 Origin: origin,
37 Logger: slog.New(slog.NewTextHandler(io.Discard, nil)),
38 })
39 if err != nil {
40 t.Fatalf("calendar.New: %v", err)
41 }
42 t.Cleanup(func() { a.Close() })
43 app = a
44 return a.Handler()
45 })
46 session := signInOverHTTP(t, app, rig.Origin, "host@example.com")
47
48 for _, width := range []int64{320, 390} {
49 var problems []string
50 ctx, cancel := context.WithTimeout(rig.Context(), 20*time.Second)
51 err := chromedp.Run(ctx,
52 network.SetCookie(session.Name, session.Value).WithURL(rig.Origin+"/").
53 WithHTTPOnly(session.HttpOnly).WithSameSite(network.CookieSameSiteLax),
54 emulation.SetDeviceMetricsOverride(width, 844, 1, true),
55 chromedp.Navigate(rig.Origin+"/"),
56 chromedp.WaitVisible(`[cal-quick] > summary`, chromedp.ByQuery),
57 chromedp.Click(`[cal-quick] > summary`, chromedp.ByQuery),
58 chromedp.WaitVisible(`[cal-quick-text]`, chromedp.ByQuery),
59 chromedp.Evaluate(quickAddProblems, &problems),
60 )
61 cancel()
62 if err != nil {
63 t.Fatalf("%dpx: %v", width, err)
64 }
65 for _, p := range problems {
66 t.Errorf("%dpx, the open quick-add panel: %s", width, p)
67 }
68 }
69}
70
71// quickAddProblems lists every visible element of the open quick-add
72// panel that reaches past either side of the viewport, and the page
73// itself if it scrolls sideways.
74const quickAddProblems = `(() => {
75 const vw = document.documentElement.clientWidth, out = []
76 const els = [document.querySelector('[cal-quick]'), ...document.querySelectorAll('[cal-quick] *')]
77 for (const el of els) {
78 const r = el.getBoundingClientRect()
79 if (r.width === 0 && r.height === 0) continue
80 if (r.right > vw + 0.5 || r.left < -0.5) {
81 const name = el.tagName.toLowerCase() + [...el.attributes].filter(a => a.name.startsWith('cal-')).map(a => '[' + a.name + ']').join('')
82 out.push(name + ' spans ' + Math.round(r.left) + '-' + Math.round(r.right) + ' in a ' + vw + 'px viewport')
83 }
84 }
85 if (document.documentElement.scrollWidth > vw) out.push('the page is ' + document.documentElement.scrollWidth + 'px wide in a ' + vw + 'px viewport')
86 return out
87})()`
88