commit 92b7b5528150afc41e4d0b91f09b98a217a4c0f5
parent 7afbc3b60046362e6f12eb677ab202e9768e91d5
Author: triesap <tyson@radroots.org>
Date: Fri, 28 Aug 2026 18:32:15 +0000
test: bind persona submission to status
- Observe the ordinary Add status lifecycle instead of virtualized row presence.
- Use one visible submit tap so qualification cannot introduce duplicate events.
- Scroll to the terminal submit control before reading its safe result value.
- Keep failure diagnostics from dereferencing absent XCUITest elements.
Diffstat:
1 file changed, 26 insertions(+), 31 deletions(-)
diff --git a/RadrootsUITests/RadrootsRemoteQualificationUITests.swift b/RadrootsUITests/RadrootsRemoteQualificationUITests.swift
@@ -1067,12 +1067,14 @@ final class RadrootsRemoteQualificationUITests: XCTestCase {
@MainActor
private func submitAndWait(_ app: XCUIApplication, submit: XCUIElement) -> String? {
- let priorSubmitValue = submit.value as? String
+ let status = app.staticTexts.matching(identifier: "radroots.add.status").firstMatch
+ let priorStatusLabel = status.exists ? status.label : nil
guard
tapSubmitUntilWorkStarts(
app,
submit: submit,
- priorSubmitValue: priorSubmitValue
+ status: status,
+ priorStatusLabel: priorStatusLabel
)
else {
XCTFail(
@@ -1084,8 +1086,8 @@ final class RadrootsRemoteQualificationUITests: XCTestCase {
guard
waitForWorkToFinish(
app,
- submit: submit,
- priorSubmitValue: priorSubmitValue
+ status: status,
+ priorStatusLabel: priorStatusLabel
)
else {
XCTFail(
@@ -1094,6 +1096,11 @@ final class RadrootsRemoteQualificationUITests: XCTestCase {
)
return nil
}
+ scrollTo(app, element: submit)
+ guard submit.waitForExistence(timeout: 10) else {
+ XCTFail("The terminal Add submission control was unavailable")
+ return nil
+ }
return submit.value as? String ?? "missing"
}
@@ -1123,18 +1130,13 @@ final class RadrootsRemoteQualificationUITests: XCTestCase {
@MainActor
private func waitForWorkToFinish(
_ app: XCUIApplication,
- submit: XCUIElement,
- priorSubmitValue: String?
+ status: XCUIElement,
+ priorStatusLabel: String?
) -> Bool {
let progress = app.descendants(matching: .any)["radroots.add.progress"]
let finished = NSPredicate { _, _ in
- guard !progress.exists else { return false }
- guard submit.exists else {
- return app.buttons["radroots.add.new"].exists
- }
- let submitValue = submit.value as? String
- return submitValue != priorSubmitValue
- && submitValue != "Working"
+ guard !progress.exists, status.exists else { return false }
+ return !status.label.isEmpty && status.label != priorStatusLabel
}
let expectation = XCTNSPredicateExpectation(predicate: finished, object: app)
return XCTWaiter.wait(for: [expectation], timeout: 180) == .completed
@@ -1144,29 +1146,19 @@ final class RadrootsRemoteQualificationUITests: XCTestCase {
private func tapSubmitUntilWorkStarts(
_ app: XCUIApplication,
submit: XCUIElement,
- priorSubmitValue: String?
+ status: XCUIElement,
+ priorStatusLabel: String?
) -> Bool {
let progress = app.descendants(matching: .any)["radroots.add.progress"]
let started = NSPredicate { _, _ in
- guard !progress.exists else { return true }
- guard submit.exists else { return true }
- let submitValue = submit.value as? String
- return submitValue != priorSubmitValue
+ if progress.exists { return true }
+ if status.exists { return status.label != priorStatusLabel }
+ return priorStatusLabel != nil
}
- for _ in 0..<3 {
- submit.tap()
- let expectation = XCTNSPredicateExpectation(predicate: started, object: app)
- if XCTWaiter.wait(for: [expectation], timeout: 5) == .completed {
- return true
- }
- guard waitUntilHittable(submit, timeout: 5),
- isUnobscured(submit, above: app.tabBars.firstMatch)
- else {
- return false
- }
- }
- return false
+ submit.tap()
+ let expectation = XCTNSPredicateExpectation(predicate: started, object: app)
+ return XCTWaiter.wait(for: [expectation], timeout: 10) == .completed
}
@MainActor
@@ -1188,6 +1180,9 @@ final class RadrootsRemoteQualificationUITests: XCTestCase {
let progress = app.descendants(matching: .any)["radroots.add.progress"]
let status = app.staticTexts.matching(identifier: "radroots.add.status").firstMatch
let statusLabel = status.exists ? status.label : "missing"
+ guard submit.exists else {
+ return "submit.exists=false, progress.exists=\(progress.exists), status=\(statusLabel)"
+ }
let tabBar = app.tabBars.firstMatch
return "submit.exists=\(submit.exists), submit.enabled=\(submit.isEnabled), "
+ "submit.hittable=\(submit.isHittable), submit.value=\(String(describing: submit.value)), "