From a7c27d96936caf16037fb6af97c21dd8223a28a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20G=C3=B6ransson?= Date: Thu, 12 Oct 2023 09:56:52 +0200 Subject: [PATCH] Fix login uiautomator flakiness --- .../mullvad/mullvadvpn/compose/screen/LoginScreen.kt | 11 ++++++++++- .../compose/test/ComposeTestTagConstants.kt | 2 ++ .../mullvadvpn/test/mockapi/LoginMockApiTest.kt | 11 ++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt index 388963866f1c..823e4f42265c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt @@ -43,8 +43,11 @@ import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType @@ -57,6 +60,7 @@ import net.mullvad.mullvadvpn.compose.state.LoginError import net.mullvad.mullvadvpn.compose.state.LoginState import net.mullvad.mullvadvpn.compose.state.LoginState.* import net.mullvad.mullvadvpn.compose.state.LoginUiState +import net.mullvad.mullvadvpn.compose.test.LOGIN_TITLE_TEST_TAG import net.mullvad.mullvadvpn.compose.textfield.mullvadWhiteTextFieldColors import net.mullvad.mullvadvpn.compose.util.accountTokenVisualTransformation import net.mullvad.mullvadvpn.lib.theme.AlphaTopBar @@ -95,6 +99,7 @@ private fun PreviewLoginSuccess() { AppTheme { LoginScreen(uiState = LoginUiState(loginState = Success)) } } +@OptIn(ExperimentalComposeUiApi::class) @Composable fun LoginScreen( uiState: LoginUiState, @@ -105,6 +110,7 @@ fun LoginScreen( onSettingsClick: () -> Unit = {}, ) { ScaffoldWithTopBar( + modifier = Modifier.semantics { testTagsAsResourceId = true }, topBarColor = MaterialTheme.colorScheme.primary, statusBarColor = MaterialTheme.colorScheme.primary, navigationBarColor = MaterialTheme.colorScheme.background, @@ -147,7 +153,10 @@ private fun LoginContent( text = uiState.loginState.title(), style = MaterialTheme.typography.headlineLarge, color = MaterialTheme.colorScheme.onPrimary, - modifier = Modifier.fillMaxWidth().padding(bottom = Dimens.smallPadding) + modifier = + Modifier.testTag(LOGIN_TITLE_TEST_TAG) + .fillMaxWidth() + .padding(bottom = Dimens.smallPadding) ) var tfFocusState: FocusState? by remember { mutableStateOf(null) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt index b6c9169ab475..3cf06f201bc3 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt @@ -24,3 +24,5 @@ const val LOCATION_INFO_TEST_TAG = "location_info_test_tag" // ConnectScreen - Notification banner const val NOTIFICATION_BANNER = "notification_banner" + +const val LOGIN_TITLE_TEST_TAG = "login_title_test_tag" diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/LoginMockApiTest.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/LoginMockApiTest.kt index 6068ffbf4ccf..9654be575c4d 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/LoginMockApiTest.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/LoginMockApiTest.kt @@ -2,10 +2,14 @@ package net.mullvad.mullvadvpn.test.mockapi import androidx.test.runner.AndroidJUnit4 import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until +import net.mullvad.mullvadvpn.compose.test.LOGIN_TITLE_TEST_TAG +import net.mullvad.mullvadvpn.test.common.constant.DEFAULT_INTERACTION_TIMEOUT import net.mullvad.mullvadvpn.test.common.extension.clickAgreeOnPrivacyDisclaimer import net.mullvad.mullvadvpn.test.common.extension.clickAllowOnNotificationPermissionPromptIfApiLevel33AndAbove import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout import net.mullvad.mullvadvpn.test.mockapi.util.currentUtcTimeWithOffsetZero +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith @@ -28,7 +32,12 @@ class LoginMockApiTest : MockApiTest() { app.attemptLogin(validAccountToken) // Assert - device.findObjectWithTimeout(By.text("Login failed")) + val result = + device + .findObject(By.res(LOGIN_TITLE_TEST_TAG)) + .wait(Until.textEquals("Login failed"), DEFAULT_INTERACTION_TIMEOUT) + + assertTrue(result) } @Test