fix(verifier): require positive bounds for swipe candidates

A zero-bounds element centers at (0,0); 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. Swipes now require positive
bounds like every other verb.
This commit is contained in:
pj committed 2026-06-10 15:20:10 +05:30
1 parent 4cf8626cb9
commit f9aa44f7e8
2 files changed
+29 -2

No files matched your search

+6 -2
View File
@@ -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
}
+23
View File
@@ -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")
}
}