Skip to content

Commit 8a3191c

Browse files
committed
Add Benchmark for navigation between list -> detail
1 parent ab04b13 commit 8a3191c

2 files changed

Lines changed: 71 additions & 13 deletions

File tree

‎Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Snacks.kt‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ import androidx.compose.ui.platform.LocalContext
6868
import androidx.compose.ui.platform.LocalDensity
6969
import androidx.compose.ui.platform.LocalInspectionMode
7070
import androidx.compose.ui.res.painterResource
71+
import androidx.compose.ui.semantics.semantics
72+
import androidx.compose.ui.semantics.testTag
73+
import androidx.compose.ui.semantics.testTagsAsResourceId
7174
import androidx.compose.ui.text.style.TextOverflow
7275
import androidx.compose.ui.tooling.preview.Preview
7376
import androidx.compose.ui.unit.Density
@@ -219,6 +222,10 @@ fun SnackItem(snack: Snack, snackCollectionId: Long, onSnackClick: (Long, String
219222
Column(
220223
horizontalAlignment = Alignment.CenterHorizontally,
221224
modifier = Modifier
225+
.semantics {
226+
testTag = "snack_item"
227+
testTagsAsResourceId = true
228+
}
222229
.clickable(onClick = {
223230
onSnackClick(snack.id, snackCollectionId.toString())
224231
})
@@ -355,6 +362,10 @@ private fun HighlightSnackItem(
355362
) {
356363
Column(
357364
modifier = Modifier
365+
.semantics {
366+
testTag = "highlight_snack_item"
367+
testTagsAsResourceId = true
368+
}
358369
.clickable(onClick = {
359370
onSnackClick(
360371
snack.id,

‎Jetsnack/benchmark/src/main/java/com/example/jetsnack/benchmark/JetsnackBenchmarks.kt‎

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,32 +44,79 @@ class JetsnackBenchmarks {
4444
compilationMode = CompilationMode.DEFAULT,
4545
startupMode = StartupMode.COLD,
4646
iterations = 10,
47+
setupBlock = {
48+
pressHome()
49+
val context = InstrumentationRegistry.getInstrumentation().context
50+
val intent = context.packageManager.getLaunchIntentForPackage(packageName)!!
51+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
52+
context.startActivity(intent)
53+
device.wait(Until.hasObject(By.pkg(packageName).depth(0)), 15000)
54+
device.wait(Until.hasObject(By.res("feed_list")), 15000)
55+
},
4756
) {
48-
pressHome()
49-
val context = InstrumentationRegistry.getInstrumentation().context
50-
val intent = context.packageManager.getLaunchIntentForPackage(packageName)!!
51-
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
52-
context.startActivity(intent)
53-
device.wait(Until.hasObject(By.pkg(packageName).depth(0)), 15000)
54-
55-
// Wait for the feed list
5657
val listSelector = By.res("feed_list")
57-
val list = device.wait(Until.findObject(listSelector), 15000)
58-
?: device.wait(Until.findObject(By.scrollable(true)), 15000)
59-
requireNotNull(list) { "Feed list not found!" }
60-
61-
list.setGestureMargin(device.displayWidth / 5)
6258

6359
// Scroll down through feed
6460
repeat(3) {
61+
val list = device.findObject(listSelector) ?: device.findObject(By.scrollable(true))
62+
requireNotNull(list) { "Feed list not found!" }
63+
list.setGestureMargin(device.displayWidth / 5)
6564
list.fling(Direction.DOWN)
6665
device.waitForIdle()
6766
}
6867

6968
// Scroll back up
7069
repeat(3) {
70+
val list = device.findObject(listSelector) ?: device.findObject(By.scrollable(true))
71+
requireNotNull(list) { "Feed list not found!" }
72+
list.setGestureMargin(device.displayWidth / 5)
7173
list.fling(Direction.UP)
7274
device.waitForIdle()
7375
}
7476
}
77+
78+
@Test
79+
fun navigateSnackDetailFrameTiming() = benchmarkRule.measureRepeated(
80+
packageName = targetPackageName,
81+
metrics = listOf(FrameTimingMetric()),
82+
compilationMode = CompilationMode.DEFAULT,
83+
startupMode = StartupMode.COLD,
84+
iterations = 10,
85+
setupBlock = {
86+
pressHome()
87+
val context = InstrumentationRegistry.getInstrumentation().context
88+
val intent = context.packageManager.getLaunchIntentForPackage(packageName)!!
89+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
90+
context.startActivity(intent)
91+
device.wait(Until.hasObject(By.pkg(packageName).depth(0)), 15000)
92+
device.wait(Until.hasObject(By.res("feed_list")), 15000)
93+
device.wait(Until.hasObject(By.res("highlight_snack_item")), 10000)
94+
device.waitForIdle()
95+
},
96+
) {
97+
val listSelector = By.res("feed_list")
98+
99+
// Find snack item to click and trigger shared element transition
100+
val snackItem = device.wait(Until.findObject(By.text("Cupcake")), 10000)
101+
?: device.wait(Until.findObject(By.text("Donut")), 5000)
102+
?: device.wait(Until.findObject(By.res("highlight_snack_item")), 5000)
103+
?: device.findObject(By.res("snack_item"))
104+
?: device.findObject(By.clickable(true))
105+
requireNotNull(snackItem) { "Snack item not found on feed!" }
106+
107+
// Click snack to navigate into detail with shared element transition
108+
snackItem.click()
109+
110+
// Wait for detail screen to appear
111+
val detailLoaded = device.wait(Until.hasObject(By.desc("Back")), 10000) ||
112+
device.wait(Until.hasObject(By.text("Details")), 5000) ||
113+
device.wait(Until.hasObject(By.textContains("CART")), 5000)
114+
check(detailLoaded) { "Detail screen not loaded!" }
115+
device.waitForIdle()
116+
117+
// Return to feed with reverse shared transition
118+
device.pressBack()
119+
device.wait(Until.hasObject(listSelector), 10000)
120+
device.waitForIdle()
121+
}
75122
}

0 commit comments

Comments
 (0)