package e2e_test import ( "testing" "time" "pad/internal/editor" "pad/internal/test/e2e" "pad/internal/ui" ) // TestEditorClickToMoveCursor tests that clicking/tapping in the editor moves the cursor. // // All state access goes through the harness's owner-side helpers // (WithState / CursorPosition): the logic goroutine is the sole owner of // State (architecture.md ยง1). func TestEditorClickToMoveCursor(t *testing.T) { h := e2e.NewHarnessWithDefaults() defer h.Cleanup() // Switch to editor page and load some text if err := h.WithState(func(st *editor.State) { editor.GoToEditor(nil) }); err != nil { t.Fatalf("GoToEditor: %v", err) } h.SendConfig(780, 1688) // Wait for frame to ensure page switch _, err := e2e.WaitForNewFrame(h, h.FrameCount(), 5*time.Second) if err != nil { t.Fatalf("timeout waiting for frame: %v", err) } // Initialize GlyphLayout for the test (owner-side write) if err := h.WithState(func(st *editor.State) { st.Editor.GlyphLayout = ui.GlyphLayout{ ByteOffsets: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, X: []ui.Dp{10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120}, Y: []ui.Dp{70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70}, Advance: []ui.Dp{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, } }); err != nil { t.Fatalf("set GlyphLayout: %v", err) } // Initial cursor position should be 0 (or end of text, depending on implementation) // For this test, let's assume it starts at 0. pos, err := h.CursorPosition() if err != nil { t.Fatalf("CursorPosition: %v", err) } if pos != 0 { t.Errorf("expected initial cursor 0, got %d", pos) } // Simulate tap at a position that should move the cursor. // We use SendInput to simulate the tap event handler for the editor's text field. h.SendInput([]ui.InputEvent{ { Handler: func(data any) { if pt, ok := data.(ui.Point); ok { editor.SetCursorFromPoint(float64(pt.X), float64(pt.Y)) } }, Data: ui.Point{X: 30, Y: 70}, }, }) // Wait for potential re-render _, err = e2e.WaitForNewFrame(h, h.FrameCount(), 1*time.Second) if err != nil { t.Logf("no new frame after tap, checking state anyway") } // Assert cursor moved pos, err = h.CursorPosition() if err != nil { t.Fatalf("CursorPosition: %v", err) } if pos == 0 { t.Errorf("expected cursor to move from 0, but it remained at 0") } }