import XCTest /// Page object for the login screen. /// /// Uses accessibility identifiers from `AccessibilityIdentifiers.Authentication` /// to locate elements. Provides typed actions for login flow interactions. class LoginScreen: BaseScreen { // MARK: - Elements var emailField: XCUIElement { app.textFields[AccessibilityIdentifiers.Authentication.usernameField] } var passwordField: XCUIElement { // Password field may be a SecureTextField or regular TextField depending on visibility toggle let secure = app.secureTextFields[AccessibilityIdentifiers.Authentication.passwordField] if secure.exists { return secure } return app.textFields[AccessibilityIdentifiers.Authentication.passwordField] } var loginButton: XCUIElement { app.buttons[AccessibilityIdentifiers.Authentication.loginButton] } var appleSignInButton: XCUIElement { app.buttons[AccessibilityIdentifiers.Authentication.appleSignInButton] } var signUpButton: XCUIElement { app.buttons[AccessibilityIdentifiers.Authentication.signUpButton] } var forgotPasswordButton: XCUIElement { app.buttons[AccessibilityIdentifiers.Authentication.forgotPasswordButton] } var passwordVisibilityToggle: XCUIElement { app.buttons[AccessibilityIdentifiers.Authentication.passwordVisibilityToggle] } var welcomeText: XCUIElement { app.staticTexts["Welcome Back"] } override var isDisplayed: Bool { emailField.waitForExistence(timeout: timeout) } // MARK: - Actions /// Logs in with the provided credentials and returns a MainTabScreen. /// Waits for the email field to appear before typing. @discardableResult func login(email: String, password: String) -> MainTabScreen { waitForElement(emailField).tap() emailField.typeText(email) let pwField = passwordField pwField.tap() pwField.typeText(password) loginButton.tap() return MainTabScreen(app: app) } /// Taps the sign up / register link and returns a RegisterScreen. @discardableResult func tapSignUp() -> RegisterScreen { waitForElement(signUpButton).tap() return RegisterScreen(app: app) } /// Taps the forgot password link. func tapForgotPassword() { waitForElement(forgotPasswordButton).tap() } /// Toggles password visibility and returns whether the password is now visible. @discardableResult func togglePasswordVisibility() -> Bool { waitForElement(passwordVisibilityToggle).tap() // If a regular text field with the password identifier exists, password is visible return app.textFields[AccessibilityIdentifiers.Authentication.passwordField].exists } }