View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0011960 | Taler | wallet (iOS App) | public | 2026-11-07 14:01 | 2026-11-07 14:01 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0011960: OIM action and chest buttons carry no accessibility label, so VoiceOver announces the image asset name ("SendMoney", "ChestOpenSLE") | ||||
| Description | In OIM mode (Balances in landscape right), the four primary controls are buttons wrapping a bare `Image`, and neither the button nor the image is labelled: * `OIMactionButton` -- TalerWallet1/Views/OIM/OIMactionButtons.swift:22-44. `Button(action:) { Image(imageName).resizable().scaledToFit() }`, where `imageName` is "SendMoney" / "Withdraw" / "Deposit" / "Request" (lines 28-33). No `.accessibilityLabel`, no `.accessibilityIdentifier`. * `OIMbalanceButton` -- same file, lines 46-62. `Button(action:) { Image(chestName + chest) }` with `chestName` either "ChestOpen" or "ChestClosed" and `chest` the currency's chest asset suffix. Same omission. SwiftUI therefore falls back to the **image asset name** for the accessibility label, and that is what VoiceOver reads out. Captured from the accessibility tree of the running app (GNU_Taler, iOS 27.2 simulator, wallet holding KUDOS and SLE balances), Balances tab rotated to landscape right: button label="ChestOpenSLE" frame=[250, 0, 80, 80] button label="SendMoney" frame=[522, 0, 83, 80] button label="Request" frame=[732, 88, 80, 80] button label="ChestClosedSLE" frame=[452, 151, 80, 80] These are developer-facing, unlocalized asset names: a blind user is told "SendMoney" and "ChestOpenSLE" rather than "Send money" and "Scallop open, SLE 130.90". The same codebase does this correctly elsewhere, so it is an omission rather than a convention: `QRButton` (TalerCommon/HelperViews/Buttons.swift:109-134) builds the same shape -- a `Button` around an `Image` with the title hidden -- and sets both `.accessibilityLabel(scanText)` with a localized "Scan QR code" and `.accessibilityIdentifier(A11yID.qrButton)`. Related but distinct: 11931 is about missing accessibility *identifiers* for UI automation, and 11946 about localized literals lost through `String`. This one is a missing *label* on controls that have no text at all, so there is nothing for VoiceOver to fall back to but the asset name. | ||||
| Steps To Reproduce | 1. Run the iOS wallet with at least one non-zero balance. 2. Go to the Balances tab and rotate the device to landscape right, which is what activates OIM mode (Controller.swift:191-201, `oimModeActive = sheetActive ? false : isLandscapeRight`). 3. Inspect the accessibility tree -- Xcode's Accessibility Inspector, or `print(app.debugDescription)` from XCUITest. The send, request and chest buttons appear with labels "SendMoney", "Request", "ChestOpen<CUR>" and "ChestClosed<CUR>". 4. With VoiceOver enabled, those strings are what is announced on focus. Expected: a localized, human description for each -- "Send money", "Request payment", "Withdraw", "Deposit", and for the chest something naming the currency and the open/closed state. | ||||
| Additional Information | Suggested fix, in OIMactionButtons.swift: * Give `OIMactions` a `label` of its own, localized, next to the existing `imageName` switch, and apply it with `.accessibilityLabel` on the `Button`. An `.accessibilityIdentifier` on the same button would also give automation a stable handle (cf. 11931); note that per earlier measurement an identifier belongs on the leaf, since on a container it propagates to every descendant. * `OIMbalanceButton` needs the currency and the open/closed state in its label, and `.accessibilityAddTraits(.isSelected)` (or a value) would carry "open" better than folding it into the label. While looking at the same screen: the drawer's denomination buttons are labelled with a bare numeral -- "10'000", "2'000", "500", "50", "10", "5", "1" -- with no currency and no unit, so VoiceOver announces a number with no indication of what it is. Worth the same pass, though it may deserve its own issue if the fix is separate. Found while extending a coverage-guided XCUITest explorer over the OIM views: the walk took twenty-four consecutive scroll-to-look actions on this screen because its steering word list named none of these four buttons, and tracing why is what surfaced the labels. | ||||
| Tags | No tags attached. | ||||
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-11-07 14:01 | bot-cg | New Issue |