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

181 lines
5.7 KiB
Swift

import XCTest
/// Helper extensions and utilities for UI tests
extension XCUIApplication {
/// Launch the app and reset to initial state
func launchAndReset() {
launchArguments = ["--uitesting"]
launch()
}
/// Clear all text from a text field
func clearText(in textField: XCUIElement) {
textField.tap()
textField.press(forDuration: 1.2)
menuItems["Select All"].tap()
textField.typeText(XCUIKeyboardKey.delete.rawValue)
}
}
/// Base test class with common setup and teardown
class BaseUITest: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launchAndReset()
}
override func tearDown() {
app = nil
super.tearDown()
}
// MARK: - Authentication Helpers
func login(username: String, password: String) {
let usernameField = app.textFields["Username"]
let passwordField = app.secureTextFields["Password"]
let loginButton = app.buttons["Login"]
if usernameField.exists {
usernameField.tap()
usernameField.typeText(username)
}
if passwordField.exists {
passwordField.tap()
passwordField.typeText(password)
}
if loginButton.exists {
loginButton.tap()
}
}
func logout() {
let profileTab = app.tabBars.buttons["Profile"]
profileTab.tap()
let logoutButton = app.buttons["Log Out"]
XCTAssertTrue(logoutButton.waitForExistence(timeout: 5))
logoutButton.tap()
}
func register(username: String, email: String, password: String, firstName: String = "", lastName: String = "") {
let signUpButton = app.buttons["Sign Up"]
XCTAssertTrue(signUpButton.waitForExistence(timeout: 3))
signUpButton.tap()
let usernameField = app.textFields["Username"]
let emailField = app.textFields["Email"]
let passwordField = app.secureTextFields["Password"]
let registerButton = app.buttons["Register"]
usernameField.tap()
usernameField.typeText(username)
emailField.tap()
emailField.typeText(email)
passwordField.tap()
passwordField.typeText(password)
if !firstName.isEmpty {
let firstNameField = app.textFields["First Name"]
firstNameField.tap()
firstNameField.typeText(firstName)
}
if !lastName.isEmpty {
let lastNameField = app.textFields["Last Name"]
lastNameField.tap()
lastNameField.typeText(lastName)
}
registerButton.tap()
}
// MARK: - Navigation Helpers
func navigateToTab(_ tabName: String) {
let tab = app.tabBars.buttons[tabName]
XCTAssertTrue(tab.waitForExistence(timeout: 3))
tab.tap()
}
func navigateBack() {
app.navigationBars.buttons.element(boundBy: 0).tap()
}
// MARK: - Assertion Helpers
func assertElementExists(_ identifier: String, timeout: TimeInterval = 5) {
let element = app.descendants(matching: .any).matching(identifier: identifier).firstMatch
XCTAssertTrue(element.waitForExistence(timeout: timeout), "Element '\(identifier)' does not exist")
}
func assertElementDoesNotExist(_ identifier: String, timeout: TimeInterval = 2) {
let element = app.descendants(matching: .any).matching(identifier: identifier).firstMatch
XCTAssertFalse(element.waitForExistence(timeout: timeout), "Element '\(identifier)' should not exist")
}
func assertNavigatedTo(title: String, timeout: TimeInterval = 5) {
let navigationBar = app.navigationBars[title]
XCTAssertTrue(navigationBar.waitForExistence(timeout: timeout), "Did not navigate to '\(title)'")
}
// MARK: - Wait Helpers
func wait(seconds: TimeInterval) {
Thread.sleep(forTimeInterval: seconds)
}
func waitForElementToAppear(_ element: XCUIElement, timeout: TimeInterval = 5) -> Bool {
return element.waitForExistence(timeout: timeout)
}
func waitForElementToDisappear(_ element: XCUIElement, timeout: TimeInterval = 5) -> Bool {
let predicate = NSPredicate(format: "exists == false")
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: element)
let result = XCTWaiter.wait(for: [expectation], timeout: timeout)
return result == .completed
}
}
/// Identifiers for UI elements (for better testability)
struct Identifiers {
struct Authentication {
static let usernameField = "UsernameField"
static let passwordField = "PasswordField"
static let loginButton = "LoginButton"
static let registerButton = "RegisterButton"
static let logoutButton = "LogoutButton"
}
struct Residence {
static let addButton = "AddResidenceButton"
static let editButton = "EditResidenceButton"
static let deleteButton = "DeleteResidenceButton"
static let nameField = "ResidenceNameField"
static let addressField = "ResidenceAddressField"
}
struct Task {
static let addButton = "AddTaskButton"
static let completeButton = "CompleteTaskButton"
static let editButton = "EditTaskButton"
static let titleField = "TaskTitleField"
static let descriptionField = "TaskDescriptionField"
}
struct MultiUser {
static let manageUsersButton = "ManageUsersButton"
static let generateCodeButton = "GenerateCodeButton"
static let joinButton = "JoinResidenceButton"
static let shareCodeField = "ShareCodeField"
}
}