Test infra: shared accessibility IDs + PageObjects + AAA_SeedTests
Ports iOS HoneyDueUITests AccessibilityIdentifiers + PageObjects pattern to Android Compose UI Test. Kotlin AccessibilityIds object mirrors Swift verbatim so scripts/verify_test_tag_parity.sh can gate on divergence. AAA_SeedTests bracketed first alphanumerically; SuiteZZ cleanup to follow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
package com.tt.honeyDue.testing
|
||||
|
||||
/**
|
||||
* Centralized accessibility identifiers for UI testing.
|
||||
*
|
||||
* 1:1 port of iOS `AccessibilityIdentifiers.swift` — string values MUST
|
||||
* remain verbatim matches so `scripts/verify_test_tag_parity.sh` can gate
|
||||
* cross-platform divergence. Production screens reference these via
|
||||
* `Modifier.testTag(AccessibilityIds.Authentication.usernameField)` so the
|
||||
* same test harness works identically across iOS and Android.
|
||||
*/
|
||||
object AccessibilityIds {
|
||||
|
||||
// MARK: - Authentication
|
||||
object Authentication {
|
||||
const val usernameField = "Login.UsernameField"
|
||||
const val passwordField = "Login.PasswordField"
|
||||
const val loginButton = "Login.LoginButton"
|
||||
const val signUpButton = "Login.SignUpButton"
|
||||
const val forgotPasswordButton = "Login.ForgotPasswordButton"
|
||||
const val passwordVisibilityToggle = "Login.PasswordVisibilityToggle"
|
||||
const val appleSignInButton = "Login.AppleSignInButton"
|
||||
const val googleSignInButton = "Login.GoogleSignInButton"
|
||||
|
||||
// Registration
|
||||
const val registerUsernameField = "Register.UsernameField"
|
||||
const val registerEmailField = "Register.EmailField"
|
||||
const val registerPasswordField = "Register.PasswordField"
|
||||
const val registerConfirmPasswordField = "Register.ConfirmPasswordField"
|
||||
const val registerButton = "Register.RegisterButton"
|
||||
const val registerCancelButton = "Register.CancelButton"
|
||||
|
||||
// Verification
|
||||
const val verificationCodeField = "Verification.CodeField"
|
||||
const val verifyButton = "Verification.VerifyButton"
|
||||
const val resendCodeButton = "Verification.ResendButton"
|
||||
}
|
||||
|
||||
// MARK: - Navigation
|
||||
object Navigation {
|
||||
const val residencesTab = "TabBar.Residences"
|
||||
const val tasksTab = "TabBar.Tasks"
|
||||
const val contractorsTab = "TabBar.Contractors"
|
||||
const val documentsTab = "TabBar.Documents"
|
||||
const val profileTab = "TabBar.Profile"
|
||||
const val settingsButton = "Navigation.SettingsButton"
|
||||
const val backButton = "Navigation.BackButton"
|
||||
}
|
||||
|
||||
// MARK: - Residence
|
||||
object Residence {
|
||||
// List
|
||||
const val addButton = "Residence.AddButton"
|
||||
const val residencesList = "Residence.List"
|
||||
const val residenceCard = "Residence.Card"
|
||||
const val emptyStateView = "Residence.EmptyState"
|
||||
const val emptyStateButton = "Residence.EmptyState.AddButton"
|
||||
|
||||
// Form
|
||||
const val nameField = "ResidenceForm.NameField"
|
||||
const val propertyTypePicker = "ResidenceForm.PropertyTypePicker"
|
||||
const val streetAddressField = "ResidenceForm.StreetAddressField"
|
||||
const val apartmentUnitField = "ResidenceForm.ApartmentUnitField"
|
||||
const val cityField = "ResidenceForm.CityField"
|
||||
const val stateProvinceField = "ResidenceForm.StateProvinceField"
|
||||
const val postalCodeField = "ResidenceForm.PostalCodeField"
|
||||
const val countryField = "ResidenceForm.CountryField"
|
||||
const val bedroomsField = "ResidenceForm.BedroomsField"
|
||||
const val bathroomsField = "ResidenceForm.BathroomsField"
|
||||
const val squareFootageField = "ResidenceForm.SquareFootageField"
|
||||
const val lotSizeField = "ResidenceForm.LotSizeField"
|
||||
const val yearBuiltField = "ResidenceForm.YearBuiltField"
|
||||
const val descriptionField = "ResidenceForm.DescriptionField"
|
||||
const val isPrimaryToggle = "ResidenceForm.IsPrimaryToggle"
|
||||
const val saveButton = "ResidenceForm.SaveButton"
|
||||
const val formCancelButton = "ResidenceForm.CancelButton"
|
||||
|
||||
// Detail
|
||||
const val detailView = "ResidenceDetail.View"
|
||||
const val editButton = "ResidenceDetail.EditButton"
|
||||
const val deleteButton = "ResidenceDetail.DeleteButton"
|
||||
const val shareButton = "ResidenceDetail.ShareButton"
|
||||
const val manageUsersButton = "ResidenceDetail.ManageUsersButton"
|
||||
const val tasksSection = "ResidenceDetail.TasksSection"
|
||||
const val addTaskButton = "ResidenceDetail.AddTaskButton"
|
||||
}
|
||||
|
||||
// MARK: - Task
|
||||
object Task {
|
||||
// List/Kanban
|
||||
const val addButton = "Task.AddButton"
|
||||
const val refreshButton = "Task.RefreshButton"
|
||||
const val tasksList = "Task.List"
|
||||
const val taskCard = "Task.Card"
|
||||
const val emptyStateView = "Task.EmptyState"
|
||||
const val kanbanView = "Task.KanbanView"
|
||||
const val overdueColumn = "Task.Column.Overdue"
|
||||
const val upcomingColumn = "Task.Column.Upcoming"
|
||||
const val inProgressColumn = "Task.Column.InProgress"
|
||||
const val completedColumn = "Task.Column.Completed"
|
||||
|
||||
// Form
|
||||
const val titleField = "TaskForm.TitleField"
|
||||
const val descriptionField = "TaskForm.DescriptionField"
|
||||
const val categoryPicker = "TaskForm.CategoryPicker"
|
||||
const val frequencyPicker = "TaskForm.FrequencyPicker"
|
||||
const val priorityPicker = "TaskForm.PriorityPicker"
|
||||
const val statusPicker = "TaskForm.StatusPicker"
|
||||
const val dueDatePicker = "TaskForm.DueDatePicker"
|
||||
const val intervalDaysField = "TaskForm.IntervalDaysField"
|
||||
const val estimatedCostField = "TaskForm.EstimatedCostField"
|
||||
const val residencePicker = "TaskForm.ResidencePicker"
|
||||
const val saveButton = "TaskForm.SaveButton"
|
||||
const val formCancelButton = "TaskForm.CancelButton"
|
||||
|
||||
// Detail
|
||||
const val detailView = "TaskDetail.View"
|
||||
const val editButton = "TaskDetail.EditButton"
|
||||
const val deleteButton = "TaskDetail.DeleteButton"
|
||||
const val markInProgressButton = "TaskDetail.MarkInProgressButton"
|
||||
const val completeButton = "TaskDetail.CompleteButton"
|
||||
const val detailCancelButton = "TaskDetail.CancelButton"
|
||||
|
||||
// Completion
|
||||
const val completionDatePicker = "TaskCompletion.CompletionDatePicker"
|
||||
const val actualCostField = "TaskCompletion.ActualCostField"
|
||||
const val ratingView = "TaskCompletion.RatingView"
|
||||
const val notesField = "TaskCompletion.NotesField"
|
||||
const val photosPicker = "TaskCompletion.PhotosPicker"
|
||||
const val submitButton = "TaskCompletion.SubmitButton"
|
||||
}
|
||||
|
||||
// MARK: - Contractor
|
||||
object Contractor {
|
||||
const val addButton = "Contractor.AddButton"
|
||||
const val contractorsList = "Contractor.List"
|
||||
const val contractorCard = "Contractor.Card"
|
||||
const val emptyStateView = "Contractor.EmptyState"
|
||||
|
||||
// Form
|
||||
const val nameField = "ContractorForm.NameField"
|
||||
const val companyField = "ContractorForm.CompanyField"
|
||||
const val emailField = "ContractorForm.EmailField"
|
||||
const val phoneField = "ContractorForm.PhoneField"
|
||||
const val specialtyPicker = "ContractorForm.SpecialtyPicker"
|
||||
const val ratingView = "ContractorForm.RatingView"
|
||||
const val notesField = "ContractorForm.NotesField"
|
||||
const val saveButton = "ContractorForm.SaveButton"
|
||||
const val formCancelButton = "ContractorForm.CancelButton"
|
||||
|
||||
// Detail
|
||||
const val detailView = "ContractorDetail.View"
|
||||
const val menuButton = "ContractorDetail.MenuButton"
|
||||
const val editButton = "ContractorDetail.EditButton"
|
||||
const val deleteButton = "ContractorDetail.DeleteButton"
|
||||
const val callButton = "ContractorDetail.CallButton"
|
||||
const val emailButton = "ContractorDetail.EmailButton"
|
||||
}
|
||||
|
||||
// MARK: - Document
|
||||
object Document {
|
||||
const val addButton = "Document.AddButton"
|
||||
const val documentsList = "Document.List"
|
||||
const val documentCard = "Document.Card"
|
||||
const val emptyStateView = "Document.EmptyState"
|
||||
|
||||
// Form
|
||||
const val titleField = "DocumentForm.TitleField"
|
||||
const val typePicker = "DocumentForm.TypePicker"
|
||||
const val categoryPicker = "DocumentForm.CategoryPicker"
|
||||
const val residencePicker = "DocumentForm.ResidencePicker"
|
||||
const val filePicker = "DocumentForm.FilePicker"
|
||||
const val notesField = "DocumentForm.NotesField"
|
||||
const val expirationDatePicker = "DocumentForm.ExpirationDatePicker"
|
||||
const val itemNameField = "DocumentForm.ItemNameField"
|
||||
const val modelNumberField = "DocumentForm.ModelNumberField"
|
||||
const val serialNumberField = "DocumentForm.SerialNumberField"
|
||||
const val providerField = "DocumentForm.ProviderField"
|
||||
const val providerContactField = "DocumentForm.ProviderContactField"
|
||||
const val tagsField = "DocumentForm.TagsField"
|
||||
const val locationField = "DocumentForm.LocationField"
|
||||
const val saveButton = "DocumentForm.SaveButton"
|
||||
const val formCancelButton = "DocumentForm.CancelButton"
|
||||
|
||||
// Detail
|
||||
const val detailView = "DocumentDetail.View"
|
||||
const val menuButton = "DocumentDetail.MenuButton"
|
||||
const val editButton = "DocumentDetail.EditButton"
|
||||
const val deleteButton = "DocumentDetail.DeleteButton"
|
||||
const val shareButton = "DocumentDetail.ShareButton"
|
||||
const val downloadButton = "DocumentDetail.DownloadButton"
|
||||
}
|
||||
|
||||
// MARK: - Onboarding
|
||||
object Onboarding {
|
||||
// Welcome Screen
|
||||
const val welcomeTitle = "Onboarding.WelcomeTitle"
|
||||
const val startFreshButton = "Onboarding.StartFreshButton"
|
||||
const val joinExistingButton = "Onboarding.JoinExistingButton"
|
||||
const val loginButton = "Onboarding.LoginButton"
|
||||
|
||||
// Value Props Screen
|
||||
const val valuePropsTitle = "Onboarding.ValuePropsTitle"
|
||||
const val valuePropsNextButton = "Onboarding.ValuePropsNextButton"
|
||||
|
||||
// Name Residence Screen
|
||||
const val nameResidenceTitle = "Onboarding.NameResidenceTitle"
|
||||
const val residenceNameField = "Onboarding.ResidenceNameField"
|
||||
const val nameResidenceContinueButton = "Onboarding.NameResidenceContinueButton"
|
||||
|
||||
// Create Account Screen
|
||||
const val createAccountTitle = "Onboarding.CreateAccountTitle"
|
||||
const val appleSignInButton = "Onboarding.AppleSignInButton"
|
||||
const val emailSignUpExpandButton = "Onboarding.EmailSignUpExpandButton"
|
||||
const val usernameField = "Onboarding.UsernameField"
|
||||
const val emailField = "Onboarding.EmailField"
|
||||
const val passwordField = "Onboarding.PasswordField"
|
||||
const val confirmPasswordField = "Onboarding.ConfirmPasswordField"
|
||||
const val createAccountButton = "Onboarding.CreateAccountButton"
|
||||
const val loginLinkButton = "Onboarding.LoginLinkButton"
|
||||
|
||||
// Verify Email Screen
|
||||
const val verifyEmailTitle = "Onboarding.VerifyEmailTitle"
|
||||
const val verificationCodeField = "Onboarding.VerificationCodeField"
|
||||
const val verifyButton = "Onboarding.VerifyButton"
|
||||
|
||||
// Join Residence Screen
|
||||
const val joinResidenceTitle = "Onboarding.JoinResidenceTitle"
|
||||
const val shareCodeField = "Onboarding.ShareCodeField"
|
||||
const val joinResidenceButton = "Onboarding.JoinResidenceButton"
|
||||
|
||||
// First Task Screen
|
||||
const val firstTaskTitle = "Onboarding.FirstTaskTitle"
|
||||
const val taskSelectionCounter = "Onboarding.TaskSelectionCounter"
|
||||
const val addPopularTasksButton = "Onboarding.AddPopularTasksButton"
|
||||
const val addTasksContinueButton = "Onboarding.AddTasksContinueButton"
|
||||
const val taskCategorySection = "Onboarding.TaskCategorySection"
|
||||
const val taskTemplateRow = "Onboarding.TaskTemplateRow"
|
||||
|
||||
// Subscription Screen
|
||||
const val subscriptionTitle = "Onboarding.SubscriptionTitle"
|
||||
const val yearlyPlanCard = "Onboarding.YearlyPlanCard"
|
||||
const val monthlyPlanCard = "Onboarding.MonthlyPlanCard"
|
||||
const val startTrialButton = "Onboarding.StartTrialButton"
|
||||
const val continueWithFreeButton = "Onboarding.ContinueWithFreeButton"
|
||||
|
||||
// Navigation
|
||||
const val backButton = "Onboarding.BackButton"
|
||||
const val skipButton = "Onboarding.SkipButton"
|
||||
const val progressIndicator = "Onboarding.ProgressIndicator"
|
||||
}
|
||||
|
||||
// MARK: - Profile
|
||||
object Profile {
|
||||
const val logoutButton = "Profile.LogoutButton"
|
||||
const val editProfileButton = "Profile.EditProfileButton"
|
||||
const val settingsButton = "Profile.SettingsButton"
|
||||
const val notificationsToggle = "Profile.NotificationsToggle"
|
||||
const val darkModeToggle = "Profile.DarkModeToggle"
|
||||
const val aboutButton = "Profile.AboutButton"
|
||||
const val helpButton = "Profile.HelpButton"
|
||||
}
|
||||
|
||||
// MARK: - Alerts & Modals
|
||||
object Alert {
|
||||
const val confirmButton = "Alert.ConfirmButton"
|
||||
const val cancelButton = "Alert.CancelButton"
|
||||
const val deleteButton = "Alert.DeleteButton"
|
||||
const val okButton = "Alert.OKButton"
|
||||
}
|
||||
|
||||
// MARK: - Common
|
||||
object Common {
|
||||
const val loadingIndicator = "Common.LoadingIndicator"
|
||||
const val errorView = "Common.ErrorView"
|
||||
const val retryButton = "Common.RetryButton"
|
||||
const val searchField = "Common.SearchField"
|
||||
const val filterButton = "Common.FilterButton"
|
||||
const val sortButton = "Common.SortButton"
|
||||
const val refreshControl = "Common.RefreshControl"
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience helper to generate dynamic identifiers.
|
||||
* Example: withId(Residence.residenceCard, residenceId) yields
|
||||
* Residence.Card.{residenceId}.
|
||||
*/
|
||||
fun withId(base: String, id: Any): String = "$base.$id"
|
||||
}
|
||||
Reference in New Issue
Block a user