import XCTest /// Critical path tests for authentication flows. /// Tests login, logout, registration entry, forgot password entry. final class AuthCriticalPathTests: BaseUITestCase { override var relaunchBetweenTests: Bool { true } // MARK: - Helpers private func navigateToLogin() { let loginField = app.textFields[AccessibilityIdentifiers.Authentication.usernameField] if loginField.waitForExistence(timeout: defaultTimeout) { return } // On onboarding — tap login button let onboardingLogin = app.buttons[AccessibilityIdentifiers.Onboarding.loginButton] if onboardingLogin.waitForExistence(timeout: navigationTimeout) { onboardingLogin.tap() } loginField.waitForExistenceOrFail(timeout: navigationTimeout, message: "Login screen should appear") } private func loginAsTestUser() { navigateToLogin() let login = LoginScreenObject(app: app) login.enterUsername("testuser") login.enterPassword("TestPass123!") app.buttons[AccessibilityIdentifiers.Authentication.loginButton].tap() // Wait for main app or verification gate let tabBar = app.tabBars.firstMatch let verification = VerificationScreen(app: app) let deadline = Date().addingTimeInterval(loginTimeout) while Date() < deadline { if tabBar.exists { return } if verification.codeField.exists { verification.enterCode(TestAccountAPIClient.debugVerificationCode) verification.submitCode() _ = tabBar.waitForExistence(timeout: loginTimeout) return } RunLoop.current.run(until: Date().addingTimeInterval(0.5)) } XCTAssertTrue(tabBar.exists, "Should reach main app after login") } // MARK: - Login func testLoginWithValidCredentials() { loginAsTestUser() XCTAssertTrue(app.tabBars.firstMatch.exists, "Tab bar should be visible after login") } func testLoginWithInvalidCredentials() { navigateToLogin() let login = LoginScreenObject(app: app) login.enterUsername("invaliduser") login.enterPassword("wrongpassword") app.buttons[AccessibilityIdentifiers.Authentication.loginButton].tap() // Should stay on login screen let loginField = app.textFields[AccessibilityIdentifiers.Authentication.usernameField] XCTAssertTrue(loginField.waitForExistence(timeout: navigationTimeout), "Should remain on login screen after invalid credentials") XCTAssertFalse(app.tabBars.firstMatch.exists, "Tab bar should not appear after failed login") } // MARK: - Logout func testLogoutFlow() { loginAsTestUser() UITestHelpers.logout(app: app) let loginField = app.textFields[AccessibilityIdentifiers.Authentication.usernameField] let onboardingLogin = app.buttons[AccessibilityIdentifiers.Onboarding.loginButton] let loggedOut = loginField.waitForExistence(timeout: loginTimeout) || onboardingLogin.waitForExistence(timeout: navigationTimeout) XCTAssertTrue(loggedOut, "Should return to login or onboarding after logout") } // MARK: - Registration Entry func testSignUpButtonNavigatesToRegistration() { navigateToLogin() app.buttons[AccessibilityIdentifiers.Authentication.signUpButton].tap() let registerUsername = app.textFields[AccessibilityIdentifiers.Authentication.registerUsernameField] XCTAssertTrue(registerUsername.waitForExistence(timeout: navigationTimeout), "Registration form should appear") } // MARK: - Forgot Password func testForgotPasswordButtonExists() { navigateToLogin() let forgotButton = app.buttons[AccessibilityIdentifiers.Authentication.forgotPasswordButton] XCTAssertTrue(forgotButton.waitForExistence(timeout: defaultTimeout), "Forgot password button should exist") } }