Complete re-validation remediation: KMP architecture, iOS platform, XCUITest rewrite
Phases 1-6 of fixes.md — closes all 13 issues from codex_issues_2.md re-validation: KMP Architecture: - Fix subscription purchase/restore response contract (VerificationResponse aligned) - Add feature benefits auth token + APILayer init flow - Remove ResidenceFormScreen direct API bypass (use APILayer) - Wire paywall purchase/restore to real SubscriptionApi calls iOS Platform: - Add iOS Keychain token storage via Swift KeychainHelper - Implement Google Sign-In via ASWebAuthenticationSession (GoogleSignInManager) - DocumentViewModelWrapper observes DataManager for auto-updates - Add missing accessibility identifiers (document, task columns, Google Sign-In) XCUITest Rewrite: - Rewrite test infrastructure: zero sleep() calls, accessibility ID lookups - Create AuthCriticalPathTests and NavigationCriticalPathTests - Delete 14 legacy brittle test files (Suite0-10, templates) - Fix CaseraTests module import (@testable import Casera) All platforms build clean. TEST BUILD SUCCEEDED. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,30 +2,32 @@ import XCTest
|
||||
|
||||
/// Page object for the main tab view that appears after login.
|
||||
///
|
||||
/// Provides navigation to each tab (Residences, Tasks, Contractors, Documents, Profile)
|
||||
/// and a logout flow. Uses predicate-based element lookup to match the existing test patterns.
|
||||
/// The app has 4 tabs: Residences, Tasks, Contractors, Documents.
|
||||
/// Profile is accessed via the settings button on the Residences screen.
|
||||
/// Uses accessibility identifiers for reliable element lookup.
|
||||
class MainTabScreen: BaseScreen {
|
||||
|
||||
// MARK: - Tab Elements
|
||||
|
||||
var residencesTab: XCUIElement {
|
||||
app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Residences'")).firstMatch
|
||||
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.residencesTab]
|
||||
}
|
||||
|
||||
var tasksTab: XCUIElement {
|
||||
app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Tasks'")).firstMatch
|
||||
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.tasksTab]
|
||||
}
|
||||
|
||||
var contractorsTab: XCUIElement {
|
||||
app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Contractors'")).firstMatch
|
||||
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.contractorsTab]
|
||||
}
|
||||
|
||||
var documentsTab: XCUIElement {
|
||||
app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Documents'")).firstMatch
|
||||
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.documentsTab]
|
||||
}
|
||||
|
||||
var profileTab: XCUIElement {
|
||||
app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Profile'")).firstMatch
|
||||
/// Settings button on the Residences tab (leads to profile/settings).
|
||||
var settingsButton: XCUIElement {
|
||||
app.buttons[AccessibilityIdentifiers.Navigation.settingsButton]
|
||||
}
|
||||
|
||||
override var isDisplayed: Bool {
|
||||
@@ -58,18 +60,20 @@ class MainTabScreen: BaseScreen {
|
||||
return self
|
||||
}
|
||||
|
||||
/// Navigates to settings/profile via the settings button on Residences tab.
|
||||
@discardableResult
|
||||
func goToProfile() -> Self {
|
||||
waitForElement(profileTab).tap()
|
||||
func goToSettings() -> Self {
|
||||
goToResidences()
|
||||
waitForElement(settingsButton).tap()
|
||||
return self
|
||||
}
|
||||
|
||||
// MARK: - Logout
|
||||
|
||||
/// Logs out by navigating to the Profile tab and tapping the logout button.
|
||||
/// Logs out by navigating to settings and tapping the logout button.
|
||||
/// Handles the confirmation alert automatically.
|
||||
func logout() {
|
||||
goToProfile()
|
||||
goToSettings()
|
||||
|
||||
let logoutButton = app.buttons[AccessibilityIdentifiers.Profile.logoutButton]
|
||||
if logoutButton.waitForExistence(timeout: 5) {
|
||||
|
||||
Reference in New Issue
Block a user