Move DataLayer/FeatureCoverage into domain folders; delete dead duplicate
- DataLayerTests -> DataLayer/DataLayerUITests (cache/ETag/persistence domain) - FeatureCoverageTests -> CrossCutting/FeatureCoverageUITests (cross-cutting: profile/theme/notifications/completion/sharing UI) - Delete the dead HoneyDueUITests/AccessibilityIdentifiers.swift duplicate (the target compiles the app's Helpers/AccessibilityIdentifiers.swift; this copy was excluded and stale). Tests/ folder removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,284 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
|
|
||||||
/// Centralized accessibility identifiers for UI testing
|
|
||||||
/// These identifiers are used by XCUITests to locate and interact with UI elements
|
|
||||||
struct AccessibilityIdentifiers {
|
|
||||||
|
|
||||||
// MARK: - Authentication
|
|
||||||
struct Authentication {
|
|
||||||
static let usernameField = "Login.UsernameField"
|
|
||||||
static let passwordField = "Login.PasswordField"
|
|
||||||
static let loginButton = "Login.LoginButton"
|
|
||||||
static let signUpButton = "Login.SignUpButton"
|
|
||||||
static let forgotPasswordButton = "Login.ForgotPasswordButton"
|
|
||||||
static let passwordVisibilityToggle = "Login.PasswordVisibilityToggle"
|
|
||||||
static let appleSignInButton = "Login.AppleSignInButton"
|
|
||||||
static let googleSignInButton = "Login.GoogleSignInButton"
|
|
||||||
|
|
||||||
// Registration
|
|
||||||
static let registerUsernameField = "Register.UsernameField"
|
|
||||||
static let registerEmailField = "Register.EmailField"
|
|
||||||
static let registerPasswordField = "Register.PasswordField"
|
|
||||||
static let registerConfirmPasswordField = "Register.ConfirmPasswordField"
|
|
||||||
static let registerButton = "Register.RegisterButton"
|
|
||||||
static let registerCancelButton = "Register.CancelButton"
|
|
||||||
|
|
||||||
// Verification
|
|
||||||
static let verificationCodeField = "Verification.CodeField"
|
|
||||||
static let verifyButton = "Verification.VerifyButton"
|
|
||||||
static let resendCodeButton = "Verification.ResendButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Navigation
|
|
||||||
struct Navigation {
|
|
||||||
static let residencesTab = "TabBar.Residences"
|
|
||||||
static let tasksTab = "TabBar.Tasks"
|
|
||||||
static let contractorsTab = "TabBar.Contractors"
|
|
||||||
static let documentsTab = "TabBar.Documents"
|
|
||||||
static let profileTab = "TabBar.Profile"
|
|
||||||
static let settingsButton = "Navigation.SettingsButton"
|
|
||||||
static let backButton = "Navigation.BackButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Residence
|
|
||||||
struct Residence {
|
|
||||||
// List
|
|
||||||
static let addButton = "Residence.AddButton"
|
|
||||||
static let residencesList = "Residence.List"
|
|
||||||
static let residenceCard = "Residence.Card"
|
|
||||||
static let emptyStateView = "Residence.EmptyState"
|
|
||||||
static let emptyStateButton = "Residence.EmptyState.AddButton"
|
|
||||||
|
|
||||||
// Form
|
|
||||||
static let nameField = "ResidenceForm.NameField"
|
|
||||||
static let propertyTypePicker = "ResidenceForm.PropertyTypePicker"
|
|
||||||
static let streetAddressField = "ResidenceForm.StreetAddressField"
|
|
||||||
static let apartmentUnitField = "ResidenceForm.ApartmentUnitField"
|
|
||||||
static let cityField = "ResidenceForm.CityField"
|
|
||||||
static let stateProvinceField = "ResidenceForm.StateProvinceField"
|
|
||||||
static let postalCodeField = "ResidenceForm.PostalCodeField"
|
|
||||||
static let countryField = "ResidenceForm.CountryField"
|
|
||||||
static let bedroomsField = "ResidenceForm.BedroomsField"
|
|
||||||
static let bathroomsField = "ResidenceForm.BathroomsField"
|
|
||||||
static let squareFootageField = "ResidenceForm.SquareFootageField"
|
|
||||||
static let lotSizeField = "ResidenceForm.LotSizeField"
|
|
||||||
static let yearBuiltField = "ResidenceForm.YearBuiltField"
|
|
||||||
static let descriptionField = "ResidenceForm.DescriptionField"
|
|
||||||
static let isPrimaryToggle = "ResidenceForm.IsPrimaryToggle"
|
|
||||||
static let saveButton = "ResidenceForm.SaveButton"
|
|
||||||
static let formCancelButton = "ResidenceForm.CancelButton"
|
|
||||||
|
|
||||||
// Detail
|
|
||||||
static let detailView = "ResidenceDetail.View"
|
|
||||||
static let editButton = "ResidenceDetail.EditButton"
|
|
||||||
static let deleteButton = "ResidenceDetail.DeleteButton"
|
|
||||||
static let shareButton = "ResidenceDetail.ShareButton"
|
|
||||||
static let manageUsersButton = "ResidenceDetail.ManageUsersButton"
|
|
||||||
static let tasksSection = "ResidenceDetail.TasksSection"
|
|
||||||
static let addTaskButton = "ResidenceDetail.AddTaskButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Task
|
|
||||||
struct Task {
|
|
||||||
// List/Kanban
|
|
||||||
static let addButton = "Task.AddButton"
|
|
||||||
static let refreshButton = "Task.RefreshButton"
|
|
||||||
static let tasksList = "Task.List"
|
|
||||||
static let taskCard = "Task.Card"
|
|
||||||
static let emptyStateView = "Task.EmptyState"
|
|
||||||
static let kanbanView = "Task.KanbanView"
|
|
||||||
static let overdueColumn = "Task.Column.Overdue"
|
|
||||||
static let upcomingColumn = "Task.Column.Upcoming"
|
|
||||||
static let inProgressColumn = "Task.Column.InProgress"
|
|
||||||
static let completedColumn = "Task.Column.Completed"
|
|
||||||
|
|
||||||
// Form
|
|
||||||
static let titleField = "TaskForm.TitleField"
|
|
||||||
static let descriptionField = "TaskForm.DescriptionField"
|
|
||||||
static let categoryPicker = "TaskForm.CategoryPicker"
|
|
||||||
static let frequencyPicker = "TaskForm.FrequencyPicker"
|
|
||||||
static let priorityPicker = "TaskForm.PriorityPicker"
|
|
||||||
static let statusPicker = "TaskForm.StatusPicker"
|
|
||||||
static let dueDatePicker = "TaskForm.DueDatePicker"
|
|
||||||
static let intervalDaysField = "TaskForm.IntervalDaysField"
|
|
||||||
static let estimatedCostField = "TaskForm.EstimatedCostField"
|
|
||||||
static let residencePicker = "TaskForm.ResidencePicker"
|
|
||||||
static let saveButton = "TaskForm.SaveButton"
|
|
||||||
static let formCancelButton = "TaskForm.CancelButton"
|
|
||||||
|
|
||||||
// Detail
|
|
||||||
static let detailView = "TaskDetail.View"
|
|
||||||
static let editButton = "TaskDetail.EditButton"
|
|
||||||
static let deleteButton = "TaskDetail.DeleteButton"
|
|
||||||
static let markInProgressButton = "TaskDetail.MarkInProgressButton"
|
|
||||||
static let completeButton = "TaskDetail.CompleteButton"
|
|
||||||
static let detailCancelButton = "TaskDetail.CancelButton"
|
|
||||||
|
|
||||||
// Completion
|
|
||||||
static let completionDatePicker = "TaskCompletion.CompletionDatePicker"
|
|
||||||
static let actualCostField = "TaskCompletion.ActualCostField"
|
|
||||||
static let ratingView = "TaskCompletion.RatingView"
|
|
||||||
static let notesField = "TaskCompletion.NotesField"
|
|
||||||
static let photosPicker = "TaskCompletion.PhotosPicker"
|
|
||||||
static let submitButton = "TaskCompletion.SubmitButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Contractor
|
|
||||||
struct Contractor {
|
|
||||||
static let addButton = "Contractor.AddButton"
|
|
||||||
static let contractorsList = "Contractor.List"
|
|
||||||
static let contractorCard = "Contractor.Card"
|
|
||||||
static let emptyStateView = "Contractor.EmptyState"
|
|
||||||
|
|
||||||
// Form
|
|
||||||
static let nameField = "ContractorForm.NameField"
|
|
||||||
static let companyField = "ContractorForm.CompanyField"
|
|
||||||
static let emailField = "ContractorForm.EmailField"
|
|
||||||
static let phoneField = "ContractorForm.PhoneField"
|
|
||||||
static let specialtyPicker = "ContractorForm.SpecialtyPicker"
|
|
||||||
static let ratingView = "ContractorForm.RatingView"
|
|
||||||
static let notesField = "ContractorForm.NotesField"
|
|
||||||
static let saveButton = "ContractorForm.SaveButton"
|
|
||||||
static let formCancelButton = "ContractorForm.CancelButton"
|
|
||||||
|
|
||||||
// Detail
|
|
||||||
static let detailView = "ContractorDetail.View"
|
|
||||||
static let menuButton = "ContractorDetail.MenuButton"
|
|
||||||
static let editButton = "ContractorDetail.EditButton"
|
|
||||||
static let deleteButton = "ContractorDetail.DeleteButton"
|
|
||||||
static let callButton = "ContractorDetail.CallButton"
|
|
||||||
static let emailButton = "ContractorDetail.EmailButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Document
|
|
||||||
struct Document {
|
|
||||||
static let addButton = "Document.AddButton"
|
|
||||||
static let documentsList = "Document.List"
|
|
||||||
static let documentCard = "Document.Card"
|
|
||||||
static let emptyStateView = "Document.EmptyState"
|
|
||||||
|
|
||||||
// Form
|
|
||||||
static let titleField = "DocumentForm.TitleField"
|
|
||||||
static let typePicker = "DocumentForm.TypePicker"
|
|
||||||
static let categoryPicker = "DocumentForm.CategoryPicker"
|
|
||||||
static let residencePicker = "DocumentForm.ResidencePicker"
|
|
||||||
static let filePicker = "DocumentForm.FilePicker"
|
|
||||||
static let notesField = "DocumentForm.NotesField"
|
|
||||||
static let expirationDatePicker = "DocumentForm.ExpirationDatePicker"
|
|
||||||
static let itemNameField = "DocumentForm.ItemNameField"
|
|
||||||
static let modelNumberField = "DocumentForm.ModelNumberField"
|
|
||||||
static let serialNumberField = "DocumentForm.SerialNumberField"
|
|
||||||
static let providerField = "DocumentForm.ProviderField"
|
|
||||||
static let providerContactField = "DocumentForm.ProviderContactField"
|
|
||||||
static let tagsField = "DocumentForm.TagsField"
|
|
||||||
static let locationField = "DocumentForm.LocationField"
|
|
||||||
static let saveButton = "DocumentForm.SaveButton"
|
|
||||||
static let formCancelButton = "DocumentForm.CancelButton"
|
|
||||||
|
|
||||||
// Detail
|
|
||||||
static let detailView = "DocumentDetail.View"
|
|
||||||
static let menuButton = "DocumentDetail.MenuButton"
|
|
||||||
static let editButton = "DocumentDetail.EditButton"
|
|
||||||
static let deleteButton = "DocumentDetail.DeleteButton"
|
|
||||||
static let shareButton = "DocumentDetail.ShareButton"
|
|
||||||
static let downloadButton = "DocumentDetail.DownloadButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Onboarding
|
|
||||||
struct Onboarding {
|
|
||||||
// Welcome Screen
|
|
||||||
static let welcomeTitle = "Onboarding.WelcomeTitle"
|
|
||||||
static let startFreshButton = "Onboarding.StartFreshButton"
|
|
||||||
static let joinExistingButton = "Onboarding.JoinExistingButton"
|
|
||||||
static let loginButton = "Onboarding.LoginButton"
|
|
||||||
|
|
||||||
// Value Props Screen
|
|
||||||
static let valuePropsTitle = "Onboarding.ValuePropsTitle"
|
|
||||||
static let valuePropsNextButton = "Onboarding.ValuePropsNextButton"
|
|
||||||
|
|
||||||
// Name Residence Screen
|
|
||||||
static let nameResidenceTitle = "Onboarding.NameResidenceTitle"
|
|
||||||
static let residenceNameField = "Onboarding.ResidenceNameField"
|
|
||||||
static let nameResidenceContinueButton = "Onboarding.NameResidenceContinueButton"
|
|
||||||
|
|
||||||
// Create Account Screen
|
|
||||||
static let createAccountTitle = "Onboarding.CreateAccountTitle"
|
|
||||||
static let appleSignInButton = "Onboarding.AppleSignInButton"
|
|
||||||
static let emailSignUpExpandButton = "Onboarding.EmailSignUpExpandButton"
|
|
||||||
static let usernameField = "Onboarding.UsernameField"
|
|
||||||
static let emailField = "Onboarding.EmailField"
|
|
||||||
static let passwordField = "Onboarding.PasswordField"
|
|
||||||
static let confirmPasswordField = "Onboarding.ConfirmPasswordField"
|
|
||||||
static let createAccountButton = "Onboarding.CreateAccountButton"
|
|
||||||
static let loginLinkButton = "Onboarding.LoginLinkButton"
|
|
||||||
|
|
||||||
// Verify Email Screen
|
|
||||||
static let verifyEmailTitle = "Onboarding.VerifyEmailTitle"
|
|
||||||
static let verificationCodeField = "Onboarding.VerificationCodeField"
|
|
||||||
static let verifyButton = "Onboarding.VerifyButton"
|
|
||||||
|
|
||||||
// Join Residence Screen
|
|
||||||
static let joinResidenceTitle = "Onboarding.JoinResidenceTitle"
|
|
||||||
static let shareCodeField = "Onboarding.ShareCodeField"
|
|
||||||
static let joinResidenceButton = "Onboarding.JoinResidenceButton"
|
|
||||||
|
|
||||||
// First Task Screen
|
|
||||||
static let firstTaskTitle = "Onboarding.FirstTaskTitle"
|
|
||||||
static let taskSelectionCounter = "Onboarding.TaskSelectionCounter"
|
|
||||||
static let addPopularTasksButton = "Onboarding.AddPopularTasksButton"
|
|
||||||
static let addTasksContinueButton = "Onboarding.AddTasksContinueButton"
|
|
||||||
static let taskCategorySection = "Onboarding.TaskCategorySection"
|
|
||||||
static let taskTemplateRow = "Onboarding.TaskTemplateRow"
|
|
||||||
|
|
||||||
// Subscription Screen
|
|
||||||
static let subscriptionTitle = "Onboarding.SubscriptionTitle"
|
|
||||||
static let yearlyPlanCard = "Onboarding.YearlyPlanCard"
|
|
||||||
static let monthlyPlanCard = "Onboarding.MonthlyPlanCard"
|
|
||||||
static let startTrialButton = "Onboarding.StartTrialButton"
|
|
||||||
static let continueWithFreeButton = "Onboarding.ContinueWithFreeButton"
|
|
||||||
|
|
||||||
// Navigation
|
|
||||||
static let backButton = "Onboarding.BackButton"
|
|
||||||
static let skipButton = "Onboarding.SkipButton"
|
|
||||||
static let progressIndicator = "Onboarding.ProgressIndicator"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Profile
|
|
||||||
struct Profile {
|
|
||||||
static let logoutButton = "Profile.LogoutButton"
|
|
||||||
static let editProfileButton = "Profile.EditProfileButton"
|
|
||||||
static let settingsButton = "Profile.SettingsButton"
|
|
||||||
static let notificationsToggle = "Profile.NotificationsToggle"
|
|
||||||
static let darkModeToggle = "Profile.DarkModeToggle"
|
|
||||||
static let aboutButton = "Profile.AboutButton"
|
|
||||||
static let helpButton = "Profile.HelpButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Alerts & Modals
|
|
||||||
struct Alert {
|
|
||||||
static let confirmButton = "Alert.ConfirmButton"
|
|
||||||
static let cancelButton = "Alert.CancelButton"
|
|
||||||
static let deleteButton = "Alert.DeleteButton"
|
|
||||||
static let okButton = "Alert.OKButton"
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Common
|
|
||||||
struct Common {
|
|
||||||
static let loadingIndicator = "Common.LoadingIndicator"
|
|
||||||
static let errorView = "Common.ErrorView"
|
|
||||||
static let retryButton = "Common.RetryButton"
|
|
||||||
static let searchField = "Common.SearchField"
|
|
||||||
static let filterButton = "Common.FilterButton"
|
|
||||||
static let sortButton = "Common.SortButton"
|
|
||||||
static let refreshControl = "Common.RefreshControl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Helper Extension
|
|
||||||
extension String {
|
|
||||||
/// Convenience method to generate dynamic identifiers
|
|
||||||
/// Example: "Residence.Card.\(residenceId)"
|
|
||||||
func withId(_ id: Any) -> String {
|
|
||||||
return "\(self).\(id)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -3,7 +3,7 @@ import XCTest
|
|||||||
/// Tests for previously uncovered features: task completion, profile edit,
|
/// Tests for previously uncovered features: task completion, profile edit,
|
||||||
/// manage users, join residence, task templates, notification preferences,
|
/// manage users, join residence, task templates, notification preferences,
|
||||||
/// and theme selection.
|
/// and theme selection.
|
||||||
final class FeatureCoverageTests: AuthenticatedUITestCase {
|
final class FeatureCoverageUITests: AuthenticatedUITestCase {
|
||||||
override var needsAPISession: Bool { true }
|
override var needsAPISession: Bool { true }
|
||||||
override var testCredentials: (username: String, password: String) { ("admin", "Test1234") }
|
override var testCredentials: (username: String, password: String) { ("admin", "Test1234") }
|
||||||
override var apiCredentials: (username: String, password: String) { ("admin", "Test1234") }
|
override var apiCredentials: (username: String, password: String) { ("admin", "Test1234") }
|
||||||
+1
-1
@@ -8,7 +8,7 @@ private enum DataLayerTestError: Error {
|
|||||||
///
|
///
|
||||||
/// Test Plan IDs: DATA-001 through DATA-007.
|
/// Test Plan IDs: DATA-001 through DATA-007.
|
||||||
/// All tests run against the real local backend via `AuthenticatedUITestCase` with UI-driven login.
|
/// All tests run against the real local backend via `AuthenticatedUITestCase` with UI-driven login.
|
||||||
final class DataLayerTests: AuthenticatedUITestCase {
|
final class DataLayerUITests: AuthenticatedUITestCase {
|
||||||
// This suite logs out and re-logs in as the SAME user mid-test to verify
|
// This suite logs out and re-logs in as the SAME user mid-test to verify
|
||||||
// cache/persistence behavior, which is incompatible with per-test fresh
|
// cache/persistence behavior, which is incompatible with per-test fresh
|
||||||
// accounts (each login would be a different account). Opt out of isolation
|
// accounts (each login would be a different account). Opt out of isolation
|
||||||
Reference in New Issue
Block a user