Pad/internal/test/e2e/scroll_cursor_test.go

89 lines
2.8 KiB
Go

package e2e_test
import (
"testing"
"time"
"pad/internal/editor"
"pad/internal/test/e2e"
"pad/internal/ui"
)
func TestEditorClickToMoveCursorWithScroll(t *testing.T) {
h := e2e.NewHarnessWithDefaults()
h.Run() // Start the harness!
defer h.Cleanup()
// Switch to editor page
editor.GoToEditor(nil)
h.SendConfig(780, 1688)
// Give it a moment to initialize
time.Sleep(200 * time.Millisecond)
// Wait for frame
_, err := h.WaitForFrameCount(1, 5*time.Second)
if err != nil {
t.Fatalf("timeout waiting for frame: %v", err)
}
// Setup:
// - 2 lines, each 10 chars + newline.
// - Line height = 14 * 1.2 = 16.8 (rounded?) Let's check EditorLineHeight()
// EditorLineHeight is 14 * 1.2 = 16.8.
lineHeight := 16.8
editor.TheState.Editor.Buffer = "Line 1\nLine 2\nLine 3"
// Scroll to start of Line 2 (skip Line 1)
editor.TheState.ScrollOffset = ui.Dp(lineHeight)
// GlyphLayout:
// Line 1: y = 0
// Line 2: y = 16.8
// Line 3: y = 33.6
editor.TheState.Editor.GlyphLayout = ui.GlyphLayout{
ByteOffsets: []int{0, 7, 14}, // Start of each line
X: []ui.Dp{10, 10, 10},
Y: []ui.Dp{ui.Dp(0), ui.Dp(lineHeight), ui.Dp(lineHeight * 2)},
Advance: []ui.Dp{10, 10, 10},
}
// Tap at y=10 (within the text area).
// Because of scroll=16.8, this should correspond to:
// visualLine = (y + scroll) / lineHeight = (10 + 16.8) / 16.8 = 26.8 / 16.8 = 1.59 -> 1
// Line 1 is index 0. Line 2 is index 1.
// So visualLine 1 should be Line 2.
// The problem is that SetCursorFromPoint expects y in DP, but receives it as raw pixels
// if we're not careful. Let's pass the y value properly.
// The test harness sends raw pixel coordinates to handler.
// EditorLayout converts tap point:
// localY := float64(pt.Y - editorRegion.Y + TheState.ScrollOffset)
// So the handler receives Y as pt.Y, where pt.Y is relative to the screen.
// The test harness doesn't seem to account for region offset.
// Let's debug by printing in the test.
t.Logf("ScrollOffset: %v", editor.TheState.ScrollOffset)
h.SendInput([]ui.InputEvent{
{
Handler: func(data any) {
if pt, ok := data.(ui.Point); ok {
// Manually simulate the offset correction that EditorLayout does
// editorRegion.Y is margin(10) + statusBarH(52) = 62.
// Let's set pt.Y to 10 + 62 = 72.
localY := float64(pt.Y) - 62.0 + float64(editor.TheState.ScrollOffset)
editor.SetCursorFromPoint(float64(pt.X), localY)
}
},
Data: ui.Point{X: 10, Y: 72},
},
})
// Assert cursor moved to start of Line 2 (offset 7)
time.Sleep(100 * time.Millisecond) // Give logic goroutine a moment to process input
t.Logf("Cursor position: %d", editor.TheState.Editor.CursorPosition)
if editor.TheState.Editor.CursorPosition != 7 {
t.Errorf("expected cursor to move to 7 (Line 2), but got %d", editor.TheState.Editor.CursorPosition)
}
}