AccessibilityIdentifiers.swift (3233B)
1 /* 2 * This file is part of GNU Taler, ©2026 Taler Systems S.A. 3 * See LICENSE.md 4 */ 5 /** 6 * Stable accessibility identifiers for UI automation. 7 * 8 * Identifiers are not shown or spoken anywhere — they exist so that a UI test 9 * can address a control by something that does not change when its label is 10 * reworded or translated. Keeping them in one place makes them greppable and 11 * keeps them unique. 12 * 13 * Two rules when adding to this list: 14 * 15 * 1. **Put identifiers on leaves, never on containers.** SwiftUI propagates 16 * `.accessibilityIdentifier` to every accessibility element inside the view 17 * it is applied to, *overwriting* identifiers those elements already carry. 18 * On a container that yields a set of duplicates — useless for addressing — 19 * and silently clobbers anything more specific underneath. 20 * 2. Applying an identifier does not change what VoiceOver reads, nor the 21 * shape of the accessibility tree; `.accessibilityLabel`, 22 * `.accessibilityHint` and `.accessibilityElement(children:)` keep doing 23 * exactly what they did. Order still matters, so add the identifier next 24 * to the other accessibility modifiers rather than before them. 25 */ 26 import Foundation 27 28 public enum A11yID { 29 // MARK: - toolbar and navigation leaves 30 public static let hamburgerButton = "button.hamburger" 31 public static let qrButton = "button.qr" 32 public static let doneButton = "button.done" 33 public static let plusButton = "button.plus" 34 public static let moreButton = "button.more" 35 public static let settingsButton = "button.settings" 36 public static let backButton = "button.back" 37 public static let forwardButton = "button.forward" 38 public static let arrowUpButton = "button.arrowUp" 39 public static let arrowDownButton = "button.arrowDown" 40 public static let zoomInButton = "button.zoomIn" 41 public static let zoomOutButton = "button.zoomOut" 42 public static let reloadButton = "button.reload" 43 public static let pasteButton = "button.paste" 44 public static let linkButton = "button.link" 45 46 // MARK: - copy / share leaves 47 /// Generic fallback; call sites that matter pass their own, e.g. 48 /// `A11yID.copy("iban")`. 49 public static let copyButton = "button.copy" 50 public static let shareButton = "button.share" 51 public static func copy(_ what: String) -> String { "button.copy.\(what)" } 52 public static func share(_ what: String) -> String { "button.share.\(what)" } 53 54 // MARK: - loading / stalled leaves 55 public static let loadingCancelButton = "button.loading.cancel" 56 public static let stalledRetryButton = "button.stalled.retry" 57 58 // MARK: - empty-wallet (onboarding) leaves 59 public static let demoCashButton = "button.onboarding.demoCash" 60 public static let withdrawRealButton = "button.onboarding.withdrawReal" 61 62 // MARK: - withdrawal flow leaves 63 public static let tosOpenButton = "button.withdraw.tos.open" 64 public static let tosAcceptButton = "button.withdraw.tos.accept" 65 public static let withdrawConfirmButton = "button.withdraw.confirm" 66 public static let withdrawAcceptButton = "button.withdraw.accept" 67 }