Skip to content

Commit 15fc4f9

Browse files
committed
Merge branch 'migrate-connectiontest-tests-to-use-pop-droid-1622'
2 parents 4baba02 + 3fe2615 commit 15fc4f9

File tree

13 files changed

+372
-102
lines changed

13 files changed

+372
-102
lines changed

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import androidx.compose.ui.unit.dp
4949
import net.mullvad.mullvadvpn.R
5050
import net.mullvad.mullvadvpn.compose.test.TOP_BAR_ACCOUNT_BUTTON
5151
import net.mullvad.mullvadvpn.compose.test.TOP_BAR_SETTINGS_BUTTON
52+
import net.mullvad.mullvadvpn.compose.test.TOP_BAR_TEST_TAG
5253
import net.mullvad.mullvadvpn.lib.theme.AppTheme
5354
import net.mullvad.mullvadvpn.lib.theme.Dimens
5455

@@ -117,7 +118,7 @@ fun MullvadTopBar(
117118
isIconAndLogoVisible: Boolean = true,
118119
) {
119120
TopAppBar(
120-
modifier = modifier,
121+
modifier = modifier.testTag(TOP_BAR_TEST_TAG),
121122
title = {
122123
if (isIconAndLogoVisible) {
123124
Row(verticalAlignment = Alignment.CenterVertically) {

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider
4343
import net.mullvad.mullvadvpn.compose.preview.SettingsUiStatePreviewParameterProvider
4444
import net.mullvad.mullvadvpn.compose.state.SettingsUiState
4545
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_TEST_TAG
46+
import net.mullvad.mullvadvpn.compose.test.VPN_SETTINGS_CELL_TEST_TAG
4647
import net.mullvad.mullvadvpn.compose.transitions.TopLevelTransition
4748
import net.mullvad.mullvadvpn.lib.theme.AppTheme
4849
import net.mullvad.mullvadvpn.lib.theme.Dimens
@@ -115,6 +116,7 @@ fun SettingsScreen(
115116
NavigationComposeCell(
116117
title = stringResource(id = R.string.settings_vpn),
117118
onClick = onVpnSettingCellClick,
119+
testTag = VPN_SETTINGS_CELL_TEST_TAG,
118120
)
119121
}
120122
item { Spacer(modifier = Modifier.height(Dimens.cellVerticalSpacing)) }

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.compose.ui.Alignment
3232
import androidx.compose.ui.Modifier
3333
import androidx.compose.ui.graphics.Color
3434
import androidx.compose.ui.platform.LocalContext
35+
import androidx.compose.ui.platform.testTag
3536
import androidx.compose.ui.res.stringResource
3637
import androidx.compose.ui.tooling.preview.Preview
3738
import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -63,6 +64,7 @@ import net.mullvad.mullvadvpn.compose.extensions.dropUnlessResumed
6364
import net.mullvad.mullvadvpn.compose.preview.SelectLocationsUiStatePreviewParameterProvider
6465
import net.mullvad.mullvadvpn.compose.state.RelayListType
6566
import net.mullvad.mullvadvpn.compose.state.SelectLocationUiState
67+
import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_SCREEN_TEST_TAG
6668
import net.mullvad.mullvadvpn.compose.transitions.TopLevelTransition
6769
import net.mullvad.mullvadvpn.compose.util.CollectSideEffectWithLifecycle
6870
import net.mullvad.mullvadvpn.compose.util.showSnackbarImmediately
@@ -237,6 +239,7 @@ fun SelectLocationScreen(
237239
)
238240
}
239241
},
242+
modifier = Modifier.testTag(SELECT_LOCATION_SCREEN_TEST_TAG),
240243
snackbarHostState = snackbarHostState,
241244
actions = {
242245
IconButton(

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package net.mullvad.mullvadvpn.compose.test
33
// Top Bar
44
const val TOP_BAR_ACCOUNT_BUTTON = "top_bar_account_button"
55
const val TOP_BAR_SETTINGS_BUTTON = "top_bar_settings_button"
6+
const val TOP_BAR_TEST_TAG = "top_bar_test_tag"
7+
8+
// Settings screen
9+
const val VPN_SETTINGS_CELL_TEST_TAG = "vpn_settings_cell_test_tag"
610

711
// VpnSettingsScreen
812
const val LAZY_LIST_VPN_SETTINGS_TEST_TAG = "lazy_list_vpn_settings_test_tag"
@@ -24,6 +28,7 @@ const val WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL =
2428
"wireguard_obfuscation_udp_over_tcp_cell_test_tag"
2529

2630
// SelectLocationScreen, ConnectScreen, CustomListLocationsScreen
31+
const val SELECT_LOCATION_SCREEN_TEST_TAG = "select_location_screen_test_tag"
2732
const val CIRCULAR_PROGRESS_INDICATOR = "circular_progress_indicator"
2833
const val EXPAND_BUTTON_TEST_TAG = "expand_button_test_tag"
2934
const val LOCATION_CELL_TEST_TAG = "location_cell_test_tag"
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,79 @@
11
package net.mullvad.mullvadvpn.test.common.page
22

33
import androidx.test.uiautomator.By
4+
import net.mullvad.mullvadvpn.test.common.constant.VERY_LONG_TIMEOUT
45
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
56

67
class ConnectPage internal constructor() : Page() {
8+
private val disconnectSelector = By.text("Disconnect")
9+
private val cancelSelector = By.text("Cancel")
10+
private val connectedSelector = By.text("CONNECTED")
11+
private val connectingSelector = By.text("CONNECTING...")
12+
713
override fun assertIsDisplayed() {
8-
uiDevice.findObjectWithTimeout(By.res("connect_card_header_test_tag"))
14+
uiDevice.findObjectWithTimeout(By.res(CONNECT_CARD_HEADER_TEST_TAG))
15+
}
16+
17+
fun clickSelectLocation() {
18+
uiDevice.findObjectWithTimeout(By.res(SELECT_LOCATION_BUTTON_TEST_TAG)).click()
19+
}
20+
21+
fun clickConnect() {
22+
uiDevice.findObjectWithTimeout(By.res(CONNECT_BUTTON_TEST_TAG)).click()
23+
}
24+
25+
fun clickDisconnect() {
26+
uiDevice.findObjectWithTimeout(disconnectSelector).click()
27+
}
28+
29+
fun clickCancel() {
30+
uiDevice.findObjectWithTimeout(cancelSelector).click()
31+
}
32+
33+
fun waitForConnectedLabel(timeout: Long = VERY_LONG_TIMEOUT) {
34+
uiDevice.findObjectWithTimeout(connectedSelector, timeout)
35+
}
36+
37+
fun waitForConnectingLabel() {
38+
uiDevice.findObjectWithTimeout(connectingSelector)
39+
}
40+
41+
/**
42+
* Extracts the in IPv4 address from the connection card. It is a prerequisite that the
43+
* connection card is in collapsed state.
44+
*/
45+
fun extractInIpv4Address(): String {
46+
uiDevice.findObjectWithTimeout(By.res("connect_card_header_test_tag")).click()
47+
val inString =
48+
uiDevice
49+
.findObjectWithTimeout(
50+
By.res("location_info_connection_in_test_tag"),
51+
VERY_LONG_TIMEOUT,
52+
)
53+
.text
54+
55+
val extractedIpAddress = inString.split(" ")[0].split(":")[0]
56+
return extractedIpAddress
57+
}
58+
59+
/**
60+
* Extracts the out IPv4 address from the connection card. It is a prerequisite that the
61+
* connection card is in collapsed state.
62+
*/
63+
fun extractOutIpv4Address(): String {
64+
uiDevice.findObjectWithTimeout(By.res("connect_card_header_test_tag")).click()
65+
return uiDevice
66+
.findObjectWithTimeout(
67+
// Text exist and contains IP address
68+
By.res("location_info_connection_out_test_tag").textContains("."),
69+
VERY_LONG_TIMEOUT,
70+
)
71+
.text
72+
}
73+
74+
companion object {
75+
const val CONNECT_CARD_HEADER_TEST_TAG = "connect_card_header_test_tag"
76+
const val SELECT_LOCATION_BUTTON_TEST_TAG = "select_location_button_test_tag"
77+
const val CONNECT_BUTTON_TEST_TAG = "connect_button_test_tag"
978
}
1079
}

android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/LoginPage.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import net.mullvad.mullvadvpn.test.common.constant.EXTREMELY_LONG_TIMEOUT
88
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
99

1010
class LoginPage internal constructor() : Page() {
11+
private val invalidAccountNumberSelector = By.text("Invalid account number")
12+
private val loginSelector = By.text("Login")
13+
1114
fun enterAccountNumber(accountNumber: String) {
1215
uiDevice.findObjectWithTimeout(By.clazz("android.widget.EditText")).text = accountNumber
1316
}
@@ -20,10 +23,10 @@ class LoginPage internal constructor() : Page() {
2023
}
2124

2225
fun verifyShowingInvalidAccount() {
23-
uiDevice.findObjectWithTimeout(By.text("Invalid account number"), EXTREMELY_LONG_TIMEOUT)
26+
uiDevice.findObjectWithTimeout(invalidAccountNumberSelector, EXTREMELY_LONG_TIMEOUT)
2427
}
2528

2629
override fun assertIsDisplayed() {
27-
uiDevice.findObjectWithTimeout(By.text("Login"))
30+
uiDevice.findObjectWithTimeout(loginSelector)
2831
}
2932
}

android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/PrivacyPage.kt

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ import net.mullvad.mullvadvpn.test.common.constant.DEFAULT_TIMEOUT
77
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
88

99
class PrivacyPage internal constructor() : Page() {
10+
private val privacySelector = By.text("Privacy")
11+
private val agreeSelector = By.text("Agree and continue")
12+
private val allowSelector = By.text("Allow")
13+
1014
override fun assertIsDisplayed() {
11-
uiDevice.findObjectWithTimeout(By.text("Privacy"))
15+
uiDevice.findObjectWithTimeout(privacySelector)
1216
}
1317

1418
fun clickAgreeOnPrivacyDisclaimer() {
15-
uiDevice.findObjectWithTimeout(By.text("Agree and continue")).click()
19+
uiDevice.findObjectWithTimeout(agreeSelector).click()
1620
}
1721

1822
fun clickAllowOnNotificationPermissionPromptIfApiLevel33AndAbove(
@@ -23,12 +27,10 @@ class PrivacyPage internal constructor() : Page() {
2327
return
2428
}
2529

26-
val selector = By.text("Allow")
27-
28-
uiDevice.wait(Until.hasObject(selector), timeout)
30+
uiDevice.wait(Until.hasObject(allowSelector), timeout)
2931

3032
try {
31-
uiDevice.findObjectWithTimeout(selector).click()
33+
uiDevice.findObjectWithTimeout(allowSelector).click()
3234
} catch (e: IllegalArgumentException) {
3335
throw IllegalArgumentException(
3436
"Failed to allow notification permission within timeout ($timeout)"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.mullvad.mullvadvpn.test.common.page
2+
3+
import androidx.test.uiautomator.By
4+
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
5+
6+
class SelectLocationPage internal constructor() : Page() {
7+
override fun assertIsDisplayed() {
8+
uiDevice.findObjectWithTimeout(By.res(SELECT_LOCATION_SCREEN_TEST_TAG))
9+
}
10+
11+
fun clickLocationExpandButton(locationName: String) {
12+
val locationCell = uiDevice.findObjectWithTimeout(By.text(locationName)).parent.parent
13+
val expandButton = locationCell.findObjectWithTimeout(By.res(EXPAND_BUTTON_TEST_TAG))
14+
expandButton.click()
15+
}
16+
17+
fun clickLocationCell(locationName: String) {
18+
uiDevice.findObjectWithTimeout(By.text(locationName)).click()
19+
}
20+
21+
companion object {
22+
const val SELECT_LOCATION_SCREEN_TEST_TAG = "select_location_screen_test_tag"
23+
const val EXPAND_BUTTON_TEST_TAG = "expand_button_test_tag"
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.mullvad.mullvadvpn.test.common.page
2+
3+
import androidx.test.uiautomator.By
4+
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
5+
6+
class SettingsPage internal constructor() : Page() {
7+
private val settingsSelector = By.text("Settings")
8+
9+
override fun assertIsDisplayed() {
10+
uiDevice.findObjectWithTimeout(settingsSelector)
11+
}
12+
13+
fun clickVpnSettings() {
14+
uiDevice.findObjectWithTimeout(By.res(VPN_SETTINGS_CELL_TEST_TAG)).click()
15+
}
16+
17+
companion object {
18+
const val VPN_SETTINGS_CELL_TEST_TAG = "vpn_settings_cell_test_tag"
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.mullvad.mullvadvpn.test.common.page
2+
3+
import androidx.test.uiautomator.By
4+
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
5+
6+
class SystemVpnConfigurationAlert internal constructor() : Page() {
7+
private val okSelector = By.text("OK")
8+
9+
override fun assertIsDisplayed() {
10+
uiDevice.findObjectWithTimeout(okSelector)
11+
}
12+
13+
fun clickOk() {
14+
uiDevice.findObjectWithTimeout(okSelector).click()
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package net.mullvad.mullvadvpn.test.common.page
2+
3+
import androidx.test.uiautomator.By
4+
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
5+
6+
class TopBar internal constructor() : Page() {
7+
override fun assertIsDisplayed() {
8+
uiDevice.findObjectWithTimeout(By.res(TOP_BAR_TEST_TAG))
9+
}
10+
11+
fun clickSettings() {
12+
uiDevice.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click()
13+
}
14+
15+
fun clickAccount() {
16+
uiDevice.findObjectWithTimeout(By.res(TOP_BAR_ACCOUNT_BUTTON)).click()
17+
}
18+
19+
companion object {
20+
const val TOP_BAR_TEST_TAG = "top_bar_test_tag"
21+
const val TOP_BAR_ACCOUNT_BUTTON = "top_bar_account_button"
22+
const val TOP_BAR_SETTINGS_BUTTON = "top_bar_settings_button"
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package net.mullvad.mullvadvpn.test.common.page
2+
3+
import androidx.test.uiautomator.By
4+
import androidx.test.uiautomator.Direction
5+
import androidx.test.uiautomator.Until
6+
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
7+
8+
class VpnSettingsPage internal constructor() : Page() {
9+
private val vpnSettingsSelector = By.text("VPN settings")
10+
private val localNetworkSharingSelector = By.text("Local network sharing")
11+
12+
override fun assertIsDisplayed() {
13+
uiDevice.findObjectWithTimeout(vpnSettingsSelector)
14+
}
15+
16+
fun clickLocalNetworkSharingSwitch() {
17+
val localNetworkSharingCell =
18+
uiDevice.findObjectWithTimeout(localNetworkSharingSelector).parent
19+
val localNetworkSharingSwitch =
20+
localNetworkSharingCell.findObjectWithTimeout(By.res(SWITCH_TEST_TAG))
21+
22+
localNetworkSharingSwitch.click()
23+
}
24+
25+
fun scrollUntilWireguardObfuscationUdpOverTcpCell() {
26+
scrollUntilCell(WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG)
27+
}
28+
29+
fun scrollUntilWireguardObfuscationOffCell() {
30+
scrollUntilCell(WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG)
31+
}
32+
33+
fun clickWireguardObfuscationUdpOverTcpCell() {
34+
uiDevice
35+
.findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG))
36+
.click()
37+
}
38+
39+
fun clickWireguardObfuscationOffCell() {
40+
uiDevice.findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG)).click()
41+
}
42+
43+
private fun scrollUntilCell(testTag: String) {
44+
val scrollView2 = uiDevice.findObjectWithTimeout(By.res(SETTINGS_SCROLL_VIEW_TEST_TAG))
45+
scrollView2.scrollUntil(Direction.DOWN, Until.hasObject(By.res(testTag)))
46+
}
47+
48+
companion object {
49+
const val SETTINGS_SCROLL_VIEW_TEST_TAG = "lazy_list_vpn_settings_test_tag"
50+
const val WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG =
51+
"wireguard_obfuscation_udp_over_tcp_cell_test_tag"
52+
const val WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG =
53+
"wireguard_obfuscation_off_cell_test_tag"
54+
const val SWITCH_TEST_TAG = "switch_test_tag"
55+
}
56+
}

0 commit comments

Comments
 (0)