import XCTest /// Authentication flow tests /// Based on working SimpleLoginTest pattern final class Suite2_AuthenticationTests: XCTestCase { var app: XCUIApplication! override func setUpWithError() throws { continueAfterFailure = false app = XCUIApplication() app.launch() ensureLoggedOut() } override func tearDownWithError() throws { app = nil } // MARK: - Helper Methods private func ensureLoggedOut() { UITestHelpers.ensureLoggedOut(app: app) } private func login(username: String, password: String) { UITestHelpers.login(app: app, username: username, password: password) } // MARK: - 1. Error/Validation Tests func test01_loginWithInvalidCredentials() { // Given: User is on login screen let welcomeText = app.staticTexts["Welcome Back"] XCTAssertTrue(welcomeText.exists, "Should be on login screen") // When: User logs in with invalid credentials login(username: "wronguser", password: "wrongpass") // Then: User should see error message and stay on login screen sleep(3) // Wait for API response // Should still be on login screen XCTAssertTrue(welcomeText.exists, "Should still be on login screen") // Sign In button should still be visible (not logged in) let signInButton = app.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Sign In'")).firstMatch XCTAssertTrue(signInButton.exists, "Should still see Sign In button") } // MARK: - 2. Creation Tests (Login/Session) func test02_loginWithValidCredentials() { // Given: User is on login screen let welcomeText = app.staticTexts["Welcome Back"] XCTAssertTrue(welcomeText.exists, "Should be on login screen") // When: User logs in with valid credentials login(username: "testuser", password: "TestPass123!") // Then: User should see main tab view let residencesTab = app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Residences'")).firstMatch let didNavigate = residencesTab.waitForExistence(timeout: 10) XCTAssertTrue(didNavigate, "Should navigate to main app after successful login") } // MARK: - 3. View/UI Tests func test03_passwordVisibilityToggle() { // Given: User is on login screen let passwordField = app.secureTextFields.containing(NSPredicate(format: "placeholderValue CONTAINS[c] 'password'")).firstMatch XCTAssertTrue(passwordField.waitForExistence(timeout: 5), "Password field should exist") // When: User types password passwordField.tap() passwordField.typeText("secret123") // Then: Find and tap the eye icon (visibility toggle) let eyeButton = app.buttons[AccessibilityIdentifiers.Authentication.passwordVisibilityToggle].firstMatch XCTAssertTrue(eyeButton.waitForExistence(timeout: 5), "Password visibility toggle button must exist") eyeButton.tap() sleep(1) // Password should now be visible in a regular text field let visiblePasswordField = app.textFields.containing(NSPredicate(format: "placeholderValue CONTAINS[c] 'password'")).firstMatch XCTAssertTrue(visiblePasswordField.exists, "Password should be visible after toggle") } // MARK: - 4. Navigation Tests func test04_navigationToSignUp() { // Given: User is on login screen let welcomeText = app.staticTexts["Welcome Back"] XCTAssertTrue(welcomeText.exists, "Should be on login screen") // When: User taps Sign Up button let signUpButton = app.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Sign Up'")).firstMatch XCTAssertTrue(signUpButton.exists, "Sign Up button should exist") signUpButton.tap() // Then: Registration screen should appear sleep(2) let registerButton = app.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Register' OR label CONTAINS[c] 'Create Account'")).firstMatch XCTAssertTrue(registerButton.waitForExistence(timeout: 5), "Should navigate to registration screen") } func test05_forgotPasswordNavigation() { // Given: User is on login screen let welcomeText = app.staticTexts["Welcome Back"] XCTAssertTrue(welcomeText.exists, "Should be on login screen") // When: User taps Forgot Password button let forgotPasswordButton = app.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Forgot Password'")).firstMatch XCTAssertTrue(forgotPasswordButton.exists, "Forgot Password button should exist") forgotPasswordButton.tap() // Then: Password reset screen should appear sleep(2) // Look for email field or reset button let emailField = app.textFields.containing(NSPredicate(format: "placeholderValue CONTAINS[c] 'email'")).firstMatch let resetButton = app.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Reset' OR label CONTAINS[c] 'Send'")).firstMatch let passwordResetScreenAppeared = emailField.exists || resetButton.exists XCTAssertTrue(passwordResetScreenAppeared, "Should navigate to password reset screen") } // MARK: - 5. Delete/Logout Tests func test06_logout() { // Given: User is logged in login(username: "testuser", password: "TestPass123!") let residencesTab = app.tabBars.buttons.containing(NSPredicate(format: "label CONTAINS[c] 'Residences'")).firstMatch XCTAssertTrue(residencesTab.waitForExistence(timeout: 10), "Should be logged in") // When: User logs out UITestHelpers.logout(app: app) // Then: User should be back on login screen (verified by UITestHelpers.logout) } }