summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-07-11 16:07:50 +0200
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-07-14 11:11:19 +0200
commitb82f65d4b19f4e534cdd69e8ead7f79aa176c6b2 (patch)
tree4d3b43e32de8277d3f2eb3ae43e2cf8a4be4a041 /android
parentc3f986e4ca32c345ae02715302a5f3c7279509b0 (diff)
downloadmullvadvpn-b82f65d4b19f4e534cdd69e8ead7f79aa176c6b2.tar.xz
mullvadvpn-b82f65d4b19f4e534cdd69e8ead7f79aa176c6b2.zip
Add ConnectScreen instrumental tests
Diffstat (limited to 'android')
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt581
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt23
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt8
4 files changed, 621 insertions, 11 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt
new file mode 100644
index 0000000000..48671136e0
--- /dev/null
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt
@@ -0,0 +1,581 @@
+package net.mullvad.mullvadvpn.compose.screen
+
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import io.mockk.verify
+import net.mullvad.mullvadvpn.compose.state.ConnectUiState
+import net.mullvad.mullvadvpn.compose.test.CIRCULAR_PROGRESS_INDICATOR
+import net.mullvad.mullvadvpn.compose.test.CONNECT_BUTTON_TEST_TAG
+import net.mullvad.mullvadvpn.compose.test.LOCATION_INFO_TEST_TAG
+import net.mullvad.mullvadvpn.compose.test.RECONNECT_BUTTON_TEST_TAG
+import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_BUTTON_TEST_TAG
+import net.mullvad.mullvadvpn.model.GeoIpLocation
+import net.mullvad.mullvadvpn.model.TunnelState
+import net.mullvad.mullvadvpn.relaylist.RelayItem
+import net.mullvad.talpid.net.TransportProtocol
+import net.mullvad.talpid.net.TunnelEndpoint
+import net.mullvad.talpid.tunnel.ActionAfterDisconnect
+import net.mullvad.talpid.tunnel.ErrorState
+import net.mullvad.talpid.tunnel.ErrorStateCause
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class ConnectScreenTest {
+ @get:Rule val composeTestRule = createComposeRule()
+
+ @Before
+ fun setup() {
+ MockKAnnotations.init(this)
+ }
+
+ @After
+ fun teardown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun testDefaultState() {
+ // Arrange
+ composeTestRule.setContent { ConnectScreen(uiState = ConnectUiState.INITIAL) }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("UNSECURED CONNECTION").assertExists()
+ onNodeWithText("Secure my connection").assertExists()
+ }
+ }
+
+ @Test
+ fun testConnectingState() {
+ // Arrange
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connecting(null, null),
+ tunnelRealState = TunnelState.Connecting(null, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
+ onNodeWithText("CREATING SECURE CONNECTION").assertExists()
+ onNodeWithText("Switch location").assertExists()
+ onNodeWithText("Cancel").assertExists()
+ }
+ }
+
+ @Test
+ fun testConnectingStateQuantumSecured() {
+ // Arrange
+ val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
+ every { mockTunnelEndpoint.quantumResistant } returns true
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connecting(endpoint = mockTunnelEndpoint, null),
+ tunnelRealState =
+ TunnelState.Connecting(endpoint = mockTunnelEndpoint, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
+ onNodeWithText("CREATING QUANTUM SECURE CONNECTION").assertExists()
+ onNodeWithText("Switch location").assertExists()
+ onNodeWithText("Cancel").assertExists()
+ }
+ }
+
+ @Test
+ fun testConnectedState() {
+ // Arrange
+ val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connected(mockTunnelEndpoint, null),
+ tunnelRealState = TunnelState.Connected(mockTunnelEndpoint, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("SECURE CONNECTION").assertExists()
+ onNodeWithText("Switch location").assertExists()
+ onNodeWithText("Disconnect").assertExists()
+ }
+ }
+
+ @Test
+ fun testConnectedStateQuantumSecured() {
+ // Arrange
+ val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
+ every { mockTunnelEndpoint.quantumResistant } returns true
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connected(mockTunnelEndpoint, null),
+ tunnelRealState = TunnelState.Connected(mockTunnelEndpoint, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("QUANTUM SECURE CONNECTION").assertExists()
+ onNodeWithText("Switch location").assertExists()
+ onNodeWithText("Disconnect").assertExists()
+ }
+ }
+
+ @Test
+ fun testDisconnectingState() {
+ // Arrange
+ val mockRelayLocation: RelayItem = mockk(relaxed = true)
+ val mockLocationName = "Home"
+ every { mockRelayLocation.locationName } returns mockLocationName
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = mockRelayLocation,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Disconnecting(ActionAfterDisconnect.Nothing),
+ tunnelRealState = TunnelState.Disconnecting(ActionAfterDisconnect.Nothing),
+ inAddress = null,
+ outAddress = "",
+ showLocation = true,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("UNSECURED CONNECTION").assertExists()
+ onNodeWithText(mockLocationName).assertExists()
+ onNodeWithText("Secure my connection").assertExists()
+ }
+ }
+
+ @Test
+ fun testDisconnectedState() {
+ // Arrange
+ val mockRelayLocation: RelayItem = mockk(relaxed = true)
+ val mockLocationName = "Home"
+ every { mockRelayLocation.locationName } returns mockLocationName
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = mockRelayLocation,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Disconnected,
+ tunnelRealState = TunnelState.Disconnected,
+ inAddress = null,
+ outAddress = "",
+ showLocation = true,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("UNSECURED CONNECTION").assertExists()
+ onNodeWithText(mockLocationName).assertExists()
+ onNodeWithText("Secure my connection").assertExists()
+ }
+ }
+
+ @Test
+ fun testErrorStateBlocked() {
+ // Arrange
+ val mockRelayLocation: RelayItem = mockk(relaxed = true)
+ val mockLocationName = "Home"
+ every { mockRelayLocation.locationName } returns mockLocationName
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = mockRelayLocation,
+ versionInfo = null,
+ tunnelUiState =
+ TunnelState.Error(ErrorState(ErrorStateCause.StartTunnelError, true)),
+ tunnelRealState =
+ TunnelState.Error(ErrorState(ErrorStateCause.StartTunnelError, true)),
+ inAddress = null,
+ outAddress = "",
+ showLocation = true,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("BLOCKED CONNECTION").assertExists()
+ onNodeWithText(mockLocationName).assertExists()
+ onNodeWithText("Disconnect").assertExists()
+ }
+ }
+
+ @Test
+ fun testErrorStateNotBlocked() {
+ // Arrange
+ val mockRelayLocation: RelayItem = mockk(relaxed = true)
+ val mockLocationName = "Home"
+ every { mockRelayLocation.locationName } returns mockLocationName
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = mockRelayLocation,
+ versionInfo = null,
+ tunnelUiState =
+ TunnelState.Error(ErrorState(ErrorStateCause.StartTunnelError, false)),
+ tunnelRealState =
+ TunnelState.Error(ErrorState(ErrorStateCause.StartTunnelError, false)),
+ inAddress = null,
+ outAddress = "",
+ showLocation = true,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("FAILED TO SECURE CONNECTION").assertExists()
+ onNodeWithText(mockLocationName).assertExists()
+ onNodeWithText("Dismiss").assertExists()
+ }
+ }
+
+ @Test
+ fun testReconnectingState() {
+ // Arrange
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Disconnecting(ActionAfterDisconnect.Reconnect),
+ tunnelRealState =
+ TunnelState.Disconnecting(ActionAfterDisconnect.Reconnect),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
+ onNodeWithText("CREATING SECURE CONNECTION").assertExists()
+ onNodeWithText("Switch location").assertExists()
+ onNodeWithText("Disconnect").assertExists()
+ }
+ }
+
+ @Test
+ fun testDisconnectingBlockState() {
+ // Arrange
+ val mockRelayLocation: RelayItem = mockk(relaxed = true)
+ val mockLocationName = "Home"
+ every { mockRelayLocation.locationName } returns mockLocationName
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = mockRelayLocation,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Disconnecting(ActionAfterDisconnect.Block),
+ tunnelRealState = TunnelState.Disconnecting(ActionAfterDisconnect.Block),
+ inAddress = null,
+ outAddress = "",
+ showLocation = true,
+ isTunnelInfoExpanded = false
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText("SECURE CONNECTION").assertExists()
+ onNodeWithText(mockLocationName).assertExists()
+ onNodeWithText("Disconnect").assertExists()
+ }
+ }
+
+ @Test
+ fun testClickSelectLocationButton() {
+ // Arrange
+ val mockRelayLocation: RelayItem = mockk(relaxed = true)
+ val mockLocationName = "Home"
+ every { mockRelayLocation.locationName } returns mockLocationName
+ val mockedClickHandler: () -> Unit = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = mockRelayLocation,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Disconnected,
+ tunnelRealState = TunnelState.Disconnected,
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ ),
+ onSwitchLocationClick = mockedClickHandler
+ )
+ }
+
+ // Act
+ composeTestRule.onNodeWithTag(SELECT_LOCATION_BUTTON_TEST_TAG).performClick()
+
+ // Assert
+ verify { mockedClickHandler.invoke() }
+ }
+
+ @Test
+ fun testOnDisconnectClick() {
+ // Arrange
+ val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
+ val mockedClickHandler: () -> Unit = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connected(mockTunnelEndpoint, null),
+ tunnelRealState = TunnelState.Connected(mockTunnelEndpoint, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ ),
+ onDisconnectClick = mockedClickHandler
+ )
+ }
+
+ // Act
+ composeTestRule.onNodeWithTag(CONNECT_BUTTON_TEST_TAG).performClick()
+
+ // Assert
+ verify { mockedClickHandler.invoke() }
+ }
+
+ @Test
+ fun testOnReconnectClick() {
+ // Arrange
+ val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
+ val mockedClickHandler: () -> Unit = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connected(mockTunnelEndpoint, null),
+ tunnelRealState = TunnelState.Connected(mockTunnelEndpoint, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ ),
+ onReconnectClick = mockedClickHandler
+ )
+ }
+
+ // Act
+ composeTestRule.onNodeWithTag(RECONNECT_BUTTON_TEST_TAG).performClick()
+
+ // Assert
+ verify { mockedClickHandler.invoke() }
+ }
+
+ @Test
+ fun testOnConnectClick() {
+ // Arrange
+ val mockedClickHandler: () -> Unit = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Disconnected,
+ tunnelRealState = TunnelState.Disconnected,
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ ),
+ onConnectClick = mockedClickHandler
+ )
+ }
+
+ // Act
+ composeTestRule.onNodeWithTag(CONNECT_BUTTON_TEST_TAG).performClick()
+
+ // Assert
+ verify { mockedClickHandler.invoke() }
+ }
+
+ @Test
+ fun testOnCancelClick() {
+ // Arrange
+ val mockedClickHandler: () -> Unit = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connecting(null, null),
+ tunnelRealState = TunnelState.Connecting(null, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ ),
+ onCancelClick = mockedClickHandler
+ )
+ }
+
+ // Act
+ composeTestRule.onNodeWithTag(CONNECT_BUTTON_TEST_TAG).performClick()
+
+ // Assert
+ verify { mockedClickHandler.invoke() }
+ }
+
+ @Test
+ fun testToggleTunnelInfo() {
+ // Arrange
+ val mockedClickHandler: () -> Unit = mockk(relaxed = true)
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = null,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connecting(null, null),
+ tunnelRealState = TunnelState.Connecting(null, null),
+ inAddress = null,
+ outAddress = "",
+ showLocation = false,
+ isTunnelInfoExpanded = false
+ ),
+ onToggleTunnelInfo = mockedClickHandler
+ )
+ }
+
+ // Act
+ composeTestRule.onNodeWithTag(LOCATION_INFO_TEST_TAG).performClick()
+
+ // Assert
+ verify { mockedClickHandler.invoke() }
+ }
+
+ @Test
+ fun showLocationInfo() {
+ // Arrange
+ val mockLocation: GeoIpLocation = mockk(relaxed = true)
+ val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
+ val mockHostName = "Host-Name"
+ val mockPort = 99
+ val mockHost = "Host"
+ val mockProtocol = TransportProtocol.Udp
+ val mockInAddress = Triple(mockHost, mockPort, mockProtocol)
+ val mockOutAddress = "HostAddressV4 / HostAddressV4"
+ every { mockLocation.hostname } returns mockHostName
+ composeTestRule.setContent {
+ ConnectScreen(
+ uiState =
+ ConnectUiState(
+ location = mockLocation,
+ relayLocation = null,
+ versionInfo = null,
+ tunnelUiState = TunnelState.Connected(mockTunnelEndpoint, null),
+ tunnelRealState = TunnelState.Connected(mockTunnelEndpoint, null),
+ inAddress = mockInAddress,
+ outAddress = mockOutAddress,
+ showLocation = false,
+ isTunnelInfoExpanded = true
+ )
+ )
+ }
+
+ // Assert
+ composeTestRule.apply {
+ onNodeWithText(mockHostName).assertExists()
+ onNodeWithText("WireGuard").assertExists()
+ onNodeWithText("In $mockHost:$mockPort UDP").assertExists()
+ onNodeWithText("Out $mockOutAddress").assertExists()
+ }
+ }
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt
index 7722ef0533..ca92eb290c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt
@@ -15,6 +15,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
@@ -31,6 +32,7 @@ import net.mullvad.talpid.tunnel.ActionAfterDisconnect
@Composable
fun ConnectionButton(
modifier: Modifier = Modifier,
+ reconnectButtonTestTag: String = "",
state: TunnelState,
disconnectClick: () -> Unit,
reconnectClick: () -> Unit,
@@ -48,14 +50,16 @@ fun ConnectionButton(
modifier = modifier,
text = stringResource(id = R.string.disconnect),
mainClick = connectClick,
- reconnectClick = reconnectClick
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
)
ActionAfterDisconnect.Reconnect ->
DisconnectButton(
modifier = modifier,
text = stringResource(id = R.string.disconnect),
mainClick = connectClick,
- reconnectClick = reconnectClick
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
)
}
}
@@ -64,14 +68,16 @@ fun ConnectionButton(
modifier = modifier,
text = stringResource(id = R.string.cancel),
mainClick = cancelClick,
- reconnectClick = reconnectClick
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
)
is TunnelState.Connected ->
DisconnectButton(
modifier = modifier,
text = stringResource(id = R.string.disconnect),
mainClick = disconnectClick,
- reconnectClick = reconnectClick
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
)
is TunnelState.Error -> {
if (state.errorState.isBlocking) {
@@ -79,14 +85,16 @@ fun ConnectionButton(
modifier = modifier,
text = stringResource(id = R.string.disconnect),
mainClick = disconnectClick,
- reconnectClick = reconnectClick
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
)
} else {
DisconnectButton(
modifier = modifier,
text = stringResource(id = R.string.dismiss),
mainClick = cancelClick,
- reconnectClick = reconnectClick
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
)
}
}
@@ -124,6 +132,7 @@ private fun DisconnectButton(
text: String,
modifier: Modifier = Modifier,
height: Dp = Dimens.connectButtonHeight,
+ reconnectButtonTestTag: String = "",
mainClick: () -> Unit,
reconnectClick: () -> Unit
) {
@@ -163,7 +172,7 @@ private fun DisconnectButton(
contentColor = MaterialTheme.colorScheme.onError
),
onClick = reconnectClick,
- modifier = Modifier.height(height).aspectRatio(1f, true)
+ modifier = Modifier.height(height).aspectRatio(1f, true).testTag(reconnectButtonTestTag)
) {
Icon(painter = painterResource(id = R.drawable.icon_reload), contentDescription = null)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
index cfc7dab08f..b6b31b7f3b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
@@ -18,6 +18,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import net.mullvad.mullvadvpn.R
@@ -26,6 +27,11 @@ import net.mullvad.mullvadvpn.compose.button.SwitchLocationButton
import net.mullvad.mullvadvpn.compose.component.ConnectionStatusText
import net.mullvad.mullvadvpn.compose.component.LocationInfo
import net.mullvad.mullvadvpn.compose.state.ConnectUiState
+import net.mullvad.mullvadvpn.compose.test.CIRCULAR_PROGRESS_INDICATOR
+import net.mullvad.mullvadvpn.compose.test.CONNECT_BUTTON_TEST_TAG
+import net.mullvad.mullvadvpn.compose.test.LOCATION_INFO_TEST_TAG
+import net.mullvad.mullvadvpn.compose.test.RECONNECT_BUTTON_TEST_TAG
+import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_BUTTON_TEST_TAG
import net.mullvad.mullvadvpn.compose.theme.AppTheme
import net.mullvad.mullvadvpn.compose.theme.Dimens
import net.mullvad.mullvadvpn.model.TunnelState
@@ -72,6 +78,7 @@ fun ConnectScreen(
height = Dimens.progressIndicatorSize
)
.align(Alignment.CenterHorizontally)
+ .testTag(CIRCULAR_PROGRESS_INDICATOR)
)
}
Spacer(modifier = Modifier.height(Dimens.smallPadding))
@@ -93,11 +100,14 @@ fun ConnectScreen(
location = uiState.location,
inAddress = uiState.inAddress,
outAddress = uiState.outAddress,
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier.fillMaxWidth().testTag(LOCATION_INFO_TEST_TAG)
)
Spacer(modifier = Modifier.height(Dimens.buttonSeparation))
SwitchLocationButton(
- modifier = Modifier.fillMaxWidth().height(Dimens.selectLocationButtonHeight),
+ modifier =
+ Modifier.fillMaxWidth()
+ .height(Dimens.selectLocationButtonHeight)
+ .testTag(SELECT_LOCATION_BUTTON_TEST_TAG),
onClick = onSwitchLocationClick,
showChevron = uiState.showLocation,
text =
@@ -110,11 +120,15 @@ fun ConnectScreen(
Spacer(modifier = Modifier.height(Dimens.buttonSeparation))
ConnectionButton(
state = uiState.tunnelUiState,
- modifier = Modifier.fillMaxWidth().height(Dimens.connectButtonHeight),
+ modifier =
+ Modifier.fillMaxWidth()
+ .height(Dimens.connectButtonHeight)
+ .testTag(CONNECT_BUTTON_TEST_TAG),
disconnectClick = onDisconnectClick,
reconnectClick = onReconnectClick,
cancelClick = onCancelClick,
connectClick = onConnectClick,
+ reconnectButtonTestTag = RECONNECT_BUTTON_TEST_TAG
)
}
}
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 536a343594..f896183bcb 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
@@ -11,5 +11,11 @@ const val LAZY_LIST_WIREGUARD_CUSTOM_PORT_TEXT_TEST_TAG =
const val LAZY_LIST_WIREGUARD_CUSTOM_PORT_NUMBER_TEST_TAG =
"lazy_list_wireguard_custom_port_number_test_tag"
-// SelectLocationScreen
+// SelectLocationScreen, ConnectScreen
const val CIRCULAR_PROGRESS_INDICATOR = "circular_progress_indicator"
+
+// ConnectScreen
+const val SELECT_LOCATION_BUTTON_TEST_TAG = "select_location_button_test_tag"
+const val CONNECT_BUTTON_TEST_TAG = "connect_button_test_tag"
+const val RECONNECT_BUTTON_TEST_TAG = "reconnect_button_test_tag"
+const val LOCATION_INFO_TEST_TAG = "location_info_test_tag"