summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2024-11-18 11:47:19 +0100
committerDavid Göransson <david.goransson@mullvad.net>2024-11-18 11:47:19 +0100
commit7d76afdaaf12b3fa7f8bd7930a8d105379d165f1 (patch)
tree73cb9eab1305d8d0a8cd06a492e6f070e53e0f59
parent13762774687abf4d68c17e36d1cbb105b0a098d2 (diff)
parentb14b0bf4dead7538af5f04409318e282ed06e1af (diff)
downloadmullvadvpn-7d76afdaaf12b3fa7f8bd7930a8d105379d165f1.tar.xz
mullvadvpn-7d76afdaaf12b3fa7f8bd7930a8d105379d165f1.zip
Merge branch 'verify-that-leak-test-catch-leaks-droid-1458'
-rwxr-xr-xandroid/scripts/run-instrumented-tests.sh4
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt3
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/ForgetAllVpnAppsInSettingsTestRule.kt45
-rw-r--r--android/test/e2e/build.gradle.kts10
-rw-r--r--android/test/e2e/e2e.properties2
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LeakTest.kt12
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt10
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HighlyRateLimited.kt12
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/constant/Constants.kt3
9 files changed, 71 insertions, 30 deletions
diff --git a/android/scripts/run-instrumented-tests.sh b/android/scripts/run-instrumented-tests.sh
index fb80995739..055112fb43 100755
--- a/android/scripts/run-instrumented-tests.sh
+++ b/android/scripts/run-instrumented-tests.sh
@@ -132,8 +132,8 @@ case "$TEST_TYPE" in
echo "Error: The variable PARTNER_AUTH or VALID_TEST_ACCOUNT_NUMBER must be set."
exit 1
fi
- OPTIONAL_TEST_ARGUMENTS+=" -e ENABLE_HIGHLY_RATE_LIMITED_TESTS $ENABLE_HIGHLY_RATE_LIMITED_TESTS"
- OPTIONAL_TEST_ARGUMENTS+=" -e ENABLE_ACCESS_TO_LOCAL_API_TESTS $ENABLE_ACCESS_TO_LOCAL_API_TESTS"
+ OPTIONAL_TEST_ARGUMENTS+=" -e enable_access_to_local_api_tests $ENABLE_ACCESS_TO_LOCAL_API_TESTS"
+ OPTIONAL_TEST_ARGUMENTS+=" -e enable_highly_rate_limited_tests $ENABLE_HIGHLY_RATE_LIMITED_TESTS"
USE_ORCHESTRATOR="true"
PACKAGE_NAME="net.mullvad.mullvadvpn"
if [[ "$INFRA_FLAVOR" =~ ^(devmole|stagemole)$ ]]; then
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt
index 143f4355d3..ff17a9f497 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt
@@ -17,6 +17,9 @@ fun UiObject2.findObjectByCaseInsensitiveText(text: String): UiObject2 {
return findObjectWithTimeout(By.text(Pattern.compile(text, Pattern.CASE_INSENSITIVE)))
}
+fun UiDevice.hasObjectWithTimeout(selector: BySelector, timeout: Long = DEFAULT_TIMEOUT): Boolean =
+ wait(Until.hasObject(selector), timeout)
+
fun UiDevice.findObjectWithTimeout(
selector: BySelector,
timeout: Long = DEFAULT_TIMEOUT,
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/ForgetAllVpnAppsInSettingsTestRule.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/ForgetAllVpnAppsInSettingsTestRule.kt
index eea44a7b98..c96718da61 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/ForgetAllVpnAppsInSettingsTestRule.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/ForgetAllVpnAppsInSettingsTestRule.kt
@@ -5,11 +5,16 @@ import android.provider.Settings
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.UiObject2
+import androidx.test.uiautomator.Until
import java.util.regex.Pattern
+import net.mullvad.mullvadvpn.test.common.constant.DEFAULT_TIMEOUT
import net.mullvad.mullvadvpn.test.common.extension.findObjectByCaseInsensitiveText
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
+import net.mullvad.mullvadvpn.test.common.extension.hasObjectWithTimeout
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback
import org.junit.jupiter.api.extension.ExtensionContext
+import org.junit.jupiter.api.fail
class ForgetAllVpnAppsInSettingsTestRule : BeforeTestExecutionCallback {
override fun beforeTestExecution(context: ExtensionContext) {
@@ -20,22 +25,40 @@ class ForgetAllVpnAppsInSettingsTestRule : BeforeTestExecutionCallback {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
)
- val vpnSettingsButtons =
- device.findObjects(By.res(SETTINGS_PACKAGE, VPN_SETTINGS_BUTTON_ID))
- vpnSettingsButtons.forEach { button ->
- button.click()
- try {
- device.findObjectWithTimeout(By.text(FORGET_VPN_VPN_BUTTON_TEXT)).click()
- device.findObjectByCaseInsensitiveText(FORGET_VPN_VPN_CONFIRM_BUTTON_TEXT).click()
- } catch (_: Exception) {
- device.findObjectWithTimeout(By.text(DELETE_VPN_PROFILE_TEXT)).click()
- device.findObjectWithTimeout(By.text(DELETE_VPN_CONFIRM_BUTTON_TEXT_REGEXP)).click()
+ val vpnSettingsSelector = By.res(SETTINGS_PACKAGE, VPN_SETTINGS_BUTTON_ID)
+ device.wait(Until.hasObject(vpnSettingsSelector), DEFAULT_TIMEOUT)
+ val vpnSettingsButtons = device.findObjects(vpnSettingsSelector)
+
+ vpnSettingsButtons
+ .filter { !it.isHardcodedVpn() }
+ .forEach { button ->
+ button.click()
+
+ if (device.hasObjectWithTimeout(By.text(FORGET_VPN_VPN_BUTTON_TEXT))) {
+ device.findObjectWithTimeout(By.text(FORGET_VPN_VPN_BUTTON_TEXT)).click()
+ device
+ .findObjectByCaseInsensitiveText(FORGET_VPN_VPN_CONFIRM_BUTTON_TEXT)
+ .click()
+ } else if (device.hasObjectWithTimeout(By.text(DELETE_VPN_PROFILE_TEXT))) {
+ device.findObjectWithTimeout(By.text(DELETE_VPN_PROFILE_TEXT)).click()
+ device
+ .findObjectWithTimeout(By.text(DELETE_VPN_CONFIRM_BUTTON_TEXT_REGEXP))
+ .click()
+ } else {
+ fail("Unable to find forget or delete button")
+ }
}
- }
}
+ private fun UiObject2.isHardcodedVpn(): Boolean =
+ parent.parent.children.any { uiObject ->
+ HARDCODED_VPN_PROFILE_NAMES.any { uiObject.hasObject(By.text(it)) }
+ }
+
companion object {
+ private val HARDCODED_VPN_PROFILE_NAMES = listOf("VPN by Google")
+
private const val FORGET_VPN_VPN_BUTTON_TEXT = "Forget VPN"
private const val DELETE_VPN_PROFILE_TEXT = "Delete VPN profile"
private const val FORGET_VPN_VPN_CONFIRM_BUTTON_TEXT = "Forget"
diff --git a/android/test/e2e/build.gradle.kts b/android/test/e2e/build.gradle.kts
index e8c5cae6d5..4b1b2b9d60 100644
--- a/android/test/e2e/build.gradle.kts
+++ b/android/test/e2e/build.gradle.kts
@@ -24,15 +24,17 @@ android {
targetProjectPath = ":app"
fun Properties.addRequiredPropertyAsBuildConfigField(name: String) {
- val value = getProperty(name) ?: throw GradleException("Missing property: $name")
+ val value =
+ System.getenv(name)
+ ?: getProperty(name)
+ ?: throw GradleException("Missing property: $name")
+
buildConfigField(type = "String", name = name, value = "\"$value\"")
}
Properties().apply {
load(project.file("e2e.properties").inputStream())
addRequiredPropertyAsBuildConfigField("API_VERSION")
- addRequiredPropertyAsBuildConfigField("ENABLE_HIGHLY_RATE_LIMITED_TESTS")
- addRequiredPropertyAsBuildConfigField("ENABLE_ACCESS_TO_LOCAL_API_TESTS")
addRequiredPropertyAsBuildConfigField("TRAFFIC_GENERATION_IP_ADDRESS")
addRequiredPropertyAsBuildConfigField("PACKET_CAPTURE_API_HOST")
}
@@ -50,6 +52,8 @@ android {
testInstrumentationRunnerArguments +=
mutableMapOf<String, String>().apply {
put("clearPackageData", "true")
+ addOptionalPropertyAsArgument("enable_access_to_local_api_tests")
+ addOptionalPropertyAsArgument("enable_highly_rate_limited_tests")
addOptionalPropertyAsArgument("valid_test_account_number")
addOptionalPropertyAsArgument("invalid_test_account_number")
}
diff --git a/android/test/e2e/e2e.properties b/android/test/e2e/e2e.properties
index 5f880bd2c1..db9bdd29a5 100644
--- a/android/test/e2e/e2e.properties
+++ b/android/test/e2e/e2e.properties
@@ -1,5 +1,3 @@
API_VERSION=v1
-ENABLE_HIGHLY_RATE_LIMITED_TESTS=false
-ENABLE_ACCESS_TO_LOCAL_API_TESTS=false
TRAFFIC_GENERATION_IP_ADDRESS=45.83.223.209
PACKET_CAPTURE_API_HOST=192.168.105.1
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 df2c3c0e15..406671d346 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
@@ -62,9 +62,9 @@ class LeakTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
val targetPort = 80
device.findObjectWithTimeout(By.res(SELECT_LOCATION_BUTTON_TEST_TAG)).click()
- clickLocationExpandButton((EndToEndTest.DEFAULT_COUNTRY))
- clickLocationExpandButton((EndToEndTest.DEFAULT_CITY))
- device.findObjectWithTimeout(By.text(EndToEndTest.DEFAULT_RELAY)).click()
+ clickLocationExpandButton(DEFAULT_COUNTRY)
+ clickLocationExpandButton(DEFAULT_CITY)
+ device.findObjectWithTimeout(By.text(DEFAULT_RELAY)).click()
device.findObjectWithTimeout(By.text("OK")).click()
device.findObjectWithTimeout(By.text("CONNECTED"), VERY_LONG_TIMEOUT)
@@ -100,9 +100,9 @@ class LeakTest : EndToEndTest(BuildConfig.FLAVOR_infrastructure) {
device.findObjectWithTimeout(By.res(SELECT_LOCATION_BUTTON_TEST_TAG)).click()
delay(1000.milliseconds)
- clickLocationExpandButton((EndToEndTest.DEFAULT_COUNTRY))
- clickLocationExpandButton((EndToEndTest.DEFAULT_CITY))
- device.findObjectWithTimeout(By.text(EndToEndTest.DEFAULT_RELAY)).click()
+ clickLocationExpandButton(DEFAULT_COUNTRY)
+ clickLocationExpandButton(DEFAULT_CITY)
+ device.findObjectWithTimeout(By.text(DEFAULT_RELAY)).click()
device.findObjectWithTimeout(By.text("OK")).click()
device.findObjectWithTimeout(By.text("CONNECTED"), VERY_LONG_TIMEOUT)
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt
index 9aa876abcd..c6c9a70ee9 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HasDependencyOnLocalAPI.kt
@@ -1,6 +1,8 @@
package net.mullvad.mullvadvpn.test.e2e.annotations
-import net.mullvad.mullvadvpn.test.e2e.BuildConfig
+import androidx.test.platform.app.InstrumentationRegistry
+import net.mullvad.mullvadvpn.test.e2e.constant.ENABLE_ACCESS_TO_LOCAL_API_TESTS
+import net.mullvad.mullvadvpn.test.e2e.extension.getRequiredArgument
import org.junit.jupiter.api.extension.ConditionEvaluationResult
import org.junit.jupiter.api.extension.ExecutionCondition
import org.junit.jupiter.api.extension.ExtendWith
@@ -17,7 +19,11 @@ annotation class HasDependencyOnLocalAPI {
override fun evaluateExecutionCondition(
context: ExtensionContext?
): ConditionEvaluationResult {
- val enable = BuildConfig.ENABLE_ACCESS_TO_LOCAL_API_TESTS.toBoolean() ?: false
+
+ val enable =
+ InstrumentationRegistry.getArguments()
+ .getRequiredArgument(ENABLE_ACCESS_TO_LOCAL_API_TESTS)
+ .toBoolean()
return if (enable) {
ConditionEvaluationResult.enabled(
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HighlyRateLimited.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HighlyRateLimited.kt
index 27b139a5a8..12280fcaf1 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HighlyRateLimited.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/annotations/HighlyRateLimited.kt
@@ -1,6 +1,8 @@
package net.mullvad.mullvadvpn.test.e2e.annotations
-import net.mullvad.mullvadvpn.test.e2e.BuildConfig
+import androidx.test.platform.app.InstrumentationRegistry
+import net.mullvad.mullvadvpn.test.e2e.constant.ENABLE_HIGHLY_RATE_LIMITED_TESTS
+import net.mullvad.mullvadvpn.test.e2e.extension.getRequiredArgument
import org.junit.jupiter.api.extension.ConditionEvaluationResult
import org.junit.jupiter.api.extension.ExecutionCondition
import org.junit.jupiter.api.extension.ExtendWith
@@ -17,10 +19,12 @@ annotation class HighlyRateLimited {
override fun evaluateExecutionCondition(
context: ExtensionContext?
): ConditionEvaluationResult {
- val enableHighlyRateLimited =
- BuildConfig.ENABLE_HIGHLY_RATE_LIMITED_TESTS.toBoolean() ?: false
+ val enable =
+ InstrumentationRegistry.getArguments()
+ .getRequiredArgument(ENABLE_HIGHLY_RATE_LIMITED_TESTS)
+ .toBoolean()
- return if (enableHighlyRateLimited) {
+ return if (enable) {
ConditionEvaluationResult.enabled("Running test highly affected by rate limiting.")
} else {
ConditionEvaluationResult.disabled(
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/constant/Constants.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/constant/Constants.kt
index baf3dcae3d..0c221f8ddf 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/constant/Constants.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/constant/Constants.kt
@@ -4,3 +4,6 @@ const val LOG_TAG = "mullvad-e2e"
const val PARTNER_AUTH = "partner_auth"
const val VALID_TEST_ACCOUNT_NUMBER_ARGUMENT_KEY = "valid_test_account_number"
const val INVALID_TEST_ACCOUNT_NUMBER_ARGUMENT_KEY = "invalid_test_account_number"
+
+const val ENABLE_ACCESS_TO_LOCAL_API_TESTS = "enable_access_to_local_api_tests"
+const val ENABLE_HIGHLY_RATE_LIMITED_TESTS = "enable_highly_rate_limited_tests"