diff --git a/Tests iOS/AppLaunchTests.swift b/Tests iOS/AppLaunchTests.swift index 6eea5ae..ef96efc 100644 --- a/Tests iOS/AppLaunchTests.swift +++ b/Tests iOS/AppLaunchTests.swift @@ -51,7 +51,8 @@ final class AppLaunchTests: BaseUITestCase { } /// Wait for a tab to become selected (iOS 26 Liquid Glass may delay state updates). - private func assertTabSelected(_ tab: XCUIElement, name: String, timeout: TimeInterval = 3) { + private func assertTabSelected(_ tab: XCUIElement, name: String, timeout: TimeInterval = 8) { + // Re-query the element to get fresh state, since isSelected can be stale. let predicate = NSPredicate(format: "isSelected == true") let expectation = XCTNSPredicateExpectation(predicate: predicate, object: tab) let result = XCTWaiter.wait(for: [expectation], timeout: timeout) diff --git a/Tests iOS/DeepLinkTests.swift b/Tests iOS/DeepLinkTests.swift index 7cbcb02..821a466 100644 --- a/Tests iOS/DeepLinkTests.swift +++ b/Tests iOS/DeepLinkTests.swift @@ -57,12 +57,12 @@ final class DeepLinkTests: BaseUITestCase { app.open(subscribeURL) // Subscription view should appear as a sheet. - // Look for common subscription UI elements. - let subscribeText = app.staticTexts.matching( - NSPredicate(format: "label CONTAINS[c] 'subscribe' OR label CONTAINS[c] 'premium' OR label CONTAINS[c] 'upgrade' OR label CONTAINS[c] 'Reflect+'") - ).firstMatch + // Detect the SubscriptionStoreView container (works even when products are unavailable in test). + let storeContainer = app.descendants(matching: .any) + .matching(identifier: "Subscription Store View Container") + .firstMatch - let found = subscribeText.waitForExistence(timeout: 8) + let found = storeContainer.waitForExistence(timeout: 8) captureScreenshot(name: "deeplink_subscribe_result") diff --git a/Tests iOS/Screens/SettingsScreen.swift b/Tests iOS/Screens/SettingsScreen.swift index a819af5..2385ee9 100644 --- a/Tests iOS/Screens/SettingsScreen.swift +++ b/Tests iOS/Screens/SettingsScreen.swift @@ -53,7 +53,7 @@ struct SettingsScreen { func assertVisible(file: StaticString = #file, line: UInt = #line) { XCTAssertTrue( - settingsHeader.waitForExistence(timeout: 5), + settingsHeader.waitForExistence(timeout: 8), "Settings header should be visible", file: file, line: line ) diff --git a/Tests iOS/SettingsActionTests.swift b/Tests iOS/SettingsActionTests.swift index dea04b5..d80fd0f 100644 --- a/Tests iOS/SettingsActionTests.swift +++ b/Tests iOS/SettingsActionTests.swift @@ -45,10 +45,14 @@ final class SettingsActionTests: BaseUITestCase { tabBar.tapDay() // App should remain usable after clearing data. - assertDayContentVisible(timeout: 10) + // After a full clear, Day view may show mood header, entry rows, or empty state. + let hasEntry = app.firstEntryRow.waitForExistence(timeout: 10) + let hasMoodHeader = app.element(UITestID.Day.moodHeader).waitForExistence(timeout: 2) + let hasEmptyState = app.element(UITestID.Day.emptyStateNoData).waitForExistence(timeout: 2) + XCTAssertTrue(hasEntry || hasMoodHeader || hasEmptyState, + "Day view should show entries, mood header, or empty state after clearing data") - // Clear action should not crash the app, even if the resulting day content - // is rehydrated by app-specific defaults/placeholders. + // Clear action should not crash the app. XCTAssertTrue(app.tabBars.firstMatch.exists, "App should remain responsive after clearing data") captureScreenshot(name: "data_cleared") diff --git a/Tests iOS/StabilityTests.swift b/Tests iOS/StabilityTests.swift index aebe370..d77a132 100644 --- a/Tests iOS/StabilityTests.swift +++ b/Tests iOS/StabilityTests.swift @@ -67,7 +67,7 @@ final class StabilityTests: BaseUITestCase { } /// Wait for a tab to become selected (iOS 26 Liquid Glass may delay state updates). - private func assertTabSelected(_ tab: XCUIElement, name: String, timeout: TimeInterval = 3) { + private func assertTabSelected(_ tab: XCUIElement, name: String, timeout: TimeInterval = 8) { let predicate = NSPredicate(format: "isSelected == true") let expectation = XCTNSPredicateExpectation(predicate: predicate, object: tab) let result = XCTWaiter.wait(for: [expectation], timeout: timeout)