Fix: expect/actual enableTestTagsAsResourceId() for iOS compile

testTagsAsResourceId is Android-only; its use in commonMain broke
compileKotlinIosSimulatorArm64. Wrap behind expect fun — Android impl
sets the semantic, other platforms return Modifier unchanged. Blocks
P3 iOS parity gallery otherwise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-04-18 19:20:48 -05:00
parent f56d854acc
commit c57743dca0
17 changed files with 66 additions and 35 deletions

View File

@@ -0,0 +1,9 @@
package com.tt.honeyDue.ui.support
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
actual fun Modifier.enableTestTagsAsResourceId(): Modifier =
this.semantics { testTagsAsResourceId = true }

View File

@@ -16,12 +16,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.ApiResultHandler
import com.tt.honeyDue.ui.components.HandleErrors
import com.tt.honeyDue.viewmodel.DocumentViewModel
@@ -80,7 +79,7 @@ fun DocumentDetailScreen(
}
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.documents_details), fontWeight = FontWeight.Bold) },

View File

@@ -16,14 +16,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil3.compose.AsyncImage
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.AuthenticatedImage
import com.tt.honeyDue.viewmodel.DocumentViewModel
import com.tt.honeyDue.viewmodel.ResidenceViewModel
@@ -188,7 +187,7 @@ fun DocumentFormScreen(
}
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = {

View File

@@ -10,13 +10,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.documents.DocumentsTabContent
import com.tt.honeyDue.ui.subscription.UpgradeFeatureScreen
import com.tt.honeyDue.utils.SubscriptionHelper
@@ -83,7 +82,7 @@ fun DocumentsScreen(
}
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
Column {
TopAppBar(

View File

@@ -20,8 +20,6 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
@@ -31,6 +29,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.HandleErrors
import com.tt.honeyDue.ui.components.auth.AuthHeader
import com.tt.honeyDue.ui.components.auth.GoogleSignInButton
@@ -111,12 +110,11 @@ fun LoginScreen(
val isLoading = loginState is ApiResult.Loading || googleSignInState is ApiResult.Loading
WarmGradientBackground {
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
Box(
modifier = Modifier
.fillMaxSize()
.imePadding()
.semantics { testTagsAsResourceId = true },
.enableTestTagsAsResourceId(),
contentAlignment = Alignment.Center
) {
OrganicCard(

View File

@@ -12,8 +12,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
@@ -25,6 +23,7 @@ import com.tt.honeyDue.models.ResidenceShareCode
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.common.StandardErrorState
import com.tt.honeyDue.ui.theme.*
import kotlinx.coroutines.launch
@@ -76,7 +75,7 @@ fun ManageUsersScreen(
WarmGradientBackground {
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
containerColor = androidx.compose.ui.graphics.Color.Transparent,
topBar = {
TopAppBar(

View File

@@ -18,8 +18,6 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
@@ -28,6 +26,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.HandleErrors
import com.tt.honeyDue.ui.components.auth.AuthHeader
import com.tt.honeyDue.ui.components.auth.RequirementItem
@@ -88,9 +87,8 @@ fun RegisterScreen(
}
WarmGradientBackground {
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.auth_register_title), fontWeight = FontWeight.SemiBold) },

View File

@@ -13,13 +13,12 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.AddNewTaskDialog
import com.tt.honeyDue.ui.components.ApiResultHandler
import com.tt.honeyDue.ui.components.CompleteTaskDialog
@@ -423,7 +422,7 @@ fun ResidenceDetailScreen(
Scaffold(
modifier = Modifier
.semantics { testTagsAsResourceId = true }
.enableTestTagsAsResourceId()
.testTag(AccessibilityIds.Residence.detailView),
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = {

View File

@@ -12,13 +12,12 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.viewmodel.ResidenceViewModel
import com.tt.honeyDue.repository.LookupsRepository
import com.tt.honeyDue.data.LocalDataManager
@@ -161,7 +160,7 @@ fun ResidenceFormScreen(
}
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = { Text(if (isEditMode) stringResource(Res.string.properties_edit_title) else stringResource(Res.string.properties_add_title)) },

View File

@@ -22,8 +22,6 @@ import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -31,6 +29,7 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.ApiResultHandler
import com.tt.honeyDue.ui.components.common.StatItem
import com.tt.honeyDue.ui.components.residence.TaskStatChip
@@ -118,7 +117,7 @@ fun ResidencesScreen(
}
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = {

View File

@@ -11,8 +11,6 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
@@ -20,6 +18,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.HandleErrors
import com.tt.honeyDue.ui.components.auth.AuthHeader
import com.tt.honeyDue.ui.components.common.ErrorCard
@@ -69,9 +68,8 @@ fun VerifyEmailScreen(
}
}
@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class)
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = { Text(stringResource(Res.string.auth_verify_title), fontWeight = FontWeight.SemiBold) },

View File

@@ -39,7 +39,6 @@ import androidx.compose.ui.semantics.LiveRegionMode
import androidx.compose.ui.semantics.error
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
@@ -48,6 +47,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.testing.AccessibilityIds
import com.tt.honeyDue.ui.support.enableTestTagsAsResourceId
import com.tt.honeyDue.ui.components.common.StandardCard
import com.tt.honeyDue.ui.components.forms.FormTextField
import com.tt.honeyDue.ui.theme.AppRadius
@@ -86,7 +86,7 @@ fun JoinResidenceScreen(
}
Scaffold(
modifier = Modifier.semantics { testTagsAsResourceId = true },
modifier = Modifier.enableTestTagsAsResourceId(),
topBar = {
TopAppBar(
title = {

View File

@@ -0,0 +1,15 @@
package com.tt.honeyDue.ui.support
import androidx.compose.ui.Modifier
/**
* Opt-in to exposing Compose [Modifier.testTag] values as Android View
* resource IDs so Espresso/UI-Automator tests can select them. No-op on
* non-Android platforms.
*
* Apply once on a screen's root Scaffold / Box:
* ```
* Scaffold(modifier = Modifier.enableTestTagsAsResourceId(), ...)
* ```
*/
expect fun Modifier.enableTestTagsAsResourceId(): Modifier

View File

@@ -0,0 +1,5 @@
package com.tt.honeyDue.ui.support
import androidx.compose.ui.Modifier
actual fun Modifier.enableTestTagsAsResourceId(): Modifier = this

View File

@@ -0,0 +1,5 @@
package com.tt.honeyDue.ui.support
import androidx.compose.ui.Modifier
actual fun Modifier.enableTestTagsAsResourceId(): Modifier = this

View File

@@ -0,0 +1,5 @@
package com.tt.honeyDue.ui.support
import androidx.compose.ui.Modifier
actual fun Modifier.enableTestTagsAsResourceId(): Modifier = this

View File

@@ -0,0 +1,5 @@
package com.tt.honeyDue.ui.support
import androidx.compose.ui.Modifier
actual fun Modifier.enableTestTagsAsResourceId(): Modifier = this