Skip to content

Commit

Permalink
Add leak test for when VPN settings change
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasberglund committed Jan 9, 2025
1 parent 8de6bf8 commit 7b6a39b
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -241,6 +242,7 @@ private fun DaitaCell(isDaitaEnabled: Boolean, onDaitaClick: () -> Unit) {
}
),
onCellClicked = onDaitaClick,
modifier = Modifier.testTag(DAITA_CELL_TEST_TAG),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -574,6 +575,7 @@ fun VpnSettingsScreen(
port = state.selectedShadowsSocksObfuscationPort,
onSelected = onSelectObfuscationMode,
onNavigate = navigateToShadowSocksSettings,
testTag = WIREGUARD_OBFUSCATION_SHADOWSOCKS_CELL,
)
}
itemWithDivider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -24,8 +28,11 @@ 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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ 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.TopBar
import net.mullvad.mullvadvpn.test.common.page.VpnSettingsPage
import net.mullvad.mullvadvpn.test.common.page.on

class AppInteractor(
private val device: UiDevice,
Expand Down Expand Up @@ -53,6 +58,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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package net.mullvad.mullvadvpn.test.common.page
import androidx.test.uiautomator.By
import net.mullvad.mullvadvpn.test.common.constant.VERY_LONG_TIMEOUT
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
import net.mullvad.mullvadvpn.test.common.page.TopBar.Companion.TOP_BAR_ACCOUNT_BUTTON
import net.mullvad.mullvadvpn.test.common.page.TopBar.Companion.TOP_BAR_SETTINGS_BUTTON

class ConnectPage internal constructor() : Page() {
private val disconnectSelector = By.text("Disconnect")
Expand All @@ -15,6 +17,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()
}
Expand Down Expand Up @@ -77,6 +87,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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import androidx.test.uiautomator.Until
import net.mullvad.mullvadvpn.test.common.constant.DEFAULT_TIMEOUT
import net.mullvad.mullvadvpn.test.common.constant.EXTREMELY_LONG_TIMEOUT
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
import net.mullvad.mullvadvpn.test.common.page.TopBar.Companion.TOP_BAR_ACCOUNT_BUTTON
import net.mullvad.mullvadvpn.test.common.page.TopBar.Companion.TOP_BAR_SETTINGS_BUTTON

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
}
Expand All @@ -29,4 +35,8 @@ class LoginPage internal constructor() : Page() {
override fun assertIsDisplayed() {
uiDevice.findObjectWithTimeout(loginSelector)
}

companion object {
const val TOP_BAR_SETTINGS_BUTTON = "top_bar_settings_button"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,40 @@ 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)))
Expand All @@ -57,6 +73,10 @@ 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"

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
@ClearFirewallRules
fun testWireGuardObfuscationAutomatic() = runBlocking {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
enableLocalNetworkSharing()
app.enableLocalNetworkSharing()

on<ConnectPage> { clickSelectLocation() }

Expand Down Expand Up @@ -109,7 +109,7 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
@ClearFirewallRules
fun testWireGuardObfuscationOff() = runBlocking {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
enableLocalNetworkSharing()
app.enableLocalNetworkSharing()

on<ConnectPage> { clickSelectLocation() }

Expand All @@ -134,13 +134,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()
Expand All @@ -162,7 +162,7 @@ class ConnectionTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
fun testUDPOverTCP() =
runBlocking<Unit> {
app.launchAndEnsureLoggedIn(accountTestRule.validAccountNumber)
enableLocalNetworkSharing()
app.enableLocalNetworkSharing()

on<ConnectPage> { clickSelectLocation() }

Expand All @@ -187,12 +187,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()
}

Expand All @@ -206,17 +206,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Loading

0 comments on commit 7b6a39b

Please sign in to comment.