summaryrefslogtreecommitdiffhomepage
path: root/android/e2e/src/main
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2022-11-23 17:54:09 +0100
committerAlbin <albin@mullvad.net>2023-01-10 15:32:27 +0100
commitbf287ad5153bb3687afb03370cdea1014b3cef75 (patch)
tree38fb21e35c8108f973853a03fe20273f5dc4c7e7 /android/e2e/src/main
parent14c536c8cf902894188a72c65301659b7cd8256b (diff)
downloadmullvadvpn-bf287ad5153bb3687afb03370cdea1014b3cef75.tar.xz
mullvadvpn-bf287ad5153bb3687afb03370cdea1014b3cef75.zip
Move :e2e project to :test:e2e
Also changes source directory from "java" to "kotlin" which is supported since upgrading the project from AGP 3.x to 7.x.
Diffstat (limited to 'android/e2e/src/main')
-rw-r--r--android/e2e/src/main/AndroidManifest.xml7
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/ConnectionTest.kt32
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/EndToEndTest.kt53
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LaunchAppTest.kt13
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LoginTest.kt58
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/WebLinkTest.kt21
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/Constants.kt6
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/PackageConstants.kt3
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/ResourceConstants.kt5
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TextConstants.kt4
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TimeoutConstants.kt7
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/BundleExtensions.kt8
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/UiAutomatorExtensions.kt55
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/AppInteractor.kt83
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/MullvadAccountInteractor.kt12
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/SystemSettingsInteractor.kt36
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/WebViewInteractor.kt47
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CaptureScreenshotOnFailedTestRule.kt31
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CleanupAccountTestRule.kt21
-rw-r--r--android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/SimpleMullvadHttpClient.kt191
20 files changed, 0 insertions, 693 deletions
diff --git a/android/e2e/src/main/AndroidManifest.xml b/android/e2e/src/main/AndroidManifest.xml
deleted file mode 100644
index 931f79d291..0000000000
--- a/android/e2e/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
-
- <uses-permission android:name="android.permission.INTERNET" />
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="net.mullvad.mullvadvpn" />
-</manifest>
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/ConnectionTest.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/ConnectionTest.kt
deleted file mode 100644
index 4334ae2265..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/ConnectionTest.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.mullvad.mullvadvpn.e2e
-
-import androidx.test.uiautomator.By
-import junit.framework.Assert.assertEquals
-import net.mullvad.mullvadvpn.e2e.extension.findObjectWithTimeout
-import net.mullvad.mullvadvpn.e2e.interactor.WebViewInteractor
-import net.mullvad.mullvadvpn.e2e.misc.CleanupAccountTestRule
-import org.junit.Rule
-import org.junit.Test
-
-class ConnectionTest : EndToEndTest() {
-
- @Rule
- @JvmField
- val cleanupAccountTestRule = CleanupAccountTestRule()
-
- @Test
- fun testConnectAndVerifyWithConnectionCheck() {
- // Given
- app.launchAndEnsureLoggedIn()
-
- // When
- device.findObjectWithTimeout(By.text("Secure my connection")).click()
- device.findObjectWithTimeout(By.text("OK")).click()
- device.findObjectWithTimeout(By.text("SECURE CONNECTION"))
- val expected = WebViewInteractor.ConnCheckState(true, app.extractIpAddress())
-
- // Then
- val result = web.launchAndExtractConnCheckState()
- assertEquals(expected, result)
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/EndToEndTest.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/EndToEndTest.kt
deleted file mode 100644
index d3f3c564b7..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/EndToEndTest.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package net.mullvad.mullvadvpn.e2e
-
-import android.content.Context
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.UiDevice
-import net.mullvad.mullvadvpn.e2e.constant.INVALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY
-import net.mullvad.mullvadvpn.e2e.constant.VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY
-import net.mullvad.mullvadvpn.e2e.extension.getRequiredArgument
-import net.mullvad.mullvadvpn.e2e.interactor.AppInteractor
-import net.mullvad.mullvadvpn.e2e.interactor.WebViewInteractor
-import net.mullvad.mullvadvpn.e2e.misc.CaptureScreenshotOnFailedTestRule
-import org.junit.Before
-import org.junit.Rule
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-abstract class EndToEndTest {
-
- @Rule
- @JvmField
- val rule = CaptureScreenshotOnFailedTestRule()
-
- lateinit var device: UiDevice
- lateinit var targetContext: Context
- lateinit var app: AppInteractor
- lateinit var web: WebViewInteractor
- lateinit var validTestAccountToken: String
- lateinit var invalidTestAccountToken: String
-
- @Before
- fun setup() {
- device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- targetContext = InstrumentationRegistry.getInstrumentation().targetContext
-
- validTestAccountToken = InstrumentationRegistry.getArguments()
- .getRequiredArgument(VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
- invalidTestAccountToken = InstrumentationRegistry.getArguments()
- .getRequiredArgument(INVALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
-
- app = AppInteractor(
- device,
- targetContext,
- validTestAccountToken,
- invalidTestAccountToken
- )
-
- web = WebViewInteractor(
- targetContext,
- device
- )
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LaunchAppTest.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LaunchAppTest.kt
deleted file mode 100644
index c873d3452c..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LaunchAppTest.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package net.mullvad.mullvadvpn.e2e
-
-import androidx.test.runner.AndroidJUnit4
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class LaunchAppTest : EndToEndTest() {
- @Test
- fun testLaunchApp() {
- app.launch()
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LoginTest.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LoginTest.kt
deleted file mode 100644
index 4919fb823f..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/LoginTest.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package net.mullvad.mullvadvpn.e2e
-
-import androidx.test.runner.AndroidJUnit4
-import androidx.test.uiautomator.By
-import junit.framework.Assert.assertNotNull
-import net.mullvad.mullvadvpn.e2e.constant.LOGIN_FAILURE_TIMEOUT
-import net.mullvad.mullvadvpn.e2e.extension.findObjectWithTimeout
-import net.mullvad.mullvadvpn.e2e.misc.CleanupAccountTestRule
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class LoginTest : EndToEndTest() {
-
- @Rule
- @JvmField
- val cleanupAccountTestRule = CleanupAccountTestRule()
-
- @Test
- fun testLoginWithInvalidCredentials() {
- // Given
- val invalidDummyAccountToken = invalidTestAccountToken
-
- // When
- app.launch()
- app.attemptLogin(invalidDummyAccountToken)
-
- // Then
- device.findObjectWithTimeout(By.text("Login failed"), LOGIN_FAILURE_TIMEOUT)
- }
-
- @Test
- fun testLoginWithValidCredentials() {
- // Given
- val token = validTestAccountToken
-
- // When
- app.launchAndEnsureLoggedIn(token)
-
- // Then
- app.ensureLoggedIn()
- }
-
- @Test
- fun testLogout() {
- // Given
- app.launchAndEnsureLoggedIn()
-
- // When
- app.clickSettingsCog()
- app.clickListItemByText("Account")
- app.clickActionButtonByText("Log out")
-
- // Then
- assertNotNull(device.findObjectWithTimeout(By.text("Login")))
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/WebLinkTest.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/WebLinkTest.kt
deleted file mode 100644
index aaff57de65..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/WebLinkTest.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.mullvad.mullvadvpn.e2e
-
-import androidx.test.uiautomator.By
-import net.mullvad.mullvadvpn.e2e.extension.findObjectWithTimeout
-import org.junit.Test
-
-class WebLinkTest : EndToEndTest() {
- @Test
- fun testOpenFaqFromApp() {
- // Given
- app.launch()
-
- // When
- device.findObjectWithTimeout(By.text("Login"))
- app.clickSettingsCog()
- app.clickListItemByText("FAQs & Guides")
-
- // Then
- device.findObjectWithTimeout(By.text("Mullvad help center"))
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/Constants.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/Constants.kt
deleted file mode 100644
index 3b6a04b51e..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/Constants.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.constant
-
-const val LOG_TAG = "mullvad-e2e"
-const val CONN_CHECK_URL = "https://mullvad.net/en/check/"
-const val VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY = "valid_test_account_token"
-const val INVALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY = "invalid_test_account_token"
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/PackageConstants.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/PackageConstants.kt
deleted file mode 100644
index 47aeaa0237..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/PackageConstants.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.constant
-
-const val MULLVAD_PACKAGE = "net.mullvad.mullvadvpn"
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/ResourceConstants.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/ResourceConstants.kt
deleted file mode 100644
index 07b2f03311..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/ResourceConstants.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.constant
-
-const val SETTINGS_COG_ID = "net.mullvad.mullvadvpn:id/settings"
-const val TUNNEL_INFO_ID = "net.mullvad.mullvadvpn:id/tunnel_info"
-const val TUNNEL_OUT_ADDRESS_ID = "net.mullvad.mullvadvpn:id/out_address"
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TextConstants.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TextConstants.kt
deleted file mode 100644
index ff8e0088d4..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TextConstants.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.constant
-
-const val CONNECTION_CHECK_IS_CONNECTED = "Using Mullvad VPN"
-const val CONNECTION_CHECK_IS_NOT_CONNECTED = "Not using Mullvad VPN"
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TimeoutConstants.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TimeoutConstants.kt
deleted file mode 100644
index ecc70c28b1..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/constant/TimeoutConstants.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.constant
-
-const val APP_LAUNCH_TIMEOUT = 5000L
-const val CONNECTION_TIMEOUT = 30000L
-const val DEFAULT_INTERACTION_TIMEOUT = 3000L
-const val LOGIN_TIMEOUT = 30000L
-const val LOGIN_FAILURE_TIMEOUT = 60000L
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/BundleExtensions.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/BundleExtensions.kt
deleted file mode 100644
index 275bd0b9c7..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/BundleExtensions.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.extension
-
-import android.os.Bundle
-
-fun Bundle.getRequiredArgument(argument: String): String {
- return getString(argument)
- ?: throw IllegalArgumentException("Missing required argument: $argument")
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/UiAutomatorExtensions.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/UiAutomatorExtensions.kt
deleted file mode 100644
index 5ecc16016d..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/extension/UiAutomatorExtensions.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.extension
-
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.BySelector
-import androidx.test.uiautomator.UiDevice
-import androidx.test.uiautomator.UiObject2
-import androidx.test.uiautomator.Until
-import java.util.regex.Pattern
-import net.mullvad.mullvadvpn.e2e.constant.DEFAULT_INTERACTION_TIMEOUT
-
-fun UiDevice.findObjectByCaseInsensitiveText(text: String): UiObject2 {
- return findObjectWithTimeout(By.text(Pattern.compile(text, Pattern.CASE_INSENSITIVE)))
-}
-
-fun UiObject2.findObjectByCaseInsensitiveText(text: String): UiObject2 {
- return findObjectWithTimeout(By.text(Pattern.compile(text, Pattern.CASE_INSENSITIVE)))
-}
-
-fun UiDevice.findObjectWithTimeout(
- selector: BySelector,
- timeout: Long = DEFAULT_INTERACTION_TIMEOUT
-): UiObject2 {
-
- wait(
- Until.hasObject(selector),
- timeout
- )
-
- return try {
- findObject(selector)
- } catch (e: NullPointerException) {
- throw IllegalArgumentException(
- "No matches for selector within timeout ($timeout): $selector"
- )
- }
-}
-
-fun UiObject2.findObjectWithTimeout(
- selector: BySelector,
- timeout: Long = DEFAULT_INTERACTION_TIMEOUT
-): UiObject2 {
-
- wait(
- Until.hasObject(selector),
- timeout
- )
-
- return try {
- findObject(selector)
- } catch (e: NullPointerException) {
- throw IllegalArgumentException(
- "No matches for selector within timeout ($timeout): $selector"
- )
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/AppInteractor.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/AppInteractor.kt
deleted file mode 100644
index 680850e718..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/AppInteractor.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.interactor
-
-import android.content.Context
-import android.content.Intent
-import android.widget.ImageButton
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
-import androidx.test.uiautomator.Until
-import net.mullvad.mullvadvpn.e2e.constant.APP_LAUNCH_TIMEOUT
-import net.mullvad.mullvadvpn.e2e.constant.CONNECTION_TIMEOUT
-import net.mullvad.mullvadvpn.e2e.constant.LOGIN_TIMEOUT
-import net.mullvad.mullvadvpn.e2e.constant.MULLVAD_PACKAGE
-import net.mullvad.mullvadvpn.e2e.constant.SETTINGS_COG_ID
-import net.mullvad.mullvadvpn.e2e.constant.TUNNEL_INFO_ID
-import net.mullvad.mullvadvpn.e2e.constant.TUNNEL_OUT_ADDRESS_ID
-import net.mullvad.mullvadvpn.e2e.extension.findObjectWithTimeout
-
-class AppInteractor(
- private val device: UiDevice,
- private val targetContext: Context,
- private val validTestAccountToken: String,
- private val invalidTestAccountToken: String
-) {
- fun launch() {
- device.pressHome()
- // Wait for launcher
- device.wait(
- Until.hasObject(By.pkg(device.launcherPackageName).depth(0)),
- APP_LAUNCH_TIMEOUT
- )
- val intent =
- targetContext.packageManager.getLaunchIntentForPackage(MULLVAD_PACKAGE)?.apply {
- // Clear out any previous instances
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
- }
- targetContext.startActivity(intent)
- device.wait(
- Until.hasObject(By.pkg(MULLVAD_PACKAGE).depth(0)),
- APP_LAUNCH_TIMEOUT
- )
- }
-
- fun launchAndEnsureLoggedIn(accountToken: String = validTestAccountToken) {
- launch()
- attemptLogin(accountToken)
- ensureLoggedIn()
- }
-
- fun attemptLogin(accountToken: String = validTestAccountToken) {
- device.findObjectWithTimeout(By.text("Login"))
- val loginObject = device.findObjectWithTimeout(By.clazz("android.widget.EditText"))
- .apply { text = accountToken }
- loginObject.parent.findObject(By.clazz(ImageButton::class.java)).click()
- }
-
- fun ensureLoggedIn() {
- device.findObjectWithTimeout(By.text("UNSECURED CONNECTION"), LOGIN_TIMEOUT)
- }
-
- fun extractIpAddress(): String {
- device.findObjectWithTimeout(By.res(TUNNEL_INFO_ID)).click()
- return device.findObjectWithTimeout(
- By.res(TUNNEL_OUT_ADDRESS_ID),
- CONNECTION_TIMEOUT
- ).text.extractIpAddress()
- }
-
- fun clickSettingsCog() {
- device.findObjectWithTimeout(By.res(SETTINGS_COG_ID)).click()
- }
-
- fun clickListItemByText(text: String) {
- device.findObjectWithTimeout(By.text(text)).click()
- }
-
- fun clickActionButtonByText(text: String) {
- device.findObjectWithTimeout(By.text(text)).click()
- }
-
- private fun String.extractIpAddress(): String {
- return split(" ")[1].split(" ")[0]
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/MullvadAccountInteractor.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/MullvadAccountInteractor.kt
deleted file mode 100644
index 08c5a698c3..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/MullvadAccountInteractor.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.interactor
-
-import net.mullvad.mullvadvpn.e2e.misc.SimpleMullvadHttpClient
-
-class MullvadAccountInteractor(
- private val httpClient: SimpleMullvadHttpClient,
- private val testAccountToken: String
-) {
- fun cleanupAccount() {
- httpClient.removeAllDevices(testAccountToken)
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/SystemSettingsInteractor.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/SystemSettingsInteractor.kt
deleted file mode 100644
index 29cef35b0a..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/SystemSettingsInteractor.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.interactor
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
-import net.mullvad.mullvadvpn.e2e.extension.findObjectByCaseInsensitiveText
-
-class SystemSettingsInteractor(
- private val uiDevice: UiDevice,
- private val context: Context
-) {
- fun openVpnSettings() {
- val intent = Intent("com.intent.MAIN").apply {
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- intent.component = ComponentName.unflattenFromString(
- "com.android.settings/.Settings\$VpnSettingsActivity"
- )
- context.startActivity(intent)
- Thread.sleep(1000)
- }
-
- fun removeAllVpnPermissions() {
- openVpnSettings()
- uiDevice.findObjects(By.descContains("Settings")).forEach {
- it.click()
- Thread.sleep(1000)
- uiDevice.findObjectByCaseInsensitiveText("forget vpn").click()
- Thread.sleep(1000)
- uiDevice.findObjectByCaseInsensitiveText("forget").click()
- }
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/WebViewInteractor.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/WebViewInteractor.kt
deleted file mode 100644
index df5afc4605..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/interactor/WebViewInteractor.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.interactor
-
-import android.content.Context
-import android.content.Intent
-import android.view.View
-import android.webkit.WebView
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.UiDevice
-import net.mullvad.mullvadvpn.TestActivity
-import net.mullvad.mullvadvpn.e2e.constant.CONNECTION_CHECK_IS_CONNECTED
-import net.mullvad.mullvadvpn.e2e.constant.CONN_CHECK_URL
-import net.mullvad.mullvadvpn.e2e.extension.findObjectByCaseInsensitiveText
-import net.mullvad.mullvadvpn.e2e.extension.findObjectWithTimeout
-
-class WebViewInteractor(
- private val context: Context,
- private val device: UiDevice
-) {
- fun launchWebView(context: Context, url: String) {
- val intent = Intent(context, TestActivity::class.java).apply {
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- putExtra("url", url)
- }
- context.startActivity(intent)
- }
-
- fun launchAndExtractConnCheckState(): ConnCheckState {
- launchWebView(context, CONN_CHECK_URL)
- val webView = device.findObjectWithTimeout(By.clazz(WebView::class.java))
- val stateText = device.findObjectByCaseInsensitiveText("using Mullvad VPN").apply {
- click()
- }
-
- // Wait for view to expand after click.
- Thread.sleep(1000)
-
- val wireGuardIpv4ConnectionRow = webView.findObjects(By.clazz(View::class.java))
- .first { it.text?.endsWith("(WireGuard)") == true }
- val wireGuardIpv4Address = wireGuardIpv4ConnectionRow.text.split(" ")[0].trim()
- return ConnCheckState(stateText.text == CONNECTION_CHECK_IS_CONNECTED, wireGuardIpv4Address)
- }
-
- data class ConnCheckState(
- val isConnected: Boolean,
- val ipAddress: String
- )
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CaptureScreenshotOnFailedTestRule.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CaptureScreenshotOnFailedTestRule.kt
deleted file mode 100644
index 82c43c958b..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CaptureScreenshotOnFailedTestRule.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.misc
-
-import android.util.Log
-import androidx.test.runner.screenshot.BasicScreenCaptureProcessor
-import androidx.test.runner.screenshot.ScreenCaptureProcessor
-import androidx.test.runner.screenshot.Screenshot
-import java.time.LocalDateTime
-import java.time.format.DateTimeFormatter
-import net.mullvad.mullvadvpn.e2e.constant.LOG_TAG
-import org.junit.rules.TestWatcher
-import org.junit.runner.Description
-
-class CaptureScreenshotOnFailedTestRule : TestWatcher() {
- override fun failed(e: Throwable?, description: Description?) {
- Log.d(LOG_TAG, "Capturing screenshot of failed test: " + description?.methodName)
- val timestamp = DateTimeFormatter.ISO_DATE_TIME.format(LocalDateTime.now()).replace(":", "")
- val screenshotName = "$timestamp-${description?.methodName}"
- captureScreenshot(screenshotName)
- }
-
- private fun captureScreenshot(screenShotName: String) {
- try {
- val screenCapture = Screenshot.capture().apply { name = screenShotName }
- val processorSet: MutableSet<ScreenCaptureProcessor> = HashSet()
- processorSet.add(BasicScreenCaptureProcessor())
- screenCapture.process(processorSet)
- } catch (ex: Exception) {
- Log.d(LOG_TAG, "Error capturing screenshot: " + ex.message)
- }
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CleanupAccountTestRule.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CleanupAccountTestRule.kt
deleted file mode 100644
index 17f7f86f6c..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/CleanupAccountTestRule.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.misc
-
-import android.util.Log
-import androidx.test.platform.app.InstrumentationRegistry
-import net.mullvad.mullvadvpn.e2e.constant.LOG_TAG
-import net.mullvad.mullvadvpn.e2e.constant.VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY
-import net.mullvad.mullvadvpn.e2e.extension.getRequiredArgument
-import net.mullvad.mullvadvpn.e2e.interactor.MullvadAccountInteractor
-import org.junit.rules.TestWatcher
-import org.junit.runner.Description
-
-class CleanupAccountTestRule : TestWatcher() {
- override fun starting(description: Description?) {
- Log.d(LOG_TAG, "Cleaning up account before test: ${description?.methodName}")
- val targetContext = InstrumentationRegistry.getInstrumentation().targetContext
- val validTestAccountToken = InstrumentationRegistry.getArguments()
- .getRequiredArgument(VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
- MullvadAccountInteractor(SimpleMullvadHttpClient(targetContext), validTestAccountToken)
- .cleanupAccount()
- }
-}
diff --git a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/SimpleMullvadHttpClient.kt b/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/SimpleMullvadHttpClient.kt
deleted file mode 100644
index ebd90f1bac..0000000000
--- a/android/e2e/src/main/java/net/mullvad/mullvadvpn/e2e/misc/SimpleMullvadHttpClient.kt
+++ /dev/null
@@ -1,191 +0,0 @@
-package net.mullvad.mullvadvpn.e2e.misc
-
-import android.content.Context
-import android.util.Log
-import androidx.test.services.events.TestEventException
-import com.android.volley.Request
-import com.android.volley.toolbox.JsonArrayRequest
-import com.android.volley.toolbox.JsonObjectRequest
-import com.android.volley.toolbox.RequestFuture
-import com.android.volley.toolbox.StringRequest
-import com.android.volley.toolbox.Volley
-import net.mullvad.mullvadvpn.e2e.BuildConfig
-import net.mullvad.mullvadvpn.e2e.constant.LOG_TAG
-import org.json.JSONArray
-import org.json.JSONObject
-
-class SimpleMullvadHttpClient(context: Context) {
-
- private val queue = Volley.newRequestQueue(context)
-
- fun removeAllDevices(accountToken: String) {
- Log.v(LOG_TAG, "Remove all devices")
- val token = login(accountToken)
- val devices = getDeviceList(token)
- devices.forEach {
- removeDevice(token, it)
- }
- Log.v(LOG_TAG, "All devices removed")
- }
-
- fun login(accountToken: String): String {
- Log.v(LOG_TAG, "Attempt login with account token: $accountToken")
- val json = JSONObject().apply {
- put("account_number", accountToken)
- }
- return sendSimpleSynchronousRequest(Request.Method.POST, AUTH_URL, json)!!.let { response ->
- response.getString("access_token").also { accessToken ->
- Log.v(LOG_TAG, "Successfully logged in and received access token: $accessToken")
- }
- }
- }
-
- fun getDeviceList(accessToken: String): List<String> {
- Log.v(LOG_TAG, "Get devices")
-
- val response = sendSimpleSynchronousRequestArray(
- Request.Method.GET,
- DEVICE_LIST_URL,
- token = accessToken
- )
-
- return response!!.iterator<JSONObject>().asSequence().toList()
- .also {
- it
- .map { jsonObject ->
- jsonObject.getString("name")
- }
- .also { deviceNames ->
- Log.v(LOG_TAG, "Devices received: $deviceNames")
- }
- }
- .map { it.getString("id") }
- .toList()
- }
-
- fun removeDevice(token: String, deviceId: String) {
- Log.v(LOG_TAG, "Remove device: $deviceId")
- sendSimpleSynchronousRequestString(
- Request.Method.DELETE,
- "$DEVICE_LIST_URL/$deviceId",
- token = token
- )
- }
-
- private fun sendSimpleSynchronousRequest(
- method: Int,
- url: String,
- body: JSONObject? = null,
- token: String? = null
- ): JSONObject? {
- val future = RequestFuture.newFuture<JSONObject>()
- val request = object : JsonObjectRequest(
- method,
- url,
- body,
- future,
- future
- ) {
- override fun getHeaders(): MutableMap<String, String> {
- val headers = HashMap<String, String>()
- if (body != null) {
- headers.put("Content-Type", "application/json")
- }
- if (token != null) {
- headers.put("Authorization", "Bearer $token")
- }
- return headers
- }
- }
- queue.add(request)
- return try {
- future.get().also { response ->
- Log.v(LOG_TAG, "Json object request response: $response")
- }
- } catch (e: Exception) {
- Log.v(LOG_TAG, "Json object request error: ${e.message}")
- throw TestEventException(REQUEST_ERROR_MESSAGE)
- }
- }
-
- private fun sendSimpleSynchronousRequestString(
- method: Int,
- url: String,
- body: String? = null,
- token: String? = null
- ): String? {
- val future = RequestFuture.newFuture<String>()
- val request = object : StringRequest(
- method,
- url,
- future,
- future
- ) {
- override fun getHeaders(): MutableMap<String, String> {
- val headers = HashMap<String, String>()
- if (body != null) {
- headers.put("Content-Type", "application/json")
- }
- if (token != null) {
- headers.put("Authorization", "Bearer $token")
- }
- return headers
- }
- }
- queue.add(request)
- return try {
- future.get().also { response ->
- Log.v(LOG_TAG, "String request response: $response")
- }
- } catch (e: Exception) {
- Log.v(LOG_TAG, "String request error: ${e.message}")
- throw TestEventException(REQUEST_ERROR_MESSAGE)
- }
- }
-
- private fun sendSimpleSynchronousRequestArray(
- method: Int,
- url: String,
- body: JSONArray? = null,
- token: String? = null
- ): JSONArray? {
- val future = RequestFuture.newFuture<JSONArray>()
- val request = object : JsonArrayRequest(
- method,
- url,
- null,
- future,
- future
- ) {
- override fun getHeaders(): MutableMap<String, String> {
- val headers = HashMap<String, String>()
- headers.put("Content-Type", "application/json")
- if (token != null) {
- headers.put("Authorization", "Bearer $token")
- }
- return headers
- }
- }
- queue.add(request)
- return try {
- future.get().also { response ->
- Log.v(LOG_TAG, "Json array request response: $response")
- }
- } catch (e: Exception) {
- Log.v(LOG_TAG, "Json array request error: ${e.message}")
- throw TestEventException(REQUEST_ERROR_MESSAGE)
- }
- }
-
- operator fun <T> JSONArray.iterator(): Iterator<T> =
- (0 until this.length()).asSequence().map { this.get(it) as T }.iterator()
-
- companion object {
- private const val AUTH_URL =
- "${BuildConfig.API_BASE_URL}/auth/${BuildConfig.API_VERSION}/token"
- private const val DEVICE_LIST_URL =
- "${BuildConfig.API_BASE_URL}/accounts/${BuildConfig.API_VERSION}/devices"
- private const val REQUEST_ERROR_MESSAGE =
- "Unable to verify account due to invalid account or connectivity issues."
- }
-}