mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
fix(sidecar): surface visible text on iOS static elements
Static text and button strings live in the accessibility label on iOS, so the text attribute came through empty and every balance extractor parsed to zero, silently disarming both folio properties. Non-editable elements now fall back title, value, then label; editable fields keep value-only so an empty field's caption does not read as content.
This commit is contained in:
1 parent
33a0924f7e
commit
d6188df667
2 files changed
+36
-3
No files matched your search
@@ -878,12 +878,20 @@ internal fun iosAxElementToTreeNode(element: hierarchy.AXElement): Map<String, A
|
|||||||
val elementType = element.elementType
|
val elementType = element.elementType
|
||||||
val title = element.title.orEmpty()
|
val title = element.title.orEmpty()
|
||||||
val value = element.value.orEmpty()
|
val value = element.value.orEmpty()
|
||||||
|
val label = element.label.orEmpty()
|
||||||
|
val editable = elementType in IOS_EDITABLE_ELEMENT_TYPES
|
||||||
val checked = elementType in IOS_CHECKABLE_ELEMENT_TYPES && value == "1"
|
val checked = elementType in IOS_CHECKABLE_ELEMENT_TYPES && value == "1"
|
||||||
|
// text carries the element's visible string, matching what Android
|
||||||
|
// surfaces in its text attribute. Editable fields expose only their
|
||||||
|
// typed content: their label is the field caption (e.g. "Email"), and
|
||||||
|
// leaking it into text would make an empty field look filled. Static
|
||||||
|
// text and buttons carry the visible string in the label.
|
||||||
|
val text = if (editable) value else title.ifEmpty { value }.ifEmpty { label }
|
||||||
val attributes = linkedMapOf(
|
val attributes = linkedMapOf(
|
||||||
"accessibilityText" to element.label.orEmpty(),
|
"accessibilityText" to label,
|
||||||
"title" to title,
|
"title" to title,
|
||||||
"value" to value,
|
"value" to value,
|
||||||
"text" to title.ifEmpty { value },
|
"text" to text,
|
||||||
"hintText" to element.placeholderValue.orEmpty(),
|
"hintText" to element.placeholderValue.orEmpty(),
|
||||||
"resource-id" to element.identifier.orEmpty(),
|
"resource-id" to element.identifier.orEmpty(),
|
||||||
"bounds" to element.frame.boundsString,
|
"bounds" to element.frame.boundsString,
|
||||||
@@ -902,6 +910,6 @@ internal fun iosAxElementToTreeNode(element: hierarchy.AXElement): Map<String, A
|
|||||||
"focused" to element.hasFocus,
|
"focused" to element.hasFocus,
|
||||||
"checked" to checked,
|
"checked" to checked,
|
||||||
"selected" to element.selected,
|
"selected" to element.selected,
|
||||||
"editable" to (elementType in IOS_EDITABLE_ELEMENT_TYPES),
|
"editable" to editable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -66,6 +66,31 @@ class IosHierarchyTest {
|
|||||||
assertEquals("StaticText", attributes["class"])
|
assertEquals("StaticText", attributes["class"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun staticTextFallsBackToLabelForText() {
|
||||||
|
val node = iosAxElementToTreeNode(element(elementType = 48, label = "$1,234.00"))
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val attributes = node["attributes"] as Map<String, String>
|
||||||
|
assertEquals("$1,234.00", attributes["text"])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun buttonFallsBackToLabelForText() {
|
||||||
|
val node = iosAxElementToTreeNode(element(elementType = 9, label = "Sign in"))
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val attributes = node["attributes"] as Map<String, String>
|
||||||
|
assertEquals("Sign in", attributes["text"])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun emptyTextFieldDoesNotLeakLabelIntoText() {
|
||||||
|
val node = iosAxElementToTreeNode(element(elementType = 49, label = "Email"))
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val attributes = node["attributes"] as Map<String, String>
|
||||||
|
assertEquals("", attributes["text"])
|
||||||
|
assertEquals("Email", attributes["accessibilityText"])
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun switchOnIsChecked() {
|
fun switchOnIsChecked() {
|
||||||
val node = iosAxElementToTreeNode(element(elementType = 40, value = "1"))
|
val node = iosAxElementToTreeNode(element(elementType = 40, value = "1"))
|
||||||
|
|||||||
Reference in new issue
Block a user