fix(benchmark): ensure UiAutomator is able to correctly find UI elements

This commit is contained in:
Harsh Shandilya 2022-11-29 21:22:14 +05:30
parent 3601c190ac
commit ce37523e11
No known key found for this signature in database
4 changed files with 52 additions and 13 deletions

View file

@ -20,11 +20,14 @@ import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource 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.compose.ui.text.font.FontWeight
import androidx.navigation.NavType import androidx.navigation.NavType
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
@ -54,7 +57,10 @@ import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
import dev.msfjarvis.claw.common.user.UserProfile import dev.msfjarvis.claw.common.user.UserProfile
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class) @OptIn(
ExperimentalComposeUiApi::class,
ExperimentalMaterial3Api::class,
)
@Composable @Composable
fun LobstersApp( fun LobstersApp(
urlLauncher: UrlLauncher, urlLauncher: UrlLauncher,
@ -156,7 +162,7 @@ fun LobstersApp(
isVisible = navItems.any { it.route == currentDestination }, isVisible = navItems.any { it.route == currentDestination },
) )
}, },
modifier = modifier, modifier = modifier.semantics { testTagsAsResourceId = true },
) { paddingValues -> ) { paddingValues ->
NavHost( NavHost(
navController = navController, navController = navController,

View file

@ -20,6 +20,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.testTag
import androidx.navigation.NavController import androidx.navigation.NavController
import dev.msfjarvis.claw.android.ui.navigation.Destinations import dev.msfjarvis.claw.android.ui.navigation.Destinations
@ -73,7 +74,8 @@ fun ClawNavigationBar(
if (navItem.route != Destinations.startDestination.route) { if (navItem.route != Destinations.startDestination.route) {
navController.navigate(navItem.route) navController.navigate(navItem.route)
} }
} },
modifier = Modifier.testTag(navItem.label.uppercase()),
) )
} }
} }

View file

@ -9,19 +9,51 @@ package dev.msfjarvis.claw.benchmark
import androidx.benchmark.macro.MacrobenchmarkScope import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.test.uiautomator.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
const val PACKAGE_NAME = "dev.msfjarvis.claw.android" 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) { fun MacrobenchmarkScope.exploreUI(device: UiDevice) {
startActivityAndWait() startActivityAndWait()
device.run { device.run {
listOf("HOTTEST", "NEWEST", "SAVED").forEach { desc -> savePosts()
findObject(By.desc(desc)).click()
waitForIdle() exploreScreens()
}
findObject(By.desc("HOTTEST")).click() returnToHottestScreen()
waitForIdle()
findObjects(By.desc("Open comments")).first().click() openCommentsScreen()
waitForIdle()
} }
} }
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()
}

View file

@ -2,7 +2,6 @@
<SmellBaseline> <SmellBaseline>
<ManuallySuppressedIssues></ManuallySuppressedIssues> <ManuallySuppressedIssues></ManuallySuppressedIssues>
<CurrentIssues> <CurrentIssues>
<ID>LongMethod:LobstersApp.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun LobstersApp( urlLauncher: UrlLauncher, htmlConverter: HTMLConverter, setWebUri: (String?) -&gt; Unit, modifier: Modifier = Modifier, viewModel: ClawViewModel = injectedViewModel(), )</ID> <ID>LongMethod:LobstersApp.kt$@OptIn( ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class, ) @Composable fun LobstersApp( urlLauncher: UrlLauncher, htmlConverter: HTMLConverter, setWebUri: (String?) -&gt; Unit, modifier: Modifier = Modifier, viewModel: ClawViewModel = injectedViewModel(), )</ID>
<ID>LongParameterList:NetworkPosts.kt$( lazyPagingItems: LazyPagingItems&lt;LobstersPost&gt;, listState: LazyListState, isPostSaved: suspend (SavedPost) -&gt; Boolean, reloadPosts: () -&gt; Unit, postActions: PostActions, modifier: Modifier = Modifier, )</ID>
</CurrentIssues> </CurrentIssues>
</SmellBaseline> </SmellBaseline>