mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
refactor(ioscompanion): name the empty-editable-field sentinel for what it is
This commit is contained in:
1 parent
622b7c5cc4
commit
a6229afda7
2 files changed
+8
-40
No files matched your search
@@ -14,25 +14,14 @@ type rawFrame struct {
|
||||
Height float64 `json:"height"`
|
||||
}
|
||||
|
||||
// emptyFieldValueSentinel is what the accessibility bridge reports as the
|
||||
// AXValue of an empty editable field. It is bridge state, not app content, so
|
||||
// it maps to an empty value rather than surfacing as literal field text.
|
||||
const emptyFieldValueSentinel = "Invalid"
|
||||
|
||||
// rawElement is one entry in the flat describe-all dump returned by the
|
||||
// simulator companion. Only the fields the mapper consumes are declared;
|
||||
// unknown fields are ignored.
|
||||
// unresolvedValueSentinel is what the accessibility bridge reports for a value
|
||||
// it cannot resolve yet (typically during app cold start). It is bridge state,
|
||||
// not app content.
|
||||
const unresolvedValueSentinel = "Invalid"
|
||||
|
||||
// hasUnresolvedValues reports whether any element in the flat dump still
|
||||
// carries the bridge's unresolved-value sentinel.
|
||||
func hasUnresolvedValues(dump []byte) bool {
|
||||
for _, element := range decodeDump(dump) {
|
||||
if stringValue(element.AXValue) == unresolvedValueSentinel {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type rawElement struct {
|
||||
Frame rawFrame `json:"frame"`
|
||||
AXUniqueID *string `json:"AXUniqueId"`
|
||||
@@ -108,9 +97,9 @@ func mapElement(element *rawElement) (treeNode, bool) {
|
||||
}
|
||||
|
||||
value := stringValue(element.AXValue)
|
||||
if value == unresolvedValueSentinel {
|
||||
// Bridge state, not app content: surfacing it would show phantom
|
||||
// field values in snapshots taken while the bridge catches up.
|
||||
if value == emptyFieldValueSentinel {
|
||||
// An empty editable field reads as this sentinel through the bridge;
|
||||
// it is not app content, so treat the field as empty.
|
||||
value = ""
|
||||
}
|
||||
label := stringValue(element.AXLabel)
|
||||
|
||||
@@ -224,27 +224,6 @@ func TestRootIsFlatWithAllChildren(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasUnresolvedValues(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
dump string
|
||||
want bool
|
||||
}{
|
||||
{name: "sentinel value", dump: `[{"type":"TextField","AXValue":"Invalid","frame":{"x":0,"y":0,"width":1,"height":1}}]`, want: true},
|
||||
{name: "clean values", dump: `[{"type":"TextField","AXValue":"hello","frame":{"x":0,"y":0,"width":1,"height":1}}]`, want: false},
|
||||
{name: "empty value", dump: `[{"type":"TextField","AXValue":"","frame":{"x":0,"y":0,"width":1,"height":1}}]`, want: false},
|
||||
{name: "empty dump", dump: `[]`, want: false},
|
||||
{name: "malformed dump", dump: `nope`, want: false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
if got := hasUnresolvedValues([]byte(c.dump)); got != c.want {
|
||||
t.Fatalf("got %v, want %v", got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapHierarchySentinelValueMapsAsEmpty(t *testing.T) {
|
||||
dump := `[{"type":"TextField","AXUniqueId":"F","AXLabel":"Email","AXValue":"Invalid","frame":{"x":0,"y":0,"width":10,"height":10},"enabled":true}]`
|
||||
mapped, err := MapHierarchy([]byte(dump), 100, 100)
|
||||
|
||||
Reference in new issue
Block a user