Open myxzlpltk opened 1 year ago
@myxzlpltk Thanks for reaching out! Do you mind sharing your code for the UI (the part being tested by the test script) ?
Here is the UI
form(SignInForm::class) {
field(SignInForm::email) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.testTag("EmailField"),
value = this.state.value?.value.orEmpty(),
onValueChange = {
Timber.d("Email changed: $it")
this.setField(it)
},
isError = resultState.value is FieldResult.Error,
supportingText = {
if (resultState.value is FieldResult.Error) {
Text(text = stringResource(R.string.email_error))
}
},
label = {
Text(text = stringResource(R.string.email_address))
},
placeholder = {
Text(text = stringResource(R.string.email_hint))
},
leadingIcon = {
Icon(imageVector = Icons.Filled.Email, contentDescription = stringResource(R.string.email_address))
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next,
),
keyboardActions = KeyboardActions(
onNext = { focusManager.moveFocus(FocusDirection.Down) }
)
)
}
field(SignInForm::password) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.testTag("PasswordField"),
value = this.state.value?.value.orEmpty(),
onValueChange = this::setField,
isError = resultState.value is FieldResult.Error,
supportingText = {
if (resultState.value is FieldResult.Error) {
Text(text = stringResource(R.string.password_error))
}
},
label = {
Text(text = stringResource(R.string.password))
},
placeholder = {
Text(text = stringResource(R.string.password_hint))
},
leadingIcon = {
Icon(imageVector = Icons.Filled.Lock, contentDescription = stringResource(R.string.password))
},
visualTransformation = if (state.isPasswordVisible) {
VisualTransformation.None
} else {
PasswordVisualTransformation()
},
trailingIcon = {
IconToggleButton(
checked = state.isPasswordVisible,
onCheckedChange = actions.setPasswordVisibility,
) {
Icon(
imageVector = if (state.isPasswordVisible) {
Icons.Filled.Visibility
} else {
Icons.Filled.VisibilityOff
},
contentDescription = stringResource(R.string.toggle_password_visibility),
)
}
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Done,
),
keyboardActions = KeyboardActions(
onDone = { focusManager.clearFocus() }
)
)
}
Spacer(modifier = Modifier.height(8.dp))
TextButton(
onClick = actions.navigateToForgotPassword,
modifier = Modifier.align(Alignment.End)
) {
Text(text = stringResource(R.string.forgot_password_question))
}
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = actions.navigateToDashboard,
modifier = Modifier
.fillMaxWidth()
.testTag("SignInButton"),
enabled = this.formState.value is FormResult.Success
) {
Text(text = stringResource(R.string.sign_in))
}
}
Hi can you replicate my problem? It's like the library validate previous form state.
rule.onNode(signInButton).assertIsNotEnabled()
rule.onNode(emailField).assertIsNotFocused()
rule.onNode(emailField).performClick()
rule.onNode(emailField).performTextInput("test@gmail.com")
rule.onNode(emailField).performImeAction()
rule.onNode(signInButton).assertIsNotEnabled()
rule.onNode(passwordField).assertIsFocused()
rule.onNode(passwordField).performTextInput("password")
rule.onNode(passwordField).performTextReplacement("") // empty string
rule.onNode(passwordField).performImeAction()
rule.onNode(signInButton).assertIsEnabled() // Success
if i debug it the formState.value it will be FormResult.Success("test@gmail.com", "")
while this should be illegal because the password shouldn't be empty
Please check this minimal, reproducible project with UI test (check androidTest folder) https://github.com/myxzlpltk/FormConductorUITest
I'm a beginner in android compose. I don't know what went wrong in my code. The button won't enabled during UI test but working during manual testing.
Please advise. Thank you
Edit: I think i know the problem. Compose isn't recompose yet during check assertIsEnabled. But still didn't understand how to fix it