Stabilize UI test suite — 39% → 98%+ pass rate
Fix root causes uncovered across repeated parallel runs: - Admin seed password "test1234" failed backend complexity (needs uppercase). Bumped to "Test1234" across every hard-coded reference (AuthenticatedUITestCase default, TestAccountManager seeded-login default, Tests/*Integration suites, Tests/DataLayer, OnboardingTests). - dismissKeyboard() tapped the Return key first, which races SwiftUI's TextField binding on numeric keyboards (postal, year built) and complex forms. KeyboardDismisser now prefers the keyboard-toolbar Done button, falls back to tap-above-keyboard, then keyboard Return. BaseUITestCase.clearAndEnterText uses the same helper. - Form page-object save() helpers (task / residence / contractor / document) now dismiss the keyboard and scroll the submit button into view before tapping, eliminating Suite4/6/7/8 "save button stayed visible" timeouts. - Suite6 createTask was producing a disabled-save race: under parallel contention the SwiftUI title binding lagged behind XCUITest typing. Rewritten to inline Suite5's proven pattern with a retry that nudges the title binding via a no-op edit when Add is disabled, and an explicit refreshTasks after creation. - Suite8 selectProperty now picks the residence by name (works with menu, list, or wheel picker variants) — avoids bad form-cell taps when the picker hasn't fully rendered. - run_ui_tests.sh uses 2 workers instead of 4 (4-worker contention caused XCUITest typing races across Suite5/7/8) and isolates Suite6 in its own 2-worker phase after the main parallel phase. - Add AAA_SeedTests / SuiteZZ_CleanupTests: the runner's Phase 1 (seed) and Phase 3 (cleanup) depend on these and they were missing from version control.
This commit is contained in:
@@ -113,6 +113,9 @@ struct TaskFormScreen {
|
||||
}
|
||||
|
||||
func save() {
|
||||
KeyboardDismisser.dismiss(app: app)
|
||||
// Scroll the form so any focused-field state commits before the
|
||||
// submit action reads it. Without this the title binding can lag.
|
||||
app.swipeUp()
|
||||
saveButton.waitForExistenceOrFail(timeout: 10)
|
||||
saveButton.forceTap()
|
||||
@@ -232,7 +235,8 @@ struct ContractorFormScreen {
|
||||
}
|
||||
|
||||
func save() {
|
||||
app.swipeUp()
|
||||
KeyboardDismisser.dismiss(app: app)
|
||||
if !saveButton.exists || !saveButton.isHittable { app.swipeUp() }
|
||||
saveButton.waitForExistenceOrFail(timeout: 10)
|
||||
saveButton.forceTap()
|
||||
_ = saveButton.waitForNonExistence(timeout: 15)
|
||||
@@ -399,13 +403,10 @@ struct DocumentFormScreen {
|
||||
}
|
||||
|
||||
func save() {
|
||||
// Dismiss keyboard first
|
||||
app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.15)).tap()
|
||||
_ = app.keyboards.firstMatch.waitForNonExistence(timeout: 3)
|
||||
|
||||
if !saveButton.exists || !saveButton.isHittable {
|
||||
app.swipeUp()
|
||||
}
|
||||
KeyboardDismisser.dismiss(app: app)
|
||||
// Unconditional swipe-up matches the task form fix — forces SwiftUI
|
||||
// state to commit before the submit button reads it.
|
||||
app.swipeUp()
|
||||
saveButton.waitForExistenceOrFail(timeout: 10)
|
||||
if saveButton.isHittable {
|
||||
saveButton.tap()
|
||||
|
||||
Reference in New Issue
Block a user