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>
93 lines
2.6 KiB
Swift
93 lines
2.6 KiB
Swift
import XCTest
|
|
|
|
/// Page object for the main tab view that appears after login.
|
|
///
|
|
/// 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[AccessibilityIdentifiers.Navigation.residencesTab]
|
|
}
|
|
|
|
var tasksTab: XCUIElement {
|
|
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.tasksTab]
|
|
}
|
|
|
|
var contractorsTab: XCUIElement {
|
|
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.contractorsTab]
|
|
}
|
|
|
|
var documentsTab: XCUIElement {
|
|
app.tabBars.buttons[AccessibilityIdentifiers.Navigation.documentsTab]
|
|
}
|
|
|
|
/// Settings button on the Residences tab (leads to profile/settings).
|
|
var settingsButton: XCUIElement {
|
|
app.buttons[AccessibilityIdentifiers.Navigation.settingsButton]
|
|
}
|
|
|
|
override var isDisplayed: Bool {
|
|
residencesTab.waitForExistence(timeout: timeout)
|
|
}
|
|
|
|
// MARK: - Navigation
|
|
|
|
@discardableResult
|
|
func goToResidences() -> Self {
|
|
waitForElement(residencesTab).tap()
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
func goToTasks() -> Self {
|
|
waitForElement(tasksTab).tap()
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
func goToContractors() -> Self {
|
|
waitForElement(contractorsTab).tap()
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
func goToDocuments() -> Self {
|
|
waitForElement(documentsTab).tap()
|
|
return self
|
|
}
|
|
|
|
/// Navigates to settings/profile via the settings button on Residences tab.
|
|
@discardableResult
|
|
func goToSettings() -> Self {
|
|
goToResidences()
|
|
waitForElement(settingsButton).tap()
|
|
return self
|
|
}
|
|
|
|
// MARK: - Logout
|
|
|
|
/// Logs out by navigating to settings and tapping the logout button.
|
|
/// Handles the confirmation alert automatically.
|
|
func logout() {
|
|
goToSettings()
|
|
|
|
let logoutButton = app.buttons[AccessibilityIdentifiers.Profile.logoutButton]
|
|
if logoutButton.waitForExistence(timeout: 5) {
|
|
waitForHittable(logoutButton).tap()
|
|
|
|
// Handle confirmation alert
|
|
let alert = app.alerts.firstMatch
|
|
if alert.waitForExistence(timeout: 3) {
|
|
let confirmLogout = alert.buttons["Log Out"]
|
|
if confirmLogout.exists {
|
|
confirmLogout.tap()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|