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:
Trey T
2026-04-18 14:19:37 -05:00
parent 42c21bfca1
commit 2d80ade6bc
12 changed files with 1076 additions and 0 deletions
@@ -0,0 +1,60 @@
package com.tt.honeyDue.fixtures
import com.tt.honeyDue.models.ResidenceCreateRequest
import kotlin.random.Random
/**
* Test residence fixture mirroring `TestFixtures.TestResidence` in Swift.
* Produces the exact payload shape the Go API expects so seed tests can
* call `APILayer.createResidence(fixture.toCreateRequest())`.
*/
data class TestResidence(
val name: String,
val streetAddress: String,
val city: String,
val stateProvince: String,
val postalCode: String,
val country: String = "USA",
val bedrooms: Int? = null,
val bathrooms: Double? = null,
val isPrimary: Boolean = false,
) {
fun toCreateRequest(): ResidenceCreateRequest = ResidenceCreateRequest(
name = name,
streetAddress = streetAddress,
city = city,
stateProvince = stateProvince,
postalCode = postalCode,
country = country,
bedrooms = bedrooms,
bathrooms = bathrooms,
isPrimary = isPrimary,
)
companion object {
fun house(suffix: String = randomSuffix()): TestResidence = TestResidence(
name = "Test House $suffix",
streetAddress = "123 Test St",
city = "Testville",
stateProvince = "CA",
postalCode = "94000",
bedrooms = 3,
bathrooms = 2.0,
isPrimary = true,
)
fun apartment(suffix: String = randomSuffix()): TestResidence = TestResidence(
name = "Test Apt $suffix",
streetAddress = "456 Mock Ave",
city = "Testville",
stateProvince = "CA",
postalCode = "94001",
bedrooms = 1,
bathrooms = 1.0,
isPrimary = false,
)
private fun randomSuffix(): String =
Random.nextInt(1000, 9999).toString()
}
}
@@ -0,0 +1,51 @@
package com.tt.honeyDue.fixtures
import com.tt.honeyDue.models.TaskCreateRequest
import kotlin.random.Random
/**
* Test task fixture mirroring `TestFixtures.TestTask` in Swift.
*
* The Go API requires a residenceId and assigns category/priority IDs from
* DataManager lookups — callers pass the ID of a seeded test residence plus
* optional lookup IDs after a prefetch.
*/
data class TestTask(
val title: String,
val description: String,
val residenceId: Int,
val priorityId: Int? = null,
val categoryId: Int? = null,
val estimatedCost: Double? = null,
) {
fun toCreateRequest(): TaskCreateRequest = TaskCreateRequest(
residenceId = residenceId,
title = title,
description = description,
categoryId = categoryId,
priorityId = priorityId,
estimatedCost = estimatedCost,
)
companion object {
fun basic(residenceId: Int, suffix: String = randomSuffix()): TestTask = TestTask(
title = "Test Task $suffix",
description = "A test task",
residenceId = residenceId,
)
fun urgent(
residenceId: Int,
priorityId: Int? = null,
suffix: String = randomSuffix(),
): TestTask = TestTask(
title = "Urgent Task $suffix",
description = "An urgent task",
residenceId = residenceId,
priorityId = priorityId,
)
private fun randomSuffix(): String =
Random.nextInt(1000, 9999).toString()
}
}
@@ -0,0 +1,48 @@
package com.tt.honeyDue.fixtures
import kotlin.random.Random
/**
* Test user fixture mirroring `TestFixtures.TestUser` in Swift.
*
* `seededTestUser()` yields the known-good backend account that
* `AAA_SeedTests` ensures exists before the parallel suites run.
*/
data class TestUser(
val username: String,
val email: String,
val password: String,
val firstName: String = "Test",
val lastName: String = "User",
) {
companion object {
/** Pre-existing user seeded against the dev backend. */
fun seededTestUser(): TestUser = TestUser(
username = "testuser",
email = "testuser@honeydue.com",
password = "TestPass123!",
)
/** Admin account used by admin-gated flows. */
fun seededAdminUser(): TestUser = TestUser(
username = "admin",
email = "admin@honeydue.com",
password = "Test1234",
)
/**
* Unique, ephemeral user used for registration flows that cannot
* re-use an existing account. Cleaned up by `SuiteZZ_CleanupTests`.
*/
fun ephemeralUser(suffix: String = randomSuffix()): TestUser = TestUser(
username = "uitest_$suffix",
email = "uitest_$suffix@test.com",
password = "TestPassword123!",
firstName = "Test",
lastName = "User",
)
private fun randomSuffix(): String =
Random.nextInt(100_000, 999_999).toString()
}
}