diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt index 4c716a96..9f845031 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt @@ -20,11 +20,14 @@ import androidx.compose.runtime.SideEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.font.FontWeight import androidx.navigation.NavType import androidx.navigation.compose.NavHost @@ -54,7 +57,10 @@ import dev.msfjarvis.claw.common.urllauncher.UrlLauncher import dev.msfjarvis.claw.common.user.UserProfile import kotlinx.coroutines.launch -@OptIn(ExperimentalMaterial3Api::class) +@OptIn( + ExperimentalComposeUiApi::class, + ExperimentalMaterial3Api::class, +) @Composable fun LobstersApp( urlLauncher: UrlLauncher, @@ -156,7 +162,7 @@ fun LobstersApp( isVisible = navItems.any { it.route == currentDestination }, ) }, - modifier = modifier, + modifier = modifier.semantics { testTagsAsResourceId = true }, ) { paddingValues -> NavHost( navController = navController, diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt index 8fd1cb6f..db30e014 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/decorations/ClawNavigationBar.kt @@ -20,6 +20,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.testTag import androidx.navigation.NavController import dev.msfjarvis.claw.android.ui.navigation.Destinations @@ -73,7 +74,8 @@ fun ClawNavigationBar( if (navItem.route != Destinations.startDestination.route) { navController.navigate(navItem.route) } - } + }, + modifier = Modifier.testTag(navItem.label.uppercase()), ) } } diff --git a/benchmark/src/main/kotlin/dev/msfjarvis/claw/benchmark/BenchmarkUtils.kt b/benchmark/src/main/kotlin/dev/msfjarvis/claw/benchmark/BenchmarkUtils.kt index 803ab652..c2676b82 100644 --- a/benchmark/src/main/kotlin/dev/msfjarvis/claw/benchmark/BenchmarkUtils.kt +++ b/benchmark/src/main/kotlin/dev/msfjarvis/claw/benchmark/BenchmarkUtils.kt @@ -9,19 +9,51 @@ package dev.msfjarvis.claw.benchmark import androidx.benchmark.macro.MacrobenchmarkScope import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until const val PACKAGE_NAME = "dev.msfjarvis.claw.android" +private const val AWAIT_TIMEOUT = 10_000L +private const val SAVE_BUTTON_DESC = "Add to saved posts" +private const val NAV_ID_HOTTEST = "HOTTEST" +private const val NAV_ID_NEWEST = "NEWEST" +private const val NAV_ID_SAVED = "SAVED" +private const val COMMENT_BUTTON_DESC = "Open comments" fun MacrobenchmarkScope.exploreUI(device: UiDevice) { startActivityAndWait() device.run { - listOf("HOTTEST", "NEWEST", "SAVED").forEach { desc -> - findObject(By.desc(desc)).click() - waitForIdle() - } - findObject(By.desc("HOTTEST")).click() - waitForIdle() - findObjects(By.desc("Open comments")).first().click() - waitForIdle() + savePosts() + + exploreScreens() + + returnToHottestScreen() + + openCommentsScreen() } } + +private fun UiDevice.waitForSubmitterName() { + wait(Until.hasObject(By.textContains("Submitted by")), AWAIT_TIMEOUT) +} + +private fun UiDevice.savePosts() { + waitForSubmitterName() + findObjects(By.desc(SAVE_BUTTON_DESC)).forEach { btn -> btn.click() } +} + +private fun UiDevice.exploreScreens() { + listOf(NAV_ID_HOTTEST, NAV_ID_NEWEST, NAV_ID_SAVED).forEach { tag -> + findObject(By.res(tag)).click() + waitForSubmitterName() + } +} + +private fun UiDevice.returnToHottestScreen() { + findObject(By.res(NAV_ID_HOTTEST)).click() + waitForSubmitterName() +} + +private fun UiDevice.openCommentsScreen() { + findObjects(By.desc(COMMENT_BUTTON_DESC)).first().click() + waitForSubmitterName() +} diff --git a/detekt-baselines/android.xml b/detekt-baselines/android.xml index 2d00d3cf..f6e20e8d 100644 --- a/detekt-baselines/android.xml +++ b/detekt-baselines/android.xml @@ -2,7 +2,6 @@ - LongMethod:LobstersApp.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun LobstersApp( urlLauncher: UrlLauncher, htmlConverter: HTMLConverter, setWebUri: (String?) -> Unit, modifier: Modifier = Modifier, viewModel: ClawViewModel = injectedViewModel(), ) - LongParameterList:NetworkPosts.kt$( lazyPagingItems: LazyPagingItems<LobstersPost>, listState: LazyListState, isPostSaved: suspend (SavedPost) -> Boolean, reloadPosts: () -> Unit, postActions: PostActions, modifier: Modifier = Modifier, ) + LongMethod:LobstersApp.kt$@OptIn( ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class, ) @Composable fun LobstersApp( urlLauncher: UrlLauncher, htmlConverter: HTMLConverter, setWebUri: (String?) -> Unit, modifier: Modifier = Modifier, viewModel: ClawViewModel = injectedViewModel(), )