diff --git a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt
index 54053a1bb..2b0bc3bf0 100644
--- a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt
+++ b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt
@@ -18,7 +18,8 @@ package com.google.samples.apps.nowinandroid.ui
import androidx.compose.ui.semantics.SemanticsActions.ScrollBy
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.assertIsOn
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertIsSelected
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
@@ -87,6 +88,8 @@ class NavigationTest {
private val forYou by composeTestRule.stringResource(FeatureForyouR.string.feature_foryou_title)
private val interests by composeTestRule.stringResource(FeatureSearchR.string.feature_search_interests)
private val sampleTopic = "Headlines"
+ private val sampleTopicCheckIconDescription = "Headlines checked"
+ private val sampleTopicAddIconDescription = "Headlines add"
private val appName by composeTestRule.stringResource(R.string.app_name)
private val saved by composeTestRule.stringResource(BookmarksR.string.feature_bookmarks_title)
private val settings by composeTestRule.stringResource(SettingsR.string.feature_settings_top_app_bar_action_icon_description)
@@ -115,13 +118,20 @@ class NavigationTest {
fun navigationBar_navigateToPreviouslySelectedTab_restoresContent() {
composeTestRule.apply {
// GIVEN the user follows a topic
- onNodeWithText(sampleTopic).performClick()
+ onNodeWithContentDescription(sampleTopic).performClick()
// WHEN the user navigates to the Interests destination
onNodeWithText(interests).performClick()
// AND the user navigates to the For You destination
onNodeWithText(forYou).performClick()
// THEN the state of the For You destination is restored
- onNodeWithContentDescription(sampleTopic).assertIsOn()
+ onNodeWithContentDescription(
+ sampleTopicCheckIconDescription,
+ useUnmergedTree = true,
+ ).assertIsDisplayed()
+ onNodeWithContentDescription(
+ sampleTopicAddIconDescription,
+ useUnmergedTree = true,
+ ).assertIsNotDisplayed()
}
}
@@ -132,11 +142,18 @@ class NavigationTest {
fun navigationBar_reselectTab_keepsState() {
composeTestRule.apply {
// GIVEN the user follows a topic
- onNodeWithText(sampleTopic).performClick()
+ onNodeWithContentDescription(sampleTopic).performClick()
// WHEN the user taps the For You navigation bar item
onNodeWithText(forYou).performClick()
// THEN the state of the For You destination is restored
- onNodeWithContentDescription(sampleTopic).assertIsOn()
+ onNodeWithContentDescription(
+ sampleTopicCheckIconDescription,
+ useUnmergedTree = true,
+ ).assertIsDisplayed()
+ onNodeWithContentDescription(
+ sampleTopicAddIconDescription,
+ useUnmergedTree = true,
+ ).assertIsNotDisplayed()
}
}
diff --git a/feature/foryou/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt
index c3ec5c560..6bb2197c5 100644
--- a/feature/foryou/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt
+++ b/feature/foryou/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt
@@ -128,7 +128,7 @@ class ForYouScreenTest {
testData.forEach { testTopic ->
composeTestRule
- .onNodeWithText(testTopic.topic.name)
+ .onNodeWithContentDescription(testTopic.topic.name)
.assertExists()
.assertHasClickAction()
}
@@ -175,7 +175,7 @@ class ForYouScreenTest {
followableTopicTestData.forEach { testTopic ->
composeTestRule
- .onNodeWithText(testTopic.topic.name)
+ .onNodeWithContentDescription(testTopic.topic.name)
.assertExists()
.assertHasClickAction()
}
diff --git a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt
index 1a3325996..7190f5cbc 100644
--- a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt
+++ b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt
@@ -75,6 +75,13 @@ import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.semantics.toggleableState
+import androidx.compose.ui.state.ToggleableState.Off
+import androidx.compose.ui.state.ToggleableState.On
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@@ -268,23 +275,30 @@ private fun LazyStaggeredGridScope.onboarding(
is OnboardingUiState.Shown -> {
item(span = StaggeredGridItemSpan.FullLine, contentType = "onboarding") {
- Column(modifier = interestsItemModifier) {
- Text(
- text = stringResource(R.string.feature_foryou_onboarding_guidance_title),
- textAlign = TextAlign.Center,
+ Column(
+ modifier = interestsItemModifier,
+ ) {
+ Column(
modifier = Modifier
- .fillMaxWidth()
- .padding(top = 24.dp),
- style = MaterialTheme.typography.titleMedium,
- )
- Text(
- text = stringResource(R.string.feature_foryou_onboarding_guidance_subtitle),
- modifier = Modifier
- .fillMaxWidth()
- .padding(top = 8.dp, start = 24.dp, end = 24.dp),
- textAlign = TextAlign.Center,
- style = MaterialTheme.typography.bodyMedium,
- )
+ .semantics(mergeDescendants = true) { },
+ ) {
+ Text(
+ text = stringResource(R.string.feature_foryou_onboarding_guidance_title),
+ textAlign = TextAlign.Center,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 24.dp),
+ style = MaterialTheme.typography.titleMedium,
+ )
+ Text(
+ text = stringResource(R.string.feature_foryou_onboarding_guidance_subtitle),
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 8.dp, start = 24.dp, end = 24.dp),
+ textAlign = TextAlign.Center,
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ }
TopicSelection(
onboardingUiState,
onTopicCheckedChanged,
@@ -384,7 +398,21 @@ private fun SingleTopicButton(
Surface(
modifier = Modifier
.width(312.dp)
- .heightIn(min = 56.dp),
+ .heightIn(min = 56.dp)
+ .semantics(mergeDescendants = true) {
+ toggleableState = if (isSelected) {
+ On
+ } else {
+ Off
+ }
+ stateDescription = if (isSelected) {
+ "Following"
+ } else {
+ "Not Following"
+ }
+
+ contentDescription = name
+ },
shape = RoundedCornerShape(corner = CornerSize(8.dp)),
color = MaterialTheme.colorScheme.surface,
selected = isSelected,
@@ -394,7 +422,9 @@ private fun SingleTopicButton(
) {
Row(
verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier.padding(start = 12.dp, end = 8.dp),
+ modifier = Modifier
+ .padding(start = 12.dp, end = 8.dp)
+ .clearAndSetSemantics { },
) {
TopicIcon(
imageUrl = imageUrl,
@@ -413,13 +443,19 @@ private fun SingleTopicButton(
icon = {
Icon(
imageVector = NiaIcons.Add,
- contentDescription = name,
+ contentDescription = stringResource(
+ id = R.string.feature_foryou_topic_icon_add,
+ name,
+ ),
)
},
checkedIcon = {
Icon(
imageVector = NiaIcons.Check,
- contentDescription = name,
+ contentDescription = stringResource(
+ id = R.string.feature_foryou_topic_icon_checked,
+ name,
+ ),
)
},
)
diff --git a/feature/foryou/src/main/res/values/strings.xml b/feature/foryou/src/main/res/values/strings.xml
index 166749664..3efa10b0b 100644
--- a/feature/foryou/src/main/res/values/strings.xml
+++ b/feature/foryou/src/main/res/values/strings.xml
@@ -21,5 +21,7 @@
Navigate up
What are you interested in?
Updates from topics you follow will appear here. Follow some things to get started.
+ %s checked
+ %s add