diff options
| author | Niklas Berglund <niklas.berglund@gmail.com> | 2024-12-13 17:31:37 +0100 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2025-01-13 11:04:24 +0100 |
| commit | dd3ee9577ff3e99b048a8653ad0a393e47169ac2 (patch) | |
| tree | bf71258782b3d5241859eb9206f28b71f0f6ac3d | |
| parent | faf8f909b83af3401920485dbfc816ffd55d5cb7 (diff) | |
| download | mullvadvpn-dd3ee9577ff3e99b048a8653ad0a393e47169ac2.tar.xz mullvadvpn-dd3ee9577ff3e99b048a8653ad0a393e47169ac2.zip | |
Add leak test for when VPN settings change
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() } |
