Files
honeyDueKMP/iosApp/iosAppUITests/AuthenticationUITests.swift
Trey t 7dce211681 wip
2025-11-08 16:02:01 -06:00

270 lines
10 KiB
Swift

import XCTest
/// Comprehensive tests for authentication flows
final class AuthenticationUITests: BaseUITest {
// MARK: - Login Tests
func testLoginWithValidCredentials() {
// Given: User is on login screen
XCTAssertTrue(app.staticTexts["MyCrib"].exists)
// When: User enters valid credentials and taps login
login(username: "testuser", password: "TestPass123!")
// Then: User should be navigated to main screen
let residencesTab = app.tabBars.buttons["Residences"]
XCTAssertTrue(residencesTab.waitForExistence(timeout: 10), "Should navigate to main tab view")
}
func testLoginWithInvalidCredentials() {
// Given: User is on login screen
XCTAssertTrue(app.staticTexts["MyCrib"].exists)
// When: User enters invalid credentials
login(username: "invaliduser", password: "WrongPassword!")
// Then: Error message should be displayed
let errorMessage = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'Invalid username or password'"))
XCTAssertTrue(errorMessage.firstMatch.waitForExistence(timeout: 5), "Should show error message")
// And: User should remain on login screen
XCTAssertTrue(app.staticTexts["MyCrib"].exists)
}
func testLoginWithEmptyFields() {
// Given: User is on login screen
let loginButton = app.buttons["Login"]
// When: User taps login without entering credentials
loginButton.tap()
// Then: Validation error should be shown
let usernameError = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'Username is required'"))
XCTAssertTrue(usernameError.firstMatch.waitForExistence(timeout: 3), "Should show username required error")
}
func testPasswordVisibilityToggle() {
// Given: User has typed password
let passwordField = app.secureTextFields["Password"]
let textField = app.textFields["Password"]
let toggleButton = app.buttons.matching(identifier: "eye").firstMatch
passwordField.tap()
passwordField.typeText("TestPassword")
// When: User taps the visibility toggle
toggleButton.tap()
// Then: Password should be visible as text
XCTAssertTrue(textField.exists, "Password should be visible")
// When: User taps toggle again
toggleButton.tap()
// Then: Password should be hidden again
XCTAssertTrue(passwordField.exists, "Password should be secure")
}
// MARK: - Registration Tests
func testRegistrationWithValidData() {
// Given: User is on login screen
let signUpButton = app.buttons["Sign Up"]
// When: User taps Sign Up
signUpButton.tap()
// Then: Registration screen should be displayed
assertNavigatedTo(title: "Create Account", timeout: 3)
// When: User fills in valid registration data
let timestamp = Int(Date().timeIntervalSince1970)
register(
username: "newuser\(timestamp)",
email: "newuser\(timestamp)@test.com",
password: "TestPass123!",
firstName: "Test",
lastName: "User"
)
// Then: User should be registered and shown verification screen
let verificationTitle = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'Verify'"))
XCTAssertTrue(verificationTitle.firstMatch.waitForExistence(timeout: 10), "Should show verification screen")
}
func testRegistrationWithExistingUsername() {
// Given: User is on registration screen
let signUpButton = app.buttons["Sign Up"]
signUpButton.tap()
// When: User registers with existing username
register(
username: "existinguser",
email: "newemail@test.com",
password: "TestPass123!"
)
// Then: Error message should be displayed
let errorMessage = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'username' OR label CONTAINS[c] 'already exists'"))
XCTAssertTrue(errorMessage.firstMatch.waitForExistence(timeout: 5), "Should show username exists error")
}
func testRegistrationWithInvalidEmail() {
// Given: User is on registration screen
let signUpButton = app.buttons["Sign Up"]
signUpButton.tap()
// When: User enters invalid email
let emailField = app.textFields["Email"]
let registerButton = app.buttons["Register"]
emailField.tap()
emailField.typeText("invalidemail")
registerButton.tap()
// Then: Email validation error should be shown
let errorMessage = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'valid email'"))
XCTAssertTrue(errorMessage.firstMatch.waitForExistence(timeout: 3), "Should show email validation error")
}
func testRegistrationWithWeakPassword() {
// Given: User is on registration screen
let signUpButton = app.buttons["Sign Up"]
signUpButton.tap()
// When: User enters weak password
let timestamp = Int(Date().timeIntervalSince1970)
let usernameField = app.textFields["Username"]
let emailField = app.textFields["Email"]
let passwordField = app.secureTextFields["Password"]
let registerButton = app.buttons["Register"]
usernameField.tap()
usernameField.typeText("testuser\(timestamp)")
emailField.tap()
emailField.typeText("test\(timestamp)@test.com")
passwordField.tap()
passwordField.typeText("weak")
registerButton.tap()
// Then: Password validation error should be shown
let errorMessage = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'password' AND (label CONTAINS[c] 'strong' OR label CONTAINS[c] 'at least')"))
XCTAssertTrue(errorMessage.firstMatch.waitForExistence(timeout: 3), "Should show password strength error")
}
// MARK: - Logout Tests
func testLogoutFlow() {
// Given: User is logged in
login(username: "testuser", password: "TestPass123!")
let residencesTab = app.tabBars.buttons["Residences"]
XCTAssertTrue(residencesTab.waitForExistence(timeout: 10))
// When: User logs out
logout()
// Then: User should be returned to login screen
XCTAssertTrue(app.staticTexts["MyCrib"].waitForExistence(timeout: 5), "Should return to login screen")
XCTAssertTrue(app.buttons["Login"].exists, "Login button should be visible")
}
func testLogoutClearsUserData() {
// Given: User is logged in and has viewed some data
login(username: "testuser", password: "TestPass123!")
let residencesTab = app.tabBars.buttons["Residences"]
XCTAssertTrue(residencesTab.waitForExistence(timeout: 10))
navigateToTab("Residences")
wait(seconds: 2) // Wait for data to load
// When: User logs out
logout()
// And: User logs back in
login(username: "testuser", password: "TestPass123!")
// Then: Fresh data should be loaded (not cached)
let loadingIndicator = app.activityIndicators.firstMatch
XCTAssertTrue(loadingIndicator.exists || app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'Loading'")).firstMatch.exists,
"Should show loading state for fresh data")
}
// MARK: - Session Management Tests
func testSessionPersistence() {
// Given: User logs in
login(username: "testuser", password: "TestPass123!")
let residencesTab = app.tabBars.buttons["Residences"]
XCTAssertTrue(residencesTab.waitForExistence(timeout: 10))
// When: App is terminated and relaunched
app.terminate()
app.launch()
// Then: User should still be logged in
XCTAssertTrue(residencesTab.waitForExistence(timeout: 5), "User session should persist")
}
func testLoginRedirectsVerifiedUser() {
// Given: Verified user logs in
login(username: "verifieduser", password: "TestPass123!")
// Then: User should go directly to main screen (not verification)
let residencesTab = app.tabBars.buttons["Residences"]
XCTAssertTrue(residencesTab.waitForExistence(timeout: 10), "Verified user should skip verification")
}
func testLoginRedirectsUnverifiedUser() {
// Given: Unverified user logs in
login(username: "unverifieduser", password: "TestPass123!")
// Then: User should be shown verification screen
let verificationTitle = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'Verify'"))
XCTAssertTrue(verificationTitle.firstMatch.waitForExistence(timeout: 10), "Unverified user should see verification screen")
}
// MARK: - Error Handling Tests
func testLoginWithNetworkError() {
// Note: This test requires network simulation or mocking
// For now, it's a placeholder for future implementation
// Given: Network is unavailable
// When: User attempts to login
// Then: Network error should be displayed
}
func testLoginRetryAfterError() {
// Given: User encountered a login error
login(username: "invaliduser", password: "WrongPassword!")
let errorMessage = app.staticTexts.containing(NSPredicate(format: "label CONTAINS[c] 'Invalid'"))
XCTAssertTrue(errorMessage.firstMatch.waitForExistence(timeout: 5))
// When: User enters correct credentials
let usernameField = app.textFields["Username"]
let passwordField = app.secureTextFields["Password"]
let loginButton = app.buttons["Login"]
app.clearText(in: usernameField)
usernameField.typeText("testuser")
app.clearText(in: passwordField)
passwordField.typeText("TestPass123!")
loginButton.tap()
// Then: Login should succeed
let residencesTab = app.tabBars.buttons["Residences"]
XCTAssertTrue(residencesTab.waitForExistence(timeout: 10), "Should login successfully after retry")
}
}