diff --git a/internal/verifier/worker_test.go b/internal/verifier/worker_test.go index 57b3dbb..68db394 100644 --- a/internal/verifier/worker_test.go +++ b/internal/verifier/worker_test.go @@ -1,6 +1,7 @@ package verifier import ( + "math" "testing" "github.com/priyanshujain/sanderling/internal/hierarchy" @@ -21,3 +22,44 @@ func TestVerbAcceptsSwipeRequiresPositiveBounds(t *testing.T) { t.Error("swipes must accept an element with positive bounds") } } + +// TestKeyboardRegionTop covers the region detection that keeps the fuzzer off +// keyboard keys, especially the guard that ignores the IME's full-screen decor +// view (which otherwise reports a huge bounds and would push the keyboard line +// to the top of the screen, excluding the whole app). +func TestKeyboardRegionTop(t *testing.T) { + ime := func(top, bottom int) *hierarchy.Element { + return &hierarchy.Element{ + ResourceID: "com.google.android.inputmethod.latin:id/keyboard_holder", + Bounds: hierarchy.Bounds{Right: 1080, Top: top, Bottom: bottom}, + } + } + app := func(top, bottom int) *hierarchy.Element { + return &hierarchy.Element{ResourceID: "app/field", Bounds: hierarchy.Bounds{Right: 1080, Top: top, Bottom: bottom}} + } + + t.Run("no keyboard yields sentinel", func(t *testing.T) { + tree := &hierarchy.Tree{Elements: []*hierarchy.Element{app(0, 2400)}} + if got := keyboardRegionTop(tree); got != math.MaxInt { + t.Errorf("keyboardRegionTop = %d, want MaxInt with no keyboard", got) + } + }) + + t.Run("decor view ignored, real keyboard sets the line", func(t *testing.T) { + tree := &hierarchy.Tree{Elements: []*hierarchy.Element{ + app(0, 2400), + ime(0, 2400), // full-screen IME decor view: must be ignored + ime(1503, 2268), // the actual keyboard + }} + if got := keyboardRegionTop(tree); got != 1503 { + t.Errorf("keyboardRegionTop = %d, want 1503 (keyboard top, not the decor view's 0)", got) + } + }) + + t.Run("decor-only view yields sentinel", func(t *testing.T) { + tree := &hierarchy.Tree{Elements: []*hierarchy.Element{app(0, 2400), ime(0, 2400)}} + if got := keyboardRegionTop(tree); got != math.MaxInt { + t.Errorf("keyboardRegionTop = %d, want MaxInt when only a full-screen IME decor view is present", got) + } + }) +}