summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNiklas Berglund <niklas.berglund@gmail.com>2024-12-13 17:31:37 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-01-13 11:04:24 +0100
commitdd3ee9577ff3e99b048a8653ad0a393e47169ac2 (patch)
treebf71258782b3d5241859eb9206f28b71f0f6ac3d
parentfaf8f909b83af3401920485dbfc816ffd55d5cb7 (diff)
downloadmullvadvpn-dd3ee9577ff3e99b048a8653ad0a393e47169ac2.tar.xz
mullvadvpn-dd3ee9577ff3e99b048a8653ad0a393e47169ac2.zip
Add leak test for when VPN settings change
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/test/ComposeTestTagConstants.kt6
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt15
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/ConnectPage.kt10
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/DaitaSettingsPage.kt25
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/LoginPage.kt8
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/SettingsPage.kt5
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/TopBar.kt24
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/VpnSettingsPage.kt27
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt28
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt4
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt104
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LogoutTest.kt4
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/WebLinkTest.kt4
16 files changed, 218 insertions, 53 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
index 70e0d1622a..60d8d7e861 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
@@ -23,6 +23,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.tooling.preview.Preview
@@ -40,6 +41,7 @@ import net.mullvad.mullvadvpn.compose.cell.SwitchComposeSubtitleCell
import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
import net.mullvad.mullvadvpn.compose.component.ScaffoldWithMediumTopBar
import net.mullvad.mullvadvpn.compose.state.DaitaUiState
+import net.mullvad.mullvadvpn.compose.test.DAITA_SCREEN_TEST_TAG
import net.mullvad.mullvadvpn.compose.transitions.SlideInFromRightTransition
import net.mullvad.mullvadvpn.compose.util.OnNavResultValue
import net.mullvad.mullvadvpn.lib.theme.AppTheme
@@ -103,6 +105,7 @@ fun DaitaScreen(
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.daita),
navigationIcon = { NavigateBackIconButton { onBackClick() } },
+ modifier = Modifier.testTag(DAITA_SCREEN_TEST_TAG),
) { modifier ->
Column(modifier = modifier) {
val pagerState = rememberPagerState(pageCount = { DaitaPages.entries.size })
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt
index e0caf03839..0aad17a24e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt
@@ -42,6 +42,7 @@ import net.mullvad.mullvadvpn.compose.extensions.createUriHook
import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider
import net.mullvad.mullvadvpn.compose.preview.SettingsUiStatePreviewParameterProvider
import net.mullvad.mullvadvpn.compose.state.SettingsUiState
+import net.mullvad.mullvadvpn.compose.test.DAITA_CELL_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.VPN_SETTINGS_CELL_TEST_TAG
import net.mullvad.mullvadvpn.compose.transitions.TopLevelTransition
@@ -248,6 +249,7 @@ private fun DaitaCell(isDaitaEnabled: Boolean, onDaitaClick: () -> Unit) {
tint = MaterialTheme.colorScheme.onPrimary,
)
},
+ modifier = Modifier.testTag(DAITA_CELL_TEST_TAG),
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
index c44972e781..db8b3f94dd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
@@ -88,6 +88,7 @@ import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_CUSTOM_PORT_TEXT_
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_OBFUSCATION_TITLE_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_PORT_ITEM_X_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.WIREGUARD_OBFUSCATION_OFF_CELL
+import net.mullvad.mullvadvpn.compose.test.WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL
import net.mullvad.mullvadvpn.compose.test.WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL
import net.mullvad.mullvadvpn.compose.transitions.SlideInFromRightTransition
import net.mullvad.mullvadvpn.compose.util.CollectSideEffectWithLifecycle
@@ -574,6 +575,7 @@ fun VpnSettingsScreen(
port = state.selectedShadowsSocksObfuscationPort,
onSelected = onSelectObfuscationMode,
onNavigate = navigateToShadowSocksSettings,
+ testTag = WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL,
)
}
itemWithDivider {
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 bdc85b1d6f..f38e349a7f 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
@@ -7,6 +7,10 @@ const val TOP_BAR_TEST_TAG = "top_bar_test_tag"
// Settings screen
const val VPN_SETTINGS_CELL_TEST_TAG = "vpn_settings_cell_test_tag"
+const val DAITA_CELL_TEST_TAG = "data_cell_test_tag"
+
+// DAITA settings screen
+const val DAITA_SCREEN_TEST_TAG = "daita_screen_test_tag"
// VpnSettingsScreen
const val LAZY_LIST_VPN_SETTINGS_TEST_TAG = "lazy_list_vpn_settings_test_tag"
@@ -24,8 +28,10 @@ const val LAZY_LIST_WIREGUARD_OBFUSCATION_TITLE_TEST_TAG =
"lazy_list_wireguard_obfuscation_title_test_tag"
const val SWITCH_TEST_TAG = "switch_test_tag"
const val WIREGUARD_OBFUSCATION_OFF_CELL = "wireguard_obfuscation_off_cell_test_tag"
+const val WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL = "wireguard_obfuscation_shadowsocks_cell_test_tag"
const val WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL =
"wireguard_obfuscation_udp_over_tcp_cell_test_tag"
+const val QUANTUM_RESISTANCE_OFF_CELL = "quantum_resistance_off_cell_test_tag"
// SelectLocationScreen, ConnectScreen, CustomListLocationsScreen
const val SELECT_LOCATION_SCREEN_TEST_TAG = "select_location_screen_test_tag"
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt
index 41fe28b68c..2b9b008ad0 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt
@@ -16,6 +16,10 @@ import net.mullvad.mullvadvpn.test.common.extension.clickAgreeOnPrivacyDisclaime
import net.mullvad.mullvadvpn.test.common.extension.clickAllowOnNotificationPermissionPromptIfApiLevel33AndAbove
import net.mullvad.mullvadvpn.test.common.extension.dismissChangelogDialogIfShown
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
+import net.mullvad.mullvadvpn.test.common.page.ConnectPage
+import net.mullvad.mullvadvpn.test.common.page.SettingsPage
+import net.mullvad.mullvadvpn.test.common.page.VpnSettingsPage
+import net.mullvad.mullvadvpn.test.common.page.on
class AppInteractor(
private val device: UiDevice,
@@ -53,6 +57,17 @@ class AppInteractor(
ensureLoggedIn()
}
+ fun enableLocalNetworkSharing() {
+ on<ConnectPage> { clickSettings() }
+
+ on<SettingsPage> { clickVpnSettings() }
+
+ on<VpnSettingsPage> { clickLocalNetworkSharingSwitch() }
+
+ device.pressBack()
+ device.pressBack()
+ }
+
fun attemptLogin(accountNumber: String) {
val loginObject =
device.findObjectWithTimeout(By.clazz("android.widget.EditText")).apply {
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/ConnectPage.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/ConnectPage.kt
index 552fc17ee4..d8f45b43bf 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/ConnectPage.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/ConnectPage.kt
@@ -15,6 +15,14 @@ class ConnectPage internal constructor() : Page() {
uiDevice.findObjectWithTimeout(By.res(CONNECT_CARD_HEADER_TEST_TAG))
}
+ fun clickSettings() {
+ uiDevice.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click()
+ }
+
+ fun clickAccount() {
+ uiDevice.findObjectWithTimeout(By.res(TOP_BAR_ACCOUNT_BUTTON)).click()
+ }
+
fun clickSelectLocation() {
uiDevice.findObjectWithTimeout(By.res(SELECT_LOCATION_BUTTON_TEST_TAG)).click()
}
@@ -77,6 +85,8 @@ class ConnectPage internal constructor() : Page() {
}
companion object {
+ const val TOP_BAR_ACCOUNT_BUTTON = "top_bar_account_button"
+ const val TOP_BAR_SETTINGS_BUTTON = "top_bar_settings_button"
const val CONNECT_CARD_HEADER_TEST_TAG = "connect_card_header_test_tag"
const val SELECT_LOCATION_BUTTON_TEST_TAG = "select_location_button_test_tag"
const val CONNECT_BUTTON_TEST_TAG = "connect_button_test_tag"
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/DaitaSettingsPage.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/DaitaSettingsPage.kt
new file mode 100644
index 0000000000..a4fa5b9286
--- /dev/null
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/DaitaSettingsPage.kt
@@ -0,0 +1,25 @@
+package net.mullvad.mullvadvpn.test.common.page
+
+import androidx.test.uiautomator.By
+import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
+import net.mullvad.mullvadvpn.test.common.page.VpnSettingsPage.Companion.SWITCH_TEST_TAG
+
+class DaitaSettingsPage internal constructor() : Page() {
+ private val enableSelector = By.text("Enable")
+
+ override fun assertIsDisplayed() {
+ uiDevice.findObjectWithTimeout(By.res(DAITA_SCREEN_TEST_TAG))
+ }
+
+ fun clickEnableSwitch() {
+ val localNetworkSharingCell = uiDevice.findObjectWithTimeout(enableSelector).parent
+ val localNetworkSharingSwitch =
+ localNetworkSharingCell.findObjectWithTimeout(By.res(SWITCH_TEST_TAG))
+
+ localNetworkSharingSwitch.click()
+ }
+
+ companion object {
+ const val DAITA_SCREEN_TEST_TAG = "daita_screen_test_tag"
+ }
+}
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/LoginPage.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/LoginPage.kt
index 1098e4d1cc..e08ff92106 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/LoginPage.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/LoginPage.kt
@@ -11,6 +11,10 @@ class LoginPage internal constructor() : Page() {
private val invalidAccountNumberSelector = By.text("Invalid account number")
private val loginSelector = By.text("Login")
+ fun clickSettings() {
+ uiDevice.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click()
+ }
+
fun enterAccountNumber(accountNumber: String) {
uiDevice.findObjectWithTimeout(By.clazz("android.widget.EditText")).text = accountNumber
}
@@ -29,4 +33,8 @@ class LoginPage internal constructor() : Page() {
override fun assertIsDisplayed() {
uiDevice.findObjectWithTimeout(loginSelector)
}
+
+ companion object {
+ const val TOP_BAR_SETTINGS_BUTTON = "top_bar_settings_button"
+ }
}
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/SettingsPage.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/SettingsPage.kt
index ebeb8eea4a..2ce0cc1c29 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/SettingsPage.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/SettingsPage.kt
@@ -19,7 +19,12 @@ class SettingsPage internal constructor() : Page() {
uiDevice.findObjectWithTimeout(faqAndGuidesSelector).click()
}
+ fun clickDaita() {
+ uiDevice.findObjectWithTimeout(By.res(DAITA_CELL_TEST_TAG)).click()
+ }
+
companion object {
const val VPN_SETTINGS_CELL_TEST_TAG = "vpn_settings_cell_test_tag"
+ const val DAITA_CELL_TEST_TAG = "data_cell_test_tag"
}
}
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/TopBar.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/TopBar.kt
deleted file mode 100644
index c602e26def..0000000000
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/TopBar.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.mullvad.mullvadvpn.test.common.page
-
-import androidx.test.uiautomator.By
-import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
-
-class TopBar internal constructor() : Page() {
- override fun assertIsDisplayed() {
- uiDevice.findObjectWithTimeout(By.res(TOP_BAR_TEST_TAG))
- }
-
- fun clickSettings() {
- uiDevice.findObjectWithTimeout(By.res(TOP_BAR_SETTINGS_BUTTON)).click()
- }
-
- fun clickAccount() {
- uiDevice.findObjectWithTimeout(By.res(TOP_BAR_ACCOUNT_BUTTON)).click()
- }
-
- companion object {
- const val TOP_BAR_TEST_TAG = "top_bar_test_tag"
- const val TOP_BAR_ACCOUNT_BUTTON = "top_bar_account_button"
- const val TOP_BAR_SETTINGS_BUTTON = "top_bar_settings_button"
- }
-}
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/VpnSettingsPage.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/VpnSettingsPage.kt
index 1a74b80232..9301768100 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/VpnSettingsPage.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/VpnSettingsPage.kt
@@ -22,24 +22,42 @@ class VpnSettingsPage internal constructor() : Page() {
localNetworkSharingSwitch.click()
}
- fun scrollUntilWireguardObfuscationUdpOverTcpCell() {
+ fun scrollUntilWireGuardObfuscationUdpOverTcpCell() {
scrollUntilCell(WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG)
}
- fun scrollUntilWireguardObfuscationOffCell() {
+ fun scrollUntilWireGuardObfuscationOffCell() {
scrollUntilCell(WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG)
}
+ fun scrollUntilPostQuantumOffCell() {
+ scrollUntilCell(QUANTUM_RESISTANCE_OFF_CELL_TEST_TAG)
+ }
+
+ fun scrollUntilWireGuardObfuscationShadowsocksCell() {
+ scrollUntilCell(WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL_TEST_TAG)
+ }
+
fun clickWireguardObfuscationUdpOverTcpCell() {
uiDevice
.findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_UDP_OVER_TCP_CELL_TEST_TAG))
.click()
}
- fun clickWireguardObfuscationOffCell() {
+ fun clickWireGuardObfuscationOffCell() {
uiDevice.findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_OFF_CELL_TEST_TAG)).click()
}
+ fun clickPostQuantumOffCell() {
+ uiDevice.findObjectWithTimeout(By.res(QUANTUM_RESISTANCE_OFF_CELL_TEST_TAG)).click()
+ }
+
+ fun clickWireGuardObfuscationShadowsocksCell() {
+ uiDevice
+ .findObjectWithTimeout(By.res(WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL_TEST_TAG))
+ .click()
+ }
+
private fun scrollUntilCell(testTag: String) {
val scrollView2 = uiDevice.findObjectWithTimeout(By.res(SETTINGS_SCROLL_VIEW_TEST_TAG))
scrollView2.scrollUntil(Direction.DOWN, Until.hasObject(By.res(testTag)))
@@ -57,6 +75,9 @@ class VpnSettingsPage internal constructor() : Page() {
"wireguard_obfuscation_off_cell_test_tag"
const val WIREGUARD_CUSTOM_PORT_CELL_TEST_TAG =
"lazy_list_wireguard_custom_port_text_test_tag"
+ const val WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL_TEST_TAG =
+ "wireguard_obfuscation_shadowsocks_cell_test_tag"
const val SWITCH_TEST_TAG = "switch_test_tag"
+ const val QUANTUM_RESISTANCE_OFF_CELL_TEST_TAG = "lazy_list_quantum_item_off_test_tag"
}
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt
index 1ba78818a2..0ed78f6db3 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt
@@ -9,7 +9,6 @@ import net.mullvad.mullvadvpn.test.common.page.ConnectPage
import net.mullvad.mullvadvpn.test.common.page.SelectLocationPage
import net.mullvad.mullvadvpn.test.common.page.SettingsPage
import net.mullvad.mullvadvpn.test.common.page.SystemVpnConfigurationAlert
-import net.mullvad.mullvadvpn.test.common.page.TopBar
import net.mullvad.mullvadvpn.test.common.page.VpnSettingsPage
import net.mullvad.mullvadvpn.test.common.page.on
import net.mullvad.mullvadvpn.test.common.rule.ForgetAllVpnAppsInSettingsTestRule
@@ -72,7 +71,7 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
@ClearFirewallRules
fun testWireGuardObfuscationAutomatic() = runBlocking {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
- enableLocalNetworkSharing()
+ app.enableLocalNetworkSharing()
on<ConnectPage> { clickSelectLocation() }
@@ -109,7 +108,7 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
@ClearFirewallRules
fun testWireGuardObfuscationOff() = runBlocking {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
- enableLocalNetworkSharing()
+ app.enableLocalNetworkSharing()
on<ConnectPage> { clickSelectLocation() }
@@ -134,13 +133,13 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
firewallClient.createRule(firewallRule)
// Enable UDP-over-TCP
- on<TopBar> { clickSettings() }
+ on<ConnectPage> { clickSettings() }
on<SettingsPage> { clickVpnSettings() }
on<VpnSettingsPage> {
- scrollUntilWireguardObfuscationOffCell()
- clickWireguardObfuscationOffCell()
+ scrollUntilWireGuardObfuscationOffCell()
+ clickWireGuardObfuscationOffCell()
}
device.pressBack()
@@ -162,7 +161,7 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
fun testUDPOverTCP() =
runBlocking<Unit> {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
- enableLocalNetworkSharing()
+ app.enableLocalNetworkSharing()
on<ConnectPage> { clickSelectLocation() }
@@ -187,12 +186,12 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
firewallClient.createRule(firewallRule)
// Enable UDP-over-TCP
- on<TopBar> { clickSettings() }
+ on<ConnectPage> { clickSettings() }
on<SettingsPage> { clickVpnSettings() }
on<VpnSettingsPage> {
- scrollUntilWireguardObfuscationUdpOverTcpCell()
+ scrollUntilWireGuardObfuscationUdpOverTcpCell()
clickWireguardObfuscationUdpOverTcpCell()
}
@@ -206,17 +205,6 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
}
}
- private fun enableLocalNetworkSharing() {
- on<TopBar> { clickSettings() }
-
- on<SettingsPage> { clickVpnSettings() }
-
- on<VpnSettingsPage> { clickLocalNetworkSharingSwitch() }
-
- device.pressBack()
- device.pressBack()
- }
-
companion object {
const val VERY_FORGIVING_WIREGUARD_OFF_CONNECTION_TIMEOUT = 60000L
const val UNSUCCESSFUL_CONNECTION_TIMEOUT = 60000L
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt
index dfa050f9bc..f74355ae2a 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt
@@ -57,5 +57,9 @@ abstract class EndToEndTest(private val infra: String) {
const val DEFAULT_COUNTRY = "Sweden"
const val DEFAULT_CITY = "Gothenburg"
const val DEFAULT_RELAY = "se-got-wg-001"
+
+ const val DAITA_COMPATIBLE_COUNTRY = "Relay Software Country"
+ const val DAITA_COMPATIBLE_CITY = "Relay Software city"
+ const val DAITA_COMPATIBLE_RELAY = "se-got-wg-002"
}
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt
index 51b6d84708..46f1271257 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt
@@ -5,10 +5,10 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import net.mullvad.mullvadvpn.test.common.misc.Attachment
import net.mullvad.mullvadvpn.test.common.page.ConnectPage
+import net.mullvad.mullvadvpn.test.common.page.DaitaSettingsPage
import net.mullvad.mullvadvpn.test.common.page.SelectLocationPage
import net.mullvad.mullvadvpn.test.common.page.SettingsPage
import net.mullvad.mullvadvpn.test.common.page.SystemVpnConfigurationAlert
-import net.mullvad.mullvadvpn.test.common.page.TopBar
import net.mullvad.mullvadvpn.test.common.page.VpnSettingsPage
import net.mullvad.mullvadvpn.test.common.page.WireGuardCustomPortDialog
import net.mullvad.mullvadvpn.test.common.page.on
@@ -36,7 +36,7 @@ class LeakTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
fun setupVPNSettings() {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
- on<TopBar> { clickSettings() }
+ on<ConnectPage> { clickSettings() }
on<SettingsPage> { clickVpnSettings() }
@@ -159,4 +159,104 @@ class LeakTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
val leakRules = listOf(NoTrafficToHostRule(targetIpAddress))
LeakCheck.assertLeaks(capturedStreams, leakRules)
}
+
+ @Test
+ @HasDependencyOnLocalAPI
+ fun testLeakWhenVpnSettingsChange() =
+ runBlocking<Unit> {
+ app.launch()
+ // Obfuscation and Post-Quantum are by default set to automatic. Explicitly set to off.
+ disableObfuscation()
+ disablePostQuantum()
+
+ on<ConnectPage> { clickSelectLocation() }
+
+ on<SelectLocationPage> {
+ clickLocationExpandButton(DAITA_COMPATIBLE_COUNTRY)
+ clickLocationExpandButton(DAITA_COMPATIBLE_CITY)
+ clickLocationCell(DAITA_COMPATIBLE_RELAY)
+ }
+
+ on<SystemVpnConfigurationAlert> { clickOk() }
+
+ on<ConnectPage> { waitForConnectedLabel() }
+
+ // Capture generated traffic to a specific host
+ val targetIpAddress = BuildConfig.TRAFFIC_GENERATION_IP_ADDRESS
+ val targetPort = 80
+ val captureResult: PacketCaptureResult =
+ PacketCapture().capturePackets {
+ TrafficGenerator(targetIpAddress, targetPort).generateTraffic(10.milliseconds) {
+ delay(
+ 1000.milliseconds
+ ) // Give it some time for generating traffic in tunnel before changing
+ // settings
+
+ enableDAITA()
+ enableShadowsocks()
+
+ on<ConnectPage> { waitForConnectedLabel() }
+
+ delay(
+ 1000.milliseconds
+ ) // Give it some time for generating traffic in tunnel after enabling
+ // settings
+ }
+ }
+
+ val capturedStreams = captureResult.streams
+ val capturedPcap = captureResult.pcap
+ val timestamp = System.currentTimeMillis()
+ Attachment.saveAttachment(
+ "capture-testLeakWhenVpnSettingsChange-$timestamp.pcap",
+ capturedPcap,
+ )
+
+ val leakRules = listOf(NoTrafficToHostRule(targetIpAddress))
+ LeakCheck.assertLeaks(capturedStreams, leakRules)
+ }
+
+ private fun disableObfuscation() {
+ on<ConnectPage> { clickSettings() }
+ on<SettingsPage> { clickVpnSettings() }
+ on<VpnSettingsPage> {
+ scrollUntilWireGuardObfuscationUdpOverTcpCell()
+ clickWireGuardObfuscationOffCell()
+ }
+
+ device.pressBack()
+ device.pressBack()
+ }
+
+ private fun disablePostQuantum() {
+ on<ConnectPage> { clickSettings() }
+ on<SettingsPage> { clickVpnSettings() }
+ on<VpnSettingsPage> {
+ scrollUntilPostQuantumOffCell()
+ clickPostQuantumOffCell()
+ }
+
+ device.pressBack()
+ device.pressBack()
+ }
+
+ private fun enableShadowsocks() {
+ on<ConnectPage> { clickSettings() }
+ on<SettingsPage> { clickVpnSettings() }
+ on<VpnSettingsPage> {
+ scrollUntilWireGuardObfuscationShadowsocksCell()
+ clickWireGuardObfuscationShadowsocksCell()
+ }
+
+ device.pressBack()
+ device.pressBack()
+ }
+
+ private fun enableDAITA() {
+ on<ConnectPage> { clickSettings() }
+ on<SettingsPage> { clickDaita() }
+ on<DaitaSettingsPage> { clickEnableSwitch() }
+ device.pressBack()
+ device.pressBack()
+ }
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LogoutTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LogoutTest.kt
index af03c462c6..f99cfc5161 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LogoutTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LogoutTest.kt
@@ -1,8 +1,8 @@
package net.mullvad.mullvadvpn.test.e2e
import net.mullvad.mullvadvpn.test.common.page.AccountPage
+import net.mullvad.mullvadvpn.test.common.page.ConnectPage
import net.mullvad.mullvadvpn.test.common.page.LoginPage
-import net.mullvad.mullvadvpn.test.common.page.TopBar
import net.mullvad.mullvadvpn.test.common.page.on
import net.mullvad.mullvadvpn.test.e2e.misc.AccountTestRule
import org.junit.jupiter.api.Test
@@ -17,7 +17,7 @@ class LogoutTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
// Given
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
- on<TopBar> { clickAccount() }
+ on<ConnectPage> { clickAccount() }
on<AccountPage> { clickLogOut() }
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/WebLinkTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/WebLinkTest.kt
index 402939db7a..8d8467392c 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/WebLinkTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/WebLinkTest.kt
@@ -1,9 +1,9 @@
package net.mullvad.mullvadvpn.test.e2e
import net.mullvad.mullvadvpn.test.common.annotation.SkipForFlavors
+import net.mullvad.mullvadvpn.test.common.page.LoginPage
import net.mullvad.mullvadvpn.test.common.page.MullvadWebsite
import net.mullvad.mullvadvpn.test.common.page.SettingsPage
-import net.mullvad.mullvadvpn.test.common.page.TopBar
import net.mullvad.mullvadvpn.test.common.page.on
import org.junit.jupiter.api.Test
@@ -13,7 +13,7 @@ class WebLinkTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
fun testOpenFaqFromApp() {
app.launchAndEnsureOnLoginPage()
- on<TopBar> { clickSettings() }
+ on<LoginPage> { clickSettings() }
on<SettingsPage> { clickFaqAndGuides() }