PM-14200: Update the eyebrows throughout the app (#4181)

This commit is contained in:
David Perez 2024-10-29 08:57:16 -05:00 committed by GitHub
parent 150c8e0312
commit a1108889cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 79 additions and 164 deletions

View file

@ -1,5 +1,6 @@
package com.x8bit.bitwarden.ui.platform.components.header package com.x8bit.bitwarden.ui.platform.components.header
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -12,16 +13,19 @@ import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
* Represents a Bitwarden-styled label text. * Represents a Bitwarden-styled label text.
* *
* @param label The text content for the label. * @param label The text content for the label.
* @param supportingLabel The optional text for the supporting label.
* @param modifier The [Modifier] to be applied to the label. * @param modifier The [Modifier] to be applied to the label.
*/ */
@Composable @Composable
fun BitwardenListHeaderText( fun BitwardenListHeaderText(
label: String, label: String,
supportingLabel: String? = null,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val supportLabel = supportingLabel?.let { " ($it)" }.orEmpty()
Text( Text(
text = label, text = "${label.uppercase()}$supportLabel",
style = BitwardenTheme.typography.labelMedium, style = BitwardenTheme.typography.eyebrowMedium,
color = BitwardenTheme.colorScheme.text.secondary, color = BitwardenTheme.colorScheme.text.secondary,
modifier = modifier.padding( modifier = modifier.padding(
top = 12.dp, top = 12.dp,
@ -34,9 +38,16 @@ fun BitwardenListHeaderText(
@Composable @Composable
private fun BitwardenListHeaderText_preview() { private fun BitwardenListHeaderText_preview() {
BitwardenTheme { BitwardenTheme {
BitwardenListHeaderText( Column {
label = "Sample Label", BitwardenListHeaderText(
modifier = Modifier, label = "Sample Label",
) modifier = Modifier,
)
BitwardenListHeaderText(
label = "Sample Label",
supportingLabel = "4",
modifier = Modifier,
)
}
} }
} }

View file

@ -1,61 +0,0 @@
package com.x8bit.bitwarden.ui.platform.components.header
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
/**
* Represents a Bitwarden-styled label text.
*
* @param label The text content for the label.
* @param supportingLabel The text for the supporting label.
* @param modifier The [Modifier] to be applied to the label.
*/
@Composable
fun BitwardenListHeaderTextWithSupportLabel(
label: String,
supportingLabel: String,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier
.padding(
top = 12.dp,
bottom = 4.dp,
end = 8.dp,
)
.semantics(mergeDescendants = true) { },
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = label,
style = BitwardenTheme.typography.labelMedium,
color = BitwardenTheme.colorScheme.text.secondary,
)
Text(
text = supportingLabel,
style = BitwardenTheme.typography.labelSmall,
color = BitwardenTheme.colorScheme.text.secondary,
)
}
}
@Preview(showBackground = true)
@Composable
private fun BitwardenListHeaderTextWithSupportLabel_preview() {
BitwardenTheme {
BitwardenListHeaderTextWithSupportLabel(
label = "Sample Label",
supportingLabel = "0",
modifier = Modifier,
)
}
}

View file

@ -234,7 +234,7 @@ val bitwardenTypography: BitwardenTypography = BitwardenTypography(
lineHeight = 18.sp, lineHeight = 18.sp,
fontFamily = FontFamily(Font(R.font.dm_sans_bold)), fontFamily = FontFamily(Font(R.font.dm_sans_bold)),
fontWeight = FontWeight.W700, fontWeight = FontWeight.W700,
letterSpacing = 0.5.sp, letterSpacing = 0.6.sp,
lineHeightStyle = LineHeightStyle( lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center, alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None, trim = LineHeightStyle.Trim.None,

View file

@ -15,7 +15,6 @@ import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.R import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard import com.x8bit.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderTextWithSupportLabel
import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem
import com.x8bit.bitwarden.ui.platform.components.model.IconData import com.x8bit.bitwarden.ui.platform.components.model.IconData
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
@ -83,7 +82,7 @@ fun SendContent(
item { item {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.all_sends), label = stringResource(id = R.string.all_sends),
supportingLabel = state.sendItems.size.toString(), supportingLabel = state.sendItems.size.toString(),
modifier = Modifier modifier = Modifier

View file

@ -21,7 +21,7 @@ import com.x8bit.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenMasterPasswordDialog import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenMasterPasswordDialog
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenTwoButtonDialog import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenTwoButtonDialog
import com.x8bit.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider import com.x8bit.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderTextWithSupportLabel import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem
import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenListItem import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenListItem
import com.x8bit.bitwarden.ui.platform.components.listitem.SelectionItemData import com.x8bit.bitwarden.ui.platform.components.listitem.SelectionItemData
@ -127,7 +127,7 @@ fun VaultItemListingContent(
if (state.displayCollectionList.isNotEmpty()) { if (state.displayCollectionList.isNotEmpty()) {
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.collections), label = stringResource(id = R.string.collections),
supportingLabel = state.displayCollectionList.count().toString(), supportingLabel = state.displayCollectionList.count().toString(),
modifier = Modifier modifier = Modifier
@ -156,7 +156,7 @@ fun VaultItemListingContent(
if (state.displayFolderList.isNotEmpty()) { if (state.displayFolderList.isNotEmpty()) {
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.folders), label = stringResource(id = R.string.folders),
supportingLabel = state.displayFolderList.count().toString(), supportingLabel = state.displayFolderList.count().toString(),
modifier = Modifier modifier = Modifier
@ -195,7 +195,7 @@ fun VaultItemListingContent(
if (state.displayItemList.isNotEmpty()) { if (state.displayItemList.isNotEmpty()) {
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.items), label = stringResource(id = R.string.items),
supportingLabel = state.displayItemList.size.toString(), supportingLabel = state.displayItemList.size.toString(),
modifier = Modifier modifier = Modifier

View file

@ -13,7 +13,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.x8bit.bitwarden.R import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider import com.x8bit.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderTextWithSupportLabel import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem import com.x8bit.bitwarden.ui.platform.components.listitem.BitwardenGroupItem
import com.x8bit.bitwarden.ui.platform.components.model.toIconResources import com.x8bit.bitwarden.ui.platform.components.model.toIconResources
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
@ -38,7 +38,7 @@ fun VaultContent(
) { ) {
if (state.totpItemsCount > 0) { if (state.totpItemsCount > 0) {
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.totp), label = stringResource(id = R.string.totp),
supportingLabel = "1", supportingLabel = "1",
modifier = Modifier modifier = Modifier
@ -64,7 +64,7 @@ fun VaultContent(
if (state.favoriteItems.isNotEmpty()) { if (state.favoriteItems.isNotEmpty()) {
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.favorites), label = stringResource(id = R.string.favorites),
supportingLabel = state.favoriteItems.count().toString(), supportingLabel = state.favoriteItems.count().toString(),
modifier = Modifier modifier = Modifier
@ -120,7 +120,7 @@ fun VaultContent(
} }
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.types), label = stringResource(id = R.string.types),
supportingLabel = "4", supportingLabel = "4",
modifier = Modifier modifier = Modifier
@ -203,7 +203,7 @@ fun VaultContent(
} }
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.folders), label = stringResource(id = R.string.folders),
supportingLabel = state.folderItems.count().toString(), supportingLabel = state.folderItems.count().toString(),
modifier = Modifier modifier = Modifier
@ -241,7 +241,7 @@ fun VaultContent(
} }
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.folder_none), label = stringResource(id = R.string.folder_none),
supportingLabel = state.noFolderItems.count().toString(), supportingLabel = state.noFolderItems.count().toString(),
modifier = Modifier modifier = Modifier
@ -288,7 +288,7 @@ fun VaultContent(
} }
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.collections), label = stringResource(id = R.string.collections),
supportingLabel = state.collectionItems.count().toString(), supportingLabel = state.collectionItems.count().toString(),
modifier = Modifier modifier = Modifier
@ -321,7 +321,7 @@ fun VaultContent(
} }
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.trash), label = stringResource(id = R.string.trash),
supportingLabel = "1", supportingLabel = "1",
modifier = Modifier modifier = Modifier

View file

@ -27,7 +27,7 @@ import com.x8bit.bitwarden.ui.platform.components.content.BitwardenErrorContent
import com.x8bit.bitwarden.ui.platform.components.content.BitwardenLoadingContent import com.x8bit.bitwarden.ui.platform.components.content.BitwardenLoadingContent
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenLoadingDialog import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenLoadingDialog
import com.x8bit.bitwarden.ui.platform.components.dialog.LoadingDialogState import com.x8bit.bitwarden.ui.platform.components.dialog.LoadingDialogState
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderTextWithSupportLabel import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.scaffold.rememberBitwardenPullToRefreshState import com.x8bit.bitwarden.ui.platform.components.scaffold.rememberBitwardenPullToRefreshState
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
@ -160,7 +160,7 @@ private fun VerificationCodeContent(
modifier = modifier, modifier = modifier,
) { ) {
item { item {
BitwardenListHeaderTextWithSupportLabel( BitwardenListHeaderText(
label = stringResource(id = R.string.items), label = stringResource(id = R.string.items),
supportingLabel = items.size.toString(), supportingLabel = items.size.toString(),
modifier = Modifier modifier = Modifier

View file

@ -311,7 +311,7 @@ class VaultItemScreenTest : BaseComposeTest() {
DEFAULT_VIEW_STATES DEFAULT_VIEW_STATES
.forEach { typeState -> .forEach { typeState ->
mutableStateFlow.update { it.copy(viewState = typeState) } mutableStateFlow.update { it.copy(viewState = typeState) }
composeTestRule.onNodeWithTextAfterScroll("Custom fields").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("CUSTOM FIELDS").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("text").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("text").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("value").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("value").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("hidden").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("hidden").assertIsDisplayed()
@ -321,7 +321,7 @@ class VaultItemScreenTest : BaseComposeTest() {
updateCommonContent(currentState) { copy(customFields = emptyList()) } updateCommonContent(currentState) { copy(customFields = emptyList()) }
} }
composeTestRule.assertScrollableNodeDoesNotExist("Custom fields") composeTestRule.assertScrollableNodeDoesNotExist("CUSTOM FIELDS")
composeTestRule.assertScrollableNodeDoesNotExist("text") composeTestRule.assertScrollableNodeDoesNotExist("text")
composeTestRule.assertScrollableNodeDoesNotExist("value") composeTestRule.assertScrollableNodeDoesNotExist("value")
composeTestRule.assertScrollableNodeDoesNotExist("hidden") composeTestRule.assertScrollableNodeDoesNotExist("hidden")
@ -334,7 +334,7 @@ class VaultItemScreenTest : BaseComposeTest() {
DEFAULT_VIEW_STATES DEFAULT_VIEW_STATES
.forEach { typeState -> .forEach { typeState ->
mutableStateFlow.update { it.copy(viewState = typeState) } mutableStateFlow.update { it.copy(viewState = typeState) }
composeTestRule.onNodeWithTextAfterScroll("Attachments").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("ATTACHMENTS").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("test.mp4").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("test.mp4").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("11 MB").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("11 MB").assertIsDisplayed()
@ -342,7 +342,7 @@ class VaultItemScreenTest : BaseComposeTest() {
updateCommonContent(currentState) { copy(attachments = emptyList()) } updateCommonContent(currentState) { copy(attachments = emptyList()) }
} }
composeTestRule.assertScrollableNodeDoesNotExist("Attachments") composeTestRule.assertScrollableNodeDoesNotExist("ATTACHMENTS")
composeTestRule.assertScrollableNodeDoesNotExist("test.mp4") composeTestRule.assertScrollableNodeDoesNotExist("test.mp4")
composeTestRule.assertScrollableNodeDoesNotExist("11 MB") composeTestRule.assertScrollableNodeDoesNotExist("11 MB")
} }
@ -1706,7 +1706,7 @@ class VaultItemScreenTest : BaseComposeTest() {
@Test @Test
fun `in login state, uris should be displayed according to state`() { fun `in login state, uris should be displayed according to state`() {
mutableStateFlow.update { it.copy(viewState = DEFAULT_LOGIN_VIEW_STATE) } mutableStateFlow.update { it.copy(viewState = DEFAULT_LOGIN_VIEW_STATE) }
composeTestRule.onNodeWithTextAfterScroll("URIs").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("URIS").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("URI").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("URI").assertIsDisplayed()
composeTestRule.onNodeWithTextAfterScroll("www.example.com").assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll("www.example.com").assertIsDisplayed()
@ -1714,7 +1714,7 @@ class VaultItemScreenTest : BaseComposeTest() {
updateLoginType(currentState) { copy(uris = emptyList()) } updateLoginType(currentState) { copy(uris = emptyList()) }
} }
composeTestRule.assertScrollableNodeDoesNotExist("URIs") composeTestRule.assertScrollableNodeDoesNotExist("URIS")
composeTestRule.assertScrollableNodeDoesNotExist("URI") composeTestRule.assertScrollableNodeDoesNotExist("URI")
composeTestRule.assertScrollableNodeDoesNotExist("www.example.com") composeTestRule.assertScrollableNodeDoesNotExist("www.example.com")
} }

View file

@ -4,7 +4,6 @@ import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.filterToOne import androidx.compose.ui.test.filterToOne
import androidx.compose.ui.test.hasAnyAncestor import androidx.compose.ui.test.hasAnyAncestor
import androidx.compose.ui.test.isDialog import androidx.compose.ui.test.isDialog
@ -654,7 +653,7 @@ class VaultItemListingScreenTest : BaseComposeTest() {
@Test @Test
fun `Folders text should be displayed according to state`() { fun `Folders text should be displayed according to state`() {
val folders = "Folders" val folders = "FOLDERS (1)"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = folders) .onNodeWithText(text = folders)
@ -666,7 +665,9 @@ class VaultItemListingScreenTest : BaseComposeTest() {
displayItemList = emptyList(), displayItemList = emptyList(),
displayFolderList = listOf( displayFolderList = listOf(
VaultItemListingState.FolderDisplayItem( VaultItemListingState.FolderDisplayItem(
name = "test", id = "1", count = 0, name = "test",
id = "1",
count = 0,
), ),
), ),
displayCollectionList = emptyList(), displayCollectionList = emptyList(),
@ -680,10 +681,9 @@ class VaultItemListingScreenTest : BaseComposeTest() {
@Test @Test
fun `Folders text count should be displayed according to state`() { fun `Folders text count should be displayed according to state`() {
val folders = "Folders"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = folders) .onNodeWithText(text = "FOLDERS (1)")
.assertDoesNotExist() .assertDoesNotExist()
mutableStateFlow.update { mutableStateFlow.update {
@ -698,9 +698,8 @@ class VaultItemListingScreenTest : BaseComposeTest() {
) )
} }
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(text = folders) .onNodeWithTextAfterScroll(text = "FOLDERS (1)")
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(folders, 1.toString())
mutableStateFlow.update { mutableStateFlow.update {
it.copy( it.copy(
@ -729,9 +728,8 @@ class VaultItemListingScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(text = folders) .onNodeWithTextAfterScroll(text = "FOLDERS (3)")
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(folders, 3.toString())
} }
@Test @Test
@ -778,7 +776,7 @@ class VaultItemListingScreenTest : BaseComposeTest() {
displayFolderList = emptyList(), displayFolderList = emptyList(),
displayCollectionList = listOf( displayCollectionList = listOf(
VaultItemListingState.CollectionDisplayItem( VaultItemListingState.CollectionDisplayItem(
name = "Collection", name = collectionName,
id = "1", id = "1",
count = 0, count = 0,
), ),
@ -793,10 +791,9 @@ class VaultItemListingScreenTest : BaseComposeTest() {
@Test @Test
fun `Collection text count should be displayed according to state`() { fun `Collection text count should be displayed according to state`() {
val collections = "Collections"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = collections) .onNodeWithText(text = "COLLECTIONS (3)")
.assertDoesNotExist() .assertDoesNotExist()
mutableStateFlow.update { mutableStateFlow.update {
@ -825,9 +822,8 @@ class VaultItemListingScreenTest : BaseComposeTest() {
) )
} }
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(text = collections) .onNodeWithTextAfterScroll(text = "COLLECTIONS (3)")
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(collections, 3.toString())
mutableStateFlow.update { mutableStateFlow.update {
it.copy( it.copy(
@ -846,9 +842,8 @@ class VaultItemListingScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(text = collections) .onNodeWithTextAfterScroll(text = "COLLECTIONS (1)")
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(collections, 1.toString())
} }
@Test @Test
@ -882,7 +877,7 @@ class VaultItemListingScreenTest : BaseComposeTest() {
@Test @Test
fun `Items text should be displayed according to state`() { fun `Items text should be displayed according to state`() {
val items = "Items" val items = "ITEMS (1)"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = items) .onNodeWithText(text = items)
@ -906,10 +901,9 @@ class VaultItemListingScreenTest : BaseComposeTest() {
@Test @Test
fun `Items text count should be displayed according to state`() { fun `Items text count should be displayed according to state`() {
val items = "Items"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = items) .onNodeWithText(text = "ITEMS (1)")
.assertDoesNotExist() .assertDoesNotExist()
mutableStateFlow.update { mutableStateFlow.update {
@ -924,9 +918,8 @@ class VaultItemListingScreenTest : BaseComposeTest() {
) )
} }
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(text = items) .onNodeWithTextAfterScroll(text = "ITEMS (1)")
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(items, 1.toString())
mutableStateFlow.update { mutableStateFlow.update {
it.copy( it.copy(
@ -944,9 +937,8 @@ class VaultItemListingScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(text = items) .onNodeWithTextAfterScroll(text = "ITEMS (4)")
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(items, 4.toString())
} }
@Test @Test

View file

@ -742,8 +742,8 @@ class VaultScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNodeWithText("TOTP") .onNodeWithText("TOTP (1)")
.assertTextEquals("TOTP", "1") .performScrollTo()
.assertIsDisplayed() .assertIsDisplayed()
composeTestRule composeTestRule
@ -760,7 +760,7 @@ class VaultScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNodeWithText("TOTP") .onNodeWithText("TOTP (1)")
.assertIsNotDisplayed() .assertIsNotDisplayed()
composeTestRule composeTestRule
@ -805,14 +805,15 @@ class VaultScreenTest : BaseComposeTest() {
) )
} }
composeTestRule.onNode(hasScrollToNodeAction()).performScrollToNode(hasText(itemText))
// Header // Header
composeTestRule composeTestRule
.onNodeWithText("Favorites") .onNodeWithText("FAVORITES (1)")
.assertTextEquals("Favorites", 1.toString()) .performScrollTo()
.assertIsDisplayed()
// Item // Item
composeTestRule composeTestRule
.onNodeWithText(itemText) .onNodeWithText(itemText)
.performScrollTo()
.assertTextEquals(itemText, username) .assertTextEquals(itemText, username)
.performClick() .performClick()
verify { verify {
@ -850,8 +851,7 @@ class VaultScreenTest : BaseComposeTest() {
@Test @Test
fun `collection data should update according to the state`() { fun `collection data should update according to the state`() {
val collectionsHeader = "Collections" val collectionsHeader = "COLLECTIONS (1)"
val collectionsCount = 1
val collectionName = "Test Collection" val collectionName = "Test Collection"
val collectionCount = 3 val collectionCount = 3
val collectionItem = VaultState.ViewState.CollectionItem( val collectionItem = VaultState.ViewState.CollectionItem(
@ -873,7 +873,7 @@ class VaultScreenTest : BaseComposeTest() {
composeTestRule composeTestRule
.onNodeWithTextAfterScroll(collectionsHeader, substring = true) .onNodeWithTextAfterScroll(collectionsHeader, substring = true)
.assertTextEquals(collectionsHeader, collectionsCount.toString()) .assertTextEquals(collectionsHeader)
.assertIsDisplayed() .assertIsDisplayed()
composeTestRule composeTestRule
.onNodeWithText(collectionName) .onNodeWithText(collectionName)
@ -1087,37 +1087,31 @@ class VaultScreenTest : BaseComposeTest() {
mutableStateFlow.update { mutableStateFlow.update {
it.copy(viewState = DEFAULT_CONTENT_VIEW_STATE) it.copy(viewState = DEFAULT_CONTENT_VIEW_STATE)
} }
composeTestRule.onNode(hasScrollToNodeAction()).performScrollToNode(hasText(rowText))
// Header // Header
composeTestRule composeTestRule
.onAllNodes(hasText(rowText)) .onNodeWithTextAfterScroll(text = "TRASH (1)")
.filterToOne(!hasClickAction()) .assertIsDisplayed()
.assertTextEquals(rowText, 1.toString())
// Item // Item
composeTestRule composeTestRule
.onAllNodes(hasText(rowText)) .onNodeWithTextAfterScroll(rowText)
.filterToOne(hasClickAction())
.assertTextEquals(rowText, 0.toString()) .assertTextEquals(rowText, 0.toString())
val trashCount = 5 val trashCount = 5
mutableStateFlow.update { mutableStateFlow.update {
it.copy( it.copy(
viewState = DEFAULT_CONTENT_VIEW_STATE.copy( viewState = DEFAULT_CONTENT_VIEW_STATE.copy(
trashItemsCount = 5, trashItemsCount = trashCount,
), ),
) )
} }
composeTestRule.onNode(hasScrollToNodeAction()).performScrollToNode(hasText(rowText))
// Header // Header
composeTestRule composeTestRule
.onAllNodes(hasText(rowText)) .onNodeWithTextAfterScroll(text = "TRASH (1)")
.filterToOne(!hasClickAction()) .assertIsDisplayed()
.assertTextEquals(rowText, 1.toString())
// Item // Item
composeTestRule composeTestRule
.onAllNodes(hasText(rowText)) .onNodeWithTextAfterScroll(rowText)
.filterToOne(hasClickAction())
.assertTextEquals(rowText, trashCount.toString()) .assertTextEquals(rowText, trashCount.toString())
} }

View file

@ -3,11 +3,8 @@ package com.x8bit.bitwarden.ui.vault.feature.verificationcode
import androidx.compose.ui.test.assert import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.filterToOne import androidx.compose.ui.test.filterToOne
import androidx.compose.ui.test.hasAnyAncestor import androidx.compose.ui.test.hasAnyAncestor
import androidx.compose.ui.test.hasScrollToNodeAction
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isDialog import androidx.compose.ui.test.isDialog
import androidx.compose.ui.test.isDisplayed import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.isPopup import androidx.compose.ui.test.isPopup
@ -15,7 +12,7 @@ import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToNode import androidx.compose.ui.test.performScrollTo
import com.x8bit.bitwarden.data.platform.repository.model.Environment import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.data.platform.repository.util.baseIconUrl import com.x8bit.bitwarden.data.platform.repository.util.baseIconUrl
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
@ -174,11 +171,10 @@ class VerificationCodeScreenTest : BaseComposeTest() {
@Test @Test
fun `Items text should be displayed according to state`() { fun `Items text should be displayed according to state`() {
val items = "Items"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = items) .onNodeWithText(text = "ITEMS (2)")
.assertDoesNotExist() .assertDoesNotExist()
mutableStateFlow.update { mutableStateFlow.update {
@ -193,20 +189,16 @@ class VerificationCodeScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNode(hasScrollToNodeAction()) .onNodeWithText(text = "ITEMS (2)")
.performScrollToNode(hasText(items)) .performScrollTo()
composeTestRule
.onNodeWithText(text = items)
.assertIsDisplayed() .assertIsDisplayed()
} }
@Test @Test
fun `Items text count should be displayed according to state`() { fun `Items text count should be displayed according to state`() {
val items = "Items"
mutableStateFlow.update { DEFAULT_STATE } mutableStateFlow.update { DEFAULT_STATE }
composeTestRule composeTestRule
.onNodeWithText(text = items) .onNodeWithText(text = "ITEMS (1)")
.assertDoesNotExist() .assertDoesNotExist()
mutableStateFlow.update { mutableStateFlow.update {
@ -220,13 +212,9 @@ class VerificationCodeScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNode(hasScrollToNodeAction()) .onNodeWithText(text = "ITEMS (1)")
.performScrollToNode(hasText(items)) .performScrollTo()
composeTestRule
.onNodeWithText(text = items)
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(items, "1")
mutableStateFlow.update { mutableStateFlow.update {
it.copy( it.copy(
@ -242,13 +230,9 @@ class VerificationCodeScreenTest : BaseComposeTest() {
} }
composeTestRule composeTestRule
.onNode(hasScrollToNodeAction()) .onNodeWithText(text = "ITEMS (4)")
.performScrollToNode(hasText(items)) .performScrollTo()
composeTestRule
.onNodeWithText(text = items)
.assertIsDisplayed() .assertIsDisplayed()
.assertTextEquals(items, "4")
} }
@Test @Test
@ -263,10 +247,6 @@ class VerificationCodeScreenTest : BaseComposeTest() {
) )
} }
composeTestRule
.onNodeWithText(text = "1")
.assertIsDisplayed()
composeTestRule composeTestRule
.onNodeWithText(text = "Label 1") .onNodeWithText(text = "Label 1")
.assertIsDisplayed() .assertIsDisplayed()