Merge branch 'github/main'

pull/591/head^2
Automerger 2 years ago
commit 8dd9abd6ac

File diff suppressed because it is too large Load Diff

@ -18,11 +18,12 @@ package com.google.samples.apps.nowinandroid.baselineprofile
import androidx.benchmark.macro.ExperimentalBaselineProfilesApi import androidx.benchmark.macro.ExperimentalBaselineProfilesApi
import androidx.benchmark.macro.junit4.BaselineProfileRule import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.uiautomator.By
import com.google.samples.apps.nowinandroid.PACKAGE_NAME import com.google.samples.apps.nowinandroid.PACKAGE_NAME
import com.google.samples.apps.nowinandroid.bookmarks.goToBookmarksScreen
import com.google.samples.apps.nowinandroid.foryou.forYouScrollFeedDownUp import com.google.samples.apps.nowinandroid.foryou.forYouScrollFeedDownUp
import com.google.samples.apps.nowinandroid.foryou.forYouSelectTopics
import com.google.samples.apps.nowinandroid.foryou.forYouWaitForContent import com.google.samples.apps.nowinandroid.foryou.forYouWaitForContent
import com.google.samples.apps.nowinandroid.interests.interestsScrollPeopleDownUp import com.google.samples.apps.nowinandroid.interests.goToInterestsScreen
import com.google.samples.apps.nowinandroid.interests.interestsScrollTopicsDownUp import com.google.samples.apps.nowinandroid.interests.interestsScrollTopicsDownUp
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -46,24 +47,16 @@ class BaselineProfileGenerator {
// Scroll the feed critical user journey // Scroll the feed critical user journey
forYouWaitForContent() forYouWaitForContent()
forYouSelectTopics(true)
forYouScrollFeedDownUp() forYouScrollFeedDownUp()
// Navigate to saved screen // Navigate to saved screen
device.findObject(By.text("Saved")).click() goToBookmarksScreen()
device.waitForIdle()
// TODO: we need to implement adding stuff to bookmarks before able to scroll it // TODO: we need to implement adding stuff to bookmarks before able to scroll it
// bookmarksScrollFeedDownUp() // bookmarksScrollFeedDownUp()
// Navigate to interests screen // Navigate to interests screen
device.findObject(By.text("Interests")).click() goToInterestsScreen()
device.waitForIdle()
interestsScrollTopicsDownUp() interestsScrollTopicsDownUp()
// Navigate to people tab
device.findObject(By.text("People")).click()
device.waitForIdle()
interestsScrollPeopleDownUp()
} }
} }

@ -18,8 +18,18 @@ package com.google.samples.apps.nowinandroid.bookmarks
import androidx.benchmark.macro.MacrobenchmarkScope import androidx.benchmark.macro.MacrobenchmarkScope
import androidx.test.uiautomator.By import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
import com.google.samples.apps.nowinandroid.flingElementDownUp import com.google.samples.apps.nowinandroid.flingElementDownUp
fun MacrobenchmarkScope.goToBookmarksScreen() {
device.findObject(By.text("Saved")).click()
device.waitForIdle()
// Wait until saved title are shown on screen
device.wait(Until.hasObject(By.res("niaTopAppBar")), 2_000)
val topAppBar = device.findObject(By.res("niaTopAppBar"))
topAppBar.wait(Until.hasObject(By.text("Saved")), 2_000)
}
fun MacrobenchmarkScope.bookmarksScrollFeedDownUp() { fun MacrobenchmarkScope.bookmarksScrollFeedDownUp() {
val feedList = device.findObject(By.res("bookmarks:feed")) val feedList = device.findObject(By.res("bookmarks:feed"))
device.flingElementDownUp(feedList) device.flingElementDownUp(feedList)

@ -23,12 +23,65 @@ import androidx.test.uiautomator.untilHasChildren
import com.google.samples.apps.nowinandroid.flingElementDownUp import com.google.samples.apps.nowinandroid.flingElementDownUp
fun MacrobenchmarkScope.forYouWaitForContent() { fun MacrobenchmarkScope.forYouWaitForContent() {
// Wait until content is loaded by checking if authors are loaded // Wait until content is loaded by checking if topics are loaded
device.wait(Until.gone(By.res("forYou:loadingWheel")), 5_000) device.wait(Until.gone(By.res("loadingWheel")), 5_000)
// Sometimes, the loading wheel is gone, but the content is not loaded yet // Sometimes, the loading wheel is gone, but the content is not loaded yet
// So we'll wait here for authors to be sure // So we'll wait here for topics to be sure
val obj = device.findObject(By.res("forYou:authors")) val obj = device.findObject(By.res("forYou:topicSelection"))
obj.wait(untilHasChildren(), 30_000) // Timeout here is quite big, because sometimes data loading takes a long time!
obj.wait(untilHasChildren(), 60_000)
}
/**
* Selects some topics, which will show the feed content for them.
* [recheckTopicsIfChecked] Topics may be already checked from the previous iteration.
*/
fun MacrobenchmarkScope.forYouSelectTopics(recheckTopicsIfChecked: Boolean = false) {
val topics = device.findObject(By.res("forYou:topicSelection"))
// Set gesture margin from sides not to trigger system gesture navigation
val horizontalMargin = 10 * topics.visibleBounds.width() / 100
topics.setGestureMargins(horizontalMargin, 0, horizontalMargin, 0)
// Select some topics to show some feed content
var index = 0
var visited = 0
while (visited < 3) {
// Selecting some topics, which will populate items in the feed.
val topic = topics.children[index % topics.childCount]
// Find the checkable element to figure out whether it's checked or not
val topicCheckIcon = topic.findObject(By.checkable(true))
// Topic icon may not be visible if it's out of the screen boundaries
// If that's the case, let's try another index
if (topicCheckIcon == null) {
index++
continue
}
when {
// Topic wasn't checked, so just do that
!topicCheckIcon.isChecked -> {
topic.click()
device.waitForIdle()
}
// Topic was checked already and we want to recheck it, so just do it twice
recheckTopicsIfChecked -> {
repeat(2) {
topic.click()
device.waitForIdle()
}
}
else -> {
// Topic is checked, but we don't recheck it
}
}
index++
visited++
}
} }
fun MacrobenchmarkScope.forYouScrollFeedDownUp() { fun MacrobenchmarkScope.forYouScrollFeedDownUp() {

@ -50,6 +50,7 @@ class ScrollForYouFeedBenchmark {
} }
) { ) {
forYouWaitForContent() forYouWaitForContent()
forYouSelectTopics()
forYouScrollFeedDownUp() forYouScrollFeedDownUp()
} }
} }

