mirror of
https://github.com/bitwarden/android.git
synced 2026-03-21 22:00:42 -05:00
PM-15147 - Design Audit - Master Password Guidance Screen (#4383)
This commit is contained in:
@@ -46,6 +46,7 @@ import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
|
||||
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTextButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.card.BitwardenActionCardSmall
|
||||
import com.x8bit.bitwarden.ui.platform.components.card.color.bitwardenCardColors
|
||||
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenBasicDialog
|
||||
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenLoadingDialog
|
||||
import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenTwoButtonDialog
|
||||
@@ -211,6 +212,10 @@ private fun CompleteRegistrationContent(
|
||||
actionIcon = rememberVectorPainter(id = R.drawable.ic_question_circle),
|
||||
actionText = stringResource(id = R.string.what_makes_a_password_strong),
|
||||
callToActionText = stringResource(id = R.string.learn_more),
|
||||
callToActionTextColor = BitwardenTheme.colorScheme.text.interaction,
|
||||
colors = bitwardenCardColors(
|
||||
containerColor = BitwardenTheme.colorScheme.background.primary,
|
||||
),
|
||||
onCardClicked = handler.onMakeStrongPassword,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
||||
@@ -1,52 +1,46 @@
|
||||
package com.x8bit.bitwarden.ui.auth.feature.masterpasswordguidance
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.bitwardenBoldSpanStyle
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.createAnnotatedString
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
|
||||
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
|
||||
import com.x8bit.bitwarden.ui.platform.components.card.BitwardenActionCardSmall
|
||||
import com.x8bit.bitwarden.ui.platform.components.divider.BitwardenHorizontalDivider
|
||||
import com.x8bit.bitwarden.ui.platform.components.card.BitwardenActionCard
|
||||
import com.x8bit.bitwarden.ui.platform.components.card.BitwardenContentCard
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.ContentBlockData
|
||||
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
private const val BULLET_TWO_TAB = "\u2022\t\t"
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
* The top level composable for the Master Password Guidance screen.
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun MasterPasswordGuidanceScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
@@ -81,126 +75,126 @@ fun MasterPasswordGuidanceScreen(
|
||||
)
|
||||
},
|
||||
) {
|
||||
Column(
|
||||
MasterPasswordGuidanceContent(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.standardHorizontalMargin(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(size = 4.dp))
|
||||
.background(BitwardenTheme.colorScheme.background.tertiary),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(all = 24.dp),
|
||||
) {
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.what_makes_a_password_strong),
|
||||
style = BitwardenTheme.typography.titleMedium,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
style = BitwardenTheme.typography.bodyMedium,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
text = stringResource(
|
||||
R.string.the_longer_your_password_the_more_difficult_to_hack,
|
||||
),
|
||||
)
|
||||
}
|
||||
BitwardenHorizontalDivider()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.the_strongest_passwords_are_usually),
|
||||
style = BitwardenTheme.typography.titleSmall,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BulletTextRow(text = stringResource(R.string.twelve_or_more_characters))
|
||||
BulletTextRow(
|
||||
text = stringResource(
|
||||
R.string.random_and_complex_using_numbers_and_special_characters,
|
||||
),
|
||||
)
|
||||
BulletTextRow(
|
||||
text = stringResource(R.string.totally_different_from_your_other_passwords),
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
TryGeneratorCard(
|
||||
onCardClicked = remember(viewModel) {
|
||||
{
|
||||
viewModel.trySendAction(
|
||||
MasterPasswordGuidanceAction.TryPasswordGeneratorAction,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
}
|
||||
onTryPasswordGeneratorAction = {
|
||||
viewModel.trySendAction(
|
||||
MasterPasswordGuidanceAction.TryPasswordGeneratorAction,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TryGeneratorCard(
|
||||
onCardClicked: () -> Unit,
|
||||
private fun MasterPasswordGuidanceContent(
|
||||
modifier: Modifier = Modifier,
|
||||
onTryPasswordGeneratorAction: () -> Unit,
|
||||
) {
|
||||
BitwardenActionCardSmall(
|
||||
actionIcon = rememberVectorPainter(id = R.drawable.ic_generate),
|
||||
actionText = stringResource(
|
||||
R.string.use_the_generator_to_create_a_strong_unique_password,
|
||||
),
|
||||
callToActionText = stringResource(R.string.try_it_out),
|
||||
onCardClicked = onCardClicked,
|
||||
modifier = modifier
|
||||
.fillMaxWidth(),
|
||||
trailingContent = {
|
||||
Icon(
|
||||
painter = rememberVectorPainter(id = R.drawable.ic_chevron_right),
|
||||
contentDescription = null,
|
||||
tint = BitwardenTheme.colorScheme.icon.primary,
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(16.dp),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BulletTextRow(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 8.dp),
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Text(
|
||||
text = BULLET_TWO_TAB,
|
||||
text = stringResource(R.string.a_secure_memorable_password),
|
||||
textAlign = TextAlign.Center,
|
||||
style = BitwardenTheme.typography.titleMedium,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.one_of_the_best_ways_to_create_a_secure_and_memorable_password,
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
style = BitwardenTheme.typography.bodyMedium,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
modifier = Modifier.clearAndSetSemantics { },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Text(
|
||||
text = text,
|
||||
style = BitwardenTheme.typography.bodyMedium,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
MasterPasswordGuidanceContentBlocks()
|
||||
NeedSomeInspirationCard(
|
||||
onActionClicked = {
|
||||
onTryPasswordGeneratorAction()
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MasterPasswordGuidanceContentBlocks(modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
BitwardenContentCard(
|
||||
contentItems = persistentListOf(
|
||||
ContentBlockData(
|
||||
headerText = stringResource(R.string.choose_three_or_four_random_words)
|
||||
.toAnnotatedString(),
|
||||
subtitleText = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
R.string.pick_three_or_four_random_unrelated_words,
|
||||
),
|
||||
highlights = listOf(
|
||||
stringResource(
|
||||
R.string.pick_three_or_four_random_unrelated_words_highlight,
|
||||
),
|
||||
),
|
||||
highlightStyle = bitwardenBoldSpanStyle,
|
||||
),
|
||||
iconVectorResource = R.drawable.ic_number1,
|
||||
),
|
||||
ContentBlockData(
|
||||
headerText = stringResource(R.string.combine_those_words_together)
|
||||
.toAnnotatedString(),
|
||||
subtitleText = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
R.string.put_the_words_together_in_any_order_to_form_your_passphrase,
|
||||
),
|
||||
highlights = listOf(
|
||||
stringResource(
|
||||
R.string.use_hyphens_spaces_or_leave_them_as_long_word_highlight,
|
||||
),
|
||||
),
|
||||
highlightStyle = bitwardenBoldSpanStyle,
|
||||
),
|
||||
iconVectorResource = R.drawable.ic_number2,
|
||||
),
|
||||
ContentBlockData(
|
||||
headerText = stringResource(R.string.make_it_yours).toAnnotatedString(),
|
||||
subtitleText = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
R.string.add_a_number_or_symbol_to_make_it_even_stronger,
|
||||
),
|
||||
highlights = listOf(
|
||||
stringResource(R.string.add_a_number_or_symbol_highlight),
|
||||
),
|
||||
highlightStyle = bitwardenBoldSpanStyle,
|
||||
),
|
||||
iconVectorResource = R.drawable.ic_number3,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NeedSomeInspirationCard(
|
||||
onActionClicked: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
BitwardenActionCard(
|
||||
cardTitle = stringResource(R.string.need_some_inspiration),
|
||||
actionText = stringResource(R.string.check_out_the_passphrase_generator),
|
||||
onActionClick = onActionClicked,
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
|
||||
@@ -35,7 +35,7 @@ import kotlin.let
|
||||
* @param cardTitle The title of the card.
|
||||
* @param actionText The text content on the CTA button.
|
||||
* @param onActionClick The action to perform when the CTA button is clicked.
|
||||
* @param onDismissClick The action to perform when the dismiss button is clicked.
|
||||
* @param onDismissClick Optional action to perform when the dismiss button is clicked.
|
||||
* @param leadingContent Optional content to display on the leading side of the
|
||||
* [cardTitle] [Text].
|
||||
*/
|
||||
@@ -44,8 +44,8 @@ fun BitwardenActionCard(
|
||||
cardTitle: String,
|
||||
actionText: String,
|
||||
onActionClick: () -> Unit,
|
||||
onDismissClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onDismissClick: (() -> Unit)? = null,
|
||||
cardSubtitle: String? = null,
|
||||
leadingContent: @Composable (() -> Unit)? = null,
|
||||
) {
|
||||
@@ -69,11 +69,13 @@ fun BitwardenActionCard(
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
BitwardenStandardIconButton(
|
||||
painter = rememberVectorPainter(id = R.drawable.ic_close),
|
||||
contentDescription = stringResource(id = R.string.close),
|
||||
onClick = onDismissClick,
|
||||
)
|
||||
onDismissClick?.let {
|
||||
BitwardenStandardIconButton(
|
||||
painter = rememberVectorPainter(id = R.drawable.ic_close),
|
||||
contentDescription = stringResource(id = R.string.close),
|
||||
onClick = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
cardSubtitle?.let {
|
||||
Spacer(Modifier.height(4.dp))
|
||||
@@ -103,6 +105,19 @@ fun BitwardenActionCard(
|
||||
*/
|
||||
fun actionCardExitAnimation() = fadeOut() + shrinkVertically(shrinkTowards = Alignment.Top)
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun BitwardenActionCardWithSubtitleNoDismiss_preview() {
|
||||
BitwardenTheme {
|
||||
BitwardenActionCard(
|
||||
cardTitle = "Title",
|
||||
actionText = "Action",
|
||||
onActionClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
|
||||
@@ -12,12 +12,14 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardColors
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.VectorPainter
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -34,6 +36,8 @@ fun BitwardenActionCardSmall(
|
||||
actionIcon: VectorPainter,
|
||||
actionText: String,
|
||||
callToActionText: String,
|
||||
callToActionTextColor: Color = BitwardenTheme.colorScheme.text.primary,
|
||||
colors: CardColors = bitwardenCardColors(),
|
||||
onCardClicked: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
trailingContent: (@Composable BoxScope.() -> Unit)? = null,
|
||||
@@ -42,7 +46,7 @@ fun BitwardenActionCardSmall(
|
||||
onClick = onCardClicked,
|
||||
shape = BitwardenTheme.shapes.actionCard,
|
||||
modifier = modifier,
|
||||
colors = bitwardenCardColors(),
|
||||
colors = colors,
|
||||
elevation = CardDefaults.elevatedCardElevation(),
|
||||
border = BorderStroke(width = 1.dp, color = BitwardenTheme.colorScheme.stroke.border),
|
||||
) {
|
||||
@@ -70,7 +74,7 @@ fun BitwardenActionCardSmall(
|
||||
Text(
|
||||
text = callToActionText,
|
||||
style = BitwardenTheme.typography.labelLarge,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
color = callToActionTextColor,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
|
||||
@@ -2,15 +2,23 @@ package com.x8bit.bitwarden.ui.platform.components.card.color
|
||||
|
||||
import androidx.compose.material3.CardColors
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
/**
|
||||
* Provides a default set of Bitwarden-styled colors for a card.
|
||||
*/
|
||||
@Composable
|
||||
fun bitwardenCardColors(): CardColors = CardColors(
|
||||
containerColor = BitwardenTheme.colorScheme.background.tertiary,
|
||||
contentColor = BitwardenTheme.colorScheme.text.primary,
|
||||
disabledContainerColor = BitwardenTheme.colorScheme.filledButton.backgroundDisabled,
|
||||
disabledContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled,
|
||||
)
|
||||
fun bitwardenCardColors(
|
||||
containerColor: Color = BitwardenTheme.colorScheme.background.tertiary,
|
||||
contentColor: Color = BitwardenTheme.colorScheme.text.primary,
|
||||
disabledContainerColor: Color = BitwardenTheme.colorScheme.filledButton.backgroundDisabled,
|
||||
disabledContentColor: Color = BitwardenTheme.colorScheme.filledButton.foregroundDisabled,
|
||||
): CardColors {
|
||||
return CardColors(
|
||||
containerColor = containerColor,
|
||||
contentColor = contentColor,
|
||||
disabledContainerColor = disabledContainerColor,
|
||||
disabledContentColor = disabledContentColor,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -962,6 +962,7 @@ Do you want to switch to this account?</string>
|
||||
<string name="remove_passkey">Remove passkey</string>
|
||||
<string name="passkey_removed">Passkey removed</string>
|
||||
<string name="what_makes_a_password_strong">What makes a password strong?</string>
|
||||
<string name="a_secure_memorable_password">A secure, memorable password</string>
|
||||
<string name="the_longer_your_password_the_more_difficult_to_hack">The longer your password, the more difficult it is to hack. The minimum for account creation is 12 characters but if you do 14 characters, the time to crack your password would be centuries!</string>
|
||||
<string name="the_strongest_passwords_are_usually">The strongest passwords are usually:</string>
|
||||
<string name="twelve_or_more_characters">12 or more characters</string>
|
||||
@@ -978,6 +979,7 @@ Do you want to switch to this account?</string>
|
||||
<string name="set_up_biometrics_or_choose_a_pin_code_to_quickly_access_your_vault_and_autofill_your_logins">Set up biometrics or choose a PIN code to quickly access your vault and AutoFill your logins.</string>
|
||||
<string name="never_lose_access_to_your_vault">Never lose access to your vault</string>
|
||||
<string name="the_best_way_to_make_sure_you_can_always_access_your_account">The best way to make sure you can always access your account is to set up safeguards from the start.</string>
|
||||
<string name="one_of_the_best_ways_to_create_a_secure_and_memorable_password">One of the best ways to create a secure and memorable password is to use a passphrase. \nHere’s how:</string>
|
||||
<string name="create_a_hint">Create a hint</string>
|
||||
<string name="your_hint_will_be_send_to_you_via_email_when_you_request_it">Your hint will be sent to you via email when you request it.</string>
|
||||
<string name="write_your_password_down">Write your password down</string>
|
||||
@@ -1099,4 +1101,15 @@ Do you want to switch to this account?</string>
|
||||
<string name="biometrics_no_longer_supported">You’ve been logged out because your device’s biometrics don’t meet the latest security requirements. To update settings, log in once again or contact your administrator for access.</string>
|
||||
<string name="cxp_import">CXP Import</string>
|
||||
<string name="cxp_export">CXP Export</string>
|
||||
<string name="choose_three_or_four_random_words">Choose three or four random words</string>
|
||||
<string name="pick_three_or_four_random_unrelated_words">Pick three or four random, unrelated words that you can easily remember. Think of objects, places, or things you like.</string>
|
||||
<string name="pick_three_or_four_random_unrelated_words_highlight">objects, places, or things</string>
|
||||
<string name="combine_those_words_together">Combine those words together</string>
|
||||
<string name="put_the_words_together_in_any_order_to_form_your_passphrase">Put the words together in any order to form your passphrase. Use hyphens, spaces, or leave them as one long word—your choice!</string>
|
||||
<string name="use_hyphens_spaces_or_leave_them_as_long_word_highlight">Use hyphens, spaces, or leave them as one long word</string>
|
||||
<string name="make_it_yours">Make it yours</string>
|
||||
<string name="add_a_number_or_symbol_to_make_it_even_stronger">Add a number or symbol to make it even stronger. Now you have a unique, secure, and memorable passphrase!</string>
|
||||
<string name="add_a_number_or_symbol_highlight">Add a number or symbol</string>
|
||||
<string name="need_some_inspiration">"Need some inspiration?"</string>
|
||||
<string name="check_out_the_passphrase_generator">"Check out the passphrase generator"</string>
|
||||
</resources>
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.auth.feature.masterpasswordguidance
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performScrollTo
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import io.mockk.every
|
||||
@@ -45,7 +46,8 @@ class MasterPasswordGuidanceScreenTest : BaseComposeTest() {
|
||||
@Test
|
||||
fun `Generator card click should invoke send of TryPasswordGeneratorAction`() {
|
||||
composeTestRule
|
||||
.onNodeWithText("Use the generator to create a strong, unique password")
|
||||
.onNodeWithText("Check out the passphrase generator")
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
||||
verify { viewModel.trySendAction(MasterPasswordGuidanceAction.TryPasswordGeneratorAction) }
|
||||
|
||||
Reference in New Issue
Block a user