- Replace gtx.Event(nil) with key.Filter{Focus: focusedID} and
key.FocusFilter{Target: focusedID} so Gio correctly routes key
and edit events to the focused editor text field.
- Convert EditorState.CursorPosition (byte offset) to line/column
coordinates for accurate cursor rendering.
- Add debug logging in HandleKeyDown and HandleCursorMove.
104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package e2e_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"pad/internal/editor"
|
|
"pad/internal/test/e2e"
|
|
"pad/internal/ui"
|
|
)
|
|
|
|
// TestEditorInitialLayout tests the initial editor layout has expected structure.
|
|
func TestEditorInitialLayout(t *testing.T) {
|
|
h := e2e.NewHarnessWithDefaults()
|
|
defer h.Cleanup()
|
|
|
|
// Switch to editor page
|
|
editor.GoToEditor(nil)
|
|
h.SendConfig(780, 1688)
|
|
|
|
// Wait for a new frame after switching to editor page
|
|
_, err := e2e.WaitForNewFrame(h, h.FrameCount(), 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("timeout waiting for frames: %v", err)
|
|
}
|
|
|
|
lastFrame := e2e.GetLastFrame(h)
|
|
ea := e2e.NewElementAssertions(t, lastFrame)
|
|
ea.HasElementCount(4)
|
|
ea.HasElementOfType(reflect.TypeOf(ui.Container{}))
|
|
ea.HasElementOfType(reflect.TypeOf(ui.TextField{}))
|
|
ea.HasElementWithID("editor_text")
|
|
}
|
|
|
|
// TestConfigChangeTriggersNewFrame tests that config changes produce new frames.
|
|
func TestConfigChangeTriggersNewFrame(t *testing.T) {
|
|
h := e2e.NewHarnessWithDefaults()
|
|
defer h.Cleanup()
|
|
|
|
_, err := h.WaitForFrameCount(1, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("timeout waiting for initial frame: %v", err)
|
|
}
|
|
|
|
initialCount := h.FrameCount()
|
|
h.SendConfig(1000, 2000)
|
|
|
|
newCount, err := e2e.WaitForNewFrame(h, initialCount, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("timeout waiting for new frame: %v", err)
|
|
}
|
|
if newCount <= initialCount {
|
|
t.Errorf("expected new frame after config change, got %d (was %d)", newCount, initialCount)
|
|
}
|
|
}
|
|
|
|
// TestElementPositionsValid tests that elements have valid regions and no overlaps.
|
|
func TestElementPositionsValid(t *testing.T) {
|
|
h := e2e.NewHarnessWithDefaults()
|
|
defer h.Cleanup()
|
|
|
|
frames, err := h.WaitForFrameCount(1, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("timeout waiting for frames: %v", err)
|
|
}
|
|
|
|
lastFrame := frames[len(frames)-1]
|
|
e2e.AssertNoOverlappingElements(t, lastFrame)
|
|
e2e.AssertFrameHasNoEmptyRegions(t, lastFrame)
|
|
e2e.AssertFrameHasNoNegativeRegions(t, lastFrame)
|
|
e2e.AssertFrameHasNoInvisibleElements(t, lastFrame)
|
|
|
|
screenBounds := ui.Region{X: 0, Y: 0, W: 780, H: 1688}
|
|
e2e.AssertFrameHasNoOutOfBoundsElements(t, lastFrame, screenBounds)
|
|
}
|
|
|
|
// TestHarnessTimeout tests that timeout errors are returned correctly.
|
|
func TestHarnessTimeout(t *testing.T) {
|
|
h := e2e.NewHarness()
|
|
h.Run()
|
|
defer h.Cleanup()
|
|
|
|
// Wait for initial startup frames first
|
|
_, err := h.WaitForFrameCount(1, 5*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("timeout waiting for initial frames: %v", err)
|
|
}
|
|
|
|
initialCount := h.FrameCount()
|
|
|
|
// Now wait for a frame count that won't be reached (no more events sent)
|
|
_, err = h.WaitForFrameCount(initialCount+10, 100*time.Millisecond)
|
|
if err == nil {
|
|
t.Error("expected timeout error, got nil")
|
|
}
|
|
}
|
|
|
|
// TestHarnessCleanup tests that cleanup stops goroutines without deadlock.
|
|
func TestHarnessCleanup(t *testing.T) {
|
|
h := e2e.NewHarnessWithDefaults()
|
|
h.Cleanup()
|
|
}
|