@ -21,16 +21,23 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until import androidx.test.uiautomator.Until
import com.google.samples.apps.nowinandroid.flingElementDownUp import com.google.samples.apps.nowinandroid.flingElementDownUp
fun MacrobenchmarkScope.goToInterestsScreen() {
device.findObject(By.text("Interests")).click()
device.waitForIdle()
// Wait until interests are shown on screen
device.wait(Until.hasObject(By.res("niaTopAppBar")), 2_000)
val topAppBar = device.findObject(By.res("niaTopAppBar"))
topAppBar.wait(Until.hasObject(By.text("Interests")), 2_000)
// Wait until content is loaded by checking if interests are loaded
device.wait(Until.gone(By.res("loadingWheel")), 5_000)
}
fun MacrobenchmarkScope.interestsScrollTopicsDownUp() { fun MacrobenchmarkScope.interestsScrollTopicsDownUp() {
val topicsList = device.findObject(By.res("interests:topics")) val topicsList = device.findObject(By.res("interests:topics"))
device.flingElementDownUp(topicsList) device.flingElementDownUp(topicsList)
} }
fun MacrobenchmarkScope.interestsScrollPeopleDownUp() {
val peopleList = device.findObject(By.res("interests:people"))
device.flingElementDownUp(peopleList)
}
fun MacrobenchmarkScope.interestsWaitForTopics() { fun MacrobenchmarkScope.interestsWaitForTopics() {
device.wait(Until.hasObject(By.text("Accessibility")), 30_000) device.wait(Until.hasObject(By.text("Accessibility")), 30_000)
} }

@ -43,6 +43,7 @@ import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -109,6 +110,7 @@ fun NiaLoadingWheel(
.padding(8.dp) .padding(8.dp)
.graphicsLayer { rotationZ = rotationAnim } .graphicsLayer { rotationZ = rotationAnim }
.semantics { contentDescription = contentDesc } .semantics { contentDescription = contentDesc }
.testTag("loadingWheel"),
) { ) {
repeat(NUM_OF_LINES) { index -> repeat(NUM_OF_LINES) { index ->
rotate(degrees = index * 30f) { rotate(degrees = index * 30f) {

@ -30,6 +30,7 @@ import androidx.compose.material3.TopAppBarDefaults
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.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
@ -68,7 +69,7 @@ fun NiaTopAppBar(
} }
}, },
colors = colors, colors = colors,
modifier = modifier modifier = modifier.testTag("niaTopAppBar"),
) )
} }
@ -97,7 +98,7 @@ fun NiaTopAppBar(
} }
}, },
colors = colors, colors = colors,
modifier = modifier, modifier = modifier.testTag("niaTopAppBar"),
) )
} }

@ -203,8 +203,7 @@ internal fun ForYouScreen(
) { ) {
NiaOverlayLoadingWheel( NiaOverlayLoadingWheel(
modifier = Modifier modifier = Modifier
.align(Alignment.Center) .align(Alignment.Center),
.testTag("forYou:loadingWheel"),
contentDesc = loadingContentDescription contentDesc = loadingContentDescription
) )
} }
@ -281,7 +280,9 @@ private fun TopicSelection(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) = trace("TopicSelection") { ) = trace("TopicSelection") {
val lazyGridState = rememberLazyGridState() val lazyGridState = rememberLazyGridState()
TrackScrollJank(scrollableState = lazyGridState, stateName = "forYou:TopicSelection") val topicSelectionTestTag = "forYou:topicSelection"
TrackScrollJank(scrollableState = lazyGridState, stateName = topicSelectionTestTag)
LazyHorizontalGrid( LazyHorizontalGrid(
state = lazyGridState, state = lazyGridState,
@ -301,6 +302,7 @@ private fun TopicSelection(
// The maximum of these two bounds is therefore a valid upper bound in all cases. // The maximum of these two bounds is therefore a valid upper bound in all cases.
.heightIn(max = max(240.dp, with(LocalDensity.current) { 240.sp.toDp() })) .heightIn(max = max(240.dp, with(LocalDensity.current) { 240.sp.toDp() }))
.fillMaxWidth() .fillMaxWidth()
.testTag(topicSelectionTestTag)
) { ) {
items(onboardingUiState.topics) { items(onboardingUiState.topics) {
SingleTopicButton( SingleTopicButton(

Loading…
Cancel
Save