feat(hierarchy): an element reports whether it masks what is typed into it

ios reads it off SecureTextField, which the companion already sent and
nothing read; web reads input[type=password]. Android cannot: the native
tree mapper drops the password attribute before the sidecar sees it, so
the fact is three-valued and null there rather than a false that would
read as "not secure".
This commit is contained in:
pj committed 2026-08-18 17:16:55 +05:30
1 parent 5f1f50c2fb
commit b1e95739ad
11 files changed
+186 -5

No files matched your search

@@ -388,3 +388,41 @@ func TestScrollableIgnoresAContainerOffTheScreen(t *testing.T) {
t.Fatalf("scrollable containers = %+v, want none off the screen", got)
}
}
// A secure text entry is what XCUITest reports a password field as
// (companion/Sources/ElementTypeName.swift). It has to reach the tree as a
// fact, because that is what lets a typed value be redacted from the record
// without redacting every other field's.
func TestSecureFactPerEditableType(t *testing.T) {
cases := []struct {
elementType string
wantReported bool
wantSecure bool
}{
{"SecureTextField", true, true},
{"TextField", true, false},
{"TextArea", true, false},
{"Button", false, false},
{"StaticText", false, false},
}
for _, testCase := range cases {
dump := `[{"type":"` + testCase.elementType + `","frame":{"x":0,"y":0,"width":10,"height":10},"enabled":true}]`
element := parseSingle(t, dump)
if element.SecureReported() != testCase.wantReported {
t.Errorf("%s reported secure = %v, want %v",
testCase.elementType, element.SecureReported(), testCase.wantReported)
}
if element.Secure != testCase.wantSecure {
t.Errorf("%s secure = %v, want %v", testCase.elementType, element.Secure, testCase.wantSecure)
}
}
}
// A secure text entry is a field a run must be able to type into, or the login
// screens every real app opens on are unreachable.
func TestSecureTextFieldIsEditable(t *testing.T) {
dump := `[{"type":"SecureTextField","frame":{"x":0,"y":0,"width":10,"height":10},"enabled":true}]`
if element := parseSingle(t, dump); !element.Editable {
t.Error("a secure text entry must be editable")
}
}