From d6188df667205cd7bceabd328e1e2674caa0b477 Mon Sep 17 00:00:00 2001 From: PJ Date: Fri, 5 Jun 2026 18:37:57 +0530 Subject: [PATCH] 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. --- .../dev/sanderling/sidecar/DriverBackend.kt | 14 ++++++++--- .../sanderling/sidecar/IosHierarchyTest.kt | 25 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/sidecar/src/main/kotlin/dev/sanderling/sidecar/DriverBackend.kt b/sidecar/src/main/kotlin/dev/sanderling/sidecar/DriverBackend.kt index a5c599e..d6e668b 100644 --- a/sidecar/src/main/kotlin/dev/sanderling/sidecar/DriverBackend.kt +++ b/sidecar/src/main/kotlin/dev/sanderling/sidecar/DriverBackend.kt @@ -878,12 +878,20 @@ internal fun iosAxElementToTreeNode(element: hierarchy.AXElement): Map + 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 + 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 + assertEquals("", attributes["text"]) + assertEquals("Email", attributes["accessibilityText"]) + } + @Test fun switchOnIsChecked() { val node = iosAxElementToTreeNode(element(elementType = 40, value = "1"))