field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

commit 25eaef705cf072176cf62e6cb4a2058ec36d7415
parent c519f7d0e858d82c229e0a7fdce6eae949ba3573
Author: triesap <tyson@radroots.org>
Date:   Fri, 28 Aug 2026 20:27:39 +0000

ios: expose stable Add operation semantics

- publish Working and Ready on the existing Add form boundary
- avoid inferring form state from disabled descendant controls
- wait for semantic settlement before locating terminal evidence
- preserve ordinary accessible UI behavior at large content sizes

Diffstat:
MRadroots/Views/RadrootsAddView.swift | 1+
MRadrootsUITests/RadrootsRemoteQualificationUITests.swift | 4++--
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Radroots/Views/RadrootsAddView.swift b/Radroots/Views/RadrootsAddView.swift @@ -99,6 +99,7 @@ struct RadrootsAddView: View { .headerProminence(.increased) .tint(.primary) .accessibilityIdentifier("radroots.add.root") + .accessibilityValue(store.isWorking ? "Working" : "Ready") .safeAreaInset(edge: .bottom, spacing: 0) { if !dynamicTypeSize.isAccessibilitySize { submitButton diff --git a/RadrootsUITests/RadrootsRemoteQualificationUITests.swift b/RadrootsUITests/RadrootsRemoteQualificationUITests.swift @@ -1169,7 +1169,7 @@ final class RadrootsRemoteQualificationUITests: XCTestCase { let addRoot = app.descendants(matching: .any)["radroots.add.root"] let progress = app.descendants(matching: .any)["radroots.add.progress"] let started = NSPredicate { _, _ in - if progress.exists || addRoot.exists && !addRoot.isEnabled { + if progress.exists || addRoot.value as? String == "Working" { return true } if status.exists, !status.label.isEmpty, status.label != priorStatusLabel { @@ -1182,7 +1182,7 @@ final class RadrootsRemoteQualificationUITests: XCTestCase { return false } let settled = NSPredicate { _, _ in - addRoot.exists && addRoot.isEnabled && !progress.exists + addRoot.value as? String == "Ready" && !progress.exists } let settleExpectation = XCTNSPredicateExpectation(predicate: settled, object: app) return XCTWaiter.wait(for: [settleExpectation], timeout: 180) == .completed