diff --git a/internal/verifier/worker.go b/internal/verifier/worker.go index 29fd8d9..b386bea 100644 --- a/internal/verifier/worker.go +++ b/internal/verifier/worker.go @@ -644,7 +644,7 @@ func selectorForElement(tree *hierarchy.Tree, element *hierarchy.Element) string // taps/doubleTaps/longPresses: clickable + enabled + positive bounds // typing: editable + enabled + positive bounds // scrolls: scrollable attribute + positive bounds -// swipes: any in-scope element +// swipes: any in-scope element with positive bounds // // Every candidate carries the resolving selector so the runner can re-route by // id/text. Out-of-scope nodes (the soft keyboard, system UI) are always dropped. @@ -689,7 +689,11 @@ func verbAccepts(verb string, element *hierarchy.Element) bool { case "scrolls": return element.Attributes["scrollable"] == "true" && positiveBounds case "swipes": - return true + // Any visible element is a valid swipe origin, but it must have real + // bounds: a zero-bounds node centers at (0,0), and a downward swipe from + // the top-left corner is the system gesture that pulls down the + // notification shade, dragging the fuzzer out of the app. + return positiveBounds default: return false } diff --git a/internal/verifier/worker_test.go b/internal/verifier/worker_test.go new file mode 100644 index 0000000..57b3dbb --- /dev/null +++ b/internal/verifier/worker_test.go @@ -0,0 +1,23 @@ +package verifier + +import ( + "testing" + + "github.com/priyanshujain/sanderling/internal/hierarchy" +) + +// TestVerbAcceptsSwipeRequiresPositiveBounds locks the fix for the notification +// shade: a zero-bounds element centers at (0,0), and a downward swipe from the +// top-left corner is the system gesture that pulls the shade over the app. The +// swipe verb must reject zero-bounds nodes like every other verb does. +func TestVerbAcceptsSwipeRequiresPositiveBounds(t *testing.T) { + zeroBounds := &hierarchy.Element{Bounds: hierarchy.Bounds{}} + if verbAccepts("swipes", zeroBounds) { + t.Error("swipes must reject a zero-bounds element (it centers at (0,0) and pulls the notification shade)") + } + + realBounds := &hierarchy.Element{Bounds: hierarchy.Bounds{Left: 100, Top: 400, Right: 980, Bottom: 600}} + if !verbAccepts("swipes", realBounds) { + t.Error("swipes must accept an element with positive bounds") + } +}