Fix 4 flaky UI tests for iOS 26 compatibility
- AppLaunchTests/StabilityTests: Increase assertTabSelected timeout to 8s for iOS 26 Liquid Glass delayed isSelected state updates - DeepLinkTests: Detect SubscriptionStoreView container instead of text labels, since Apple's native view shows "Subscription Unavailable" in test storefront - SettingsActionTests: Check for empty state after clearing data, bump Settings header timeout to 8s Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user