Skip to content

Commit 18ca09d

Browse files
authored
android: fix MainActivityTest (#550)
-Permissions are shown after 'Get Started' screen, fix ordering in test -Tap 'Authorize Tailscale' -Re-add instrumentation test runner in build.gradle Updates tailscale/corp#24242 Signed-off-by: kari-ts <[email protected]>
1 parent bd745b5 commit 18ca09d

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

android/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ android {
3939
targetSdkVersion 34
4040
versionCode 242
4141
versionName getVersionProperty("VERSION_LONG")
42+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
4243

4344
// This setting, which defaults to 'true', will cause Tailscale to fall
4445
// back to the Google DNS servers if it cannot determine what the

android/src/androidTest/kotlin/com/tailscale/ipn/MainActivityTest.kt

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@ import androidx.test.uiautomator.UiSelector
1717
import dev.turingcomplete.kotlinonetimepassword.HmacAlgorithm
1818
import dev.turingcomplete.kotlinonetimepassword.TimeBasedOneTimePasswordConfig
1919
import dev.turingcomplete.kotlinonetimepassword.TimeBasedOneTimePasswordGenerator
20+
import java.net.HttpURLConnection
21+
import java.net.URL
22+
import java.util.concurrent.TimeUnit
23+
import kotlin.time.Duration.Companion.minutes
24+
import kotlin.time.Duration.Companion.seconds
2025
import org.apache.commons.codec.binary.Base32
2126
import org.junit.After
2227
import org.junit.Assert
2328
import org.junit.Before
2429
import org.junit.Rule
2530
import org.junit.Test
2631
import org.junit.runner.RunWith
27-
import java.net.HttpURLConnection
28-
import java.net.URL
29-
import java.util.concurrent.TimeUnit
30-
import kotlin.time.Duration.Companion.minutes
31-
import kotlin.time.Duration.Companion.seconds
3232

3333
@RunWith(AndroidJUnit4::class)
3434
@LargeTest
@@ -59,18 +59,18 @@ class MainActivityTest {
5959
timeStep = 30,
6060
timeStepUnit = TimeUnit.SECONDS)
6161
val githubTOTP = TimeBasedOneTimePasswordGenerator(github2FASecret, config)
62-
6362
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
64-
Log.d(TAG, "Wait for VPN permission prompt and accept")
65-
device.find(By.text("Connection request"))
66-
device.find(By.text("OK")).click()
6763

6864
Log.d(TAG, "Click through Get Started screen")
6965
device.find(By.text("Get Started"))
7066
device.find(By.text("Get Started")).click()
7167

68+
Log.d(TAG, "Wait for VPN permission prompt and accept")
69+
device.find(By.text("Connection request"))
70+
device.find(By.text("OK")).click()
71+
7272
asNecessary(
73-
timeout = 2.minutes,
73+
2.minutes,
7474
{
7575
Log.d(TAG, "Log in")
7676
device.find(By.text("Log in")).click()
@@ -93,7 +93,6 @@ class MainActivityTest {
9393
},
9494
{
9595
Log.d(TAG, "Make sure GitHub page has loaded")
96-
device.find(By.text("New to GitHub"))
9796
device.find(By.text("Username or email address"))
9897
device.find(By.text("Sign in"))
9998
},
@@ -115,19 +114,23 @@ class MainActivityTest {
115114
.setText(githubTOTP.generate())
116115
device.find(UiSelector().instance(0).className(Button::class.java)).click()
117116
},
117+
{
118+
Log.d(TAG, "Authorizing Tailscale")
119+
device.find(By.text("Authorize tailscale")).click()
120+
},
118121
{
119122
Log.d(TAG, "Accept Tailscale app")
120123
device.find(By.text("Learn more about OAuth"))
121124
// Sleep a little to give button time to activate
125+
122126
Thread.sleep(5.seconds.inWholeMilliseconds)
123127
device.find(UiSelector().instance(1).className(Button::class.java)).click()
124128
},
125129
{
126130
Log.d(TAG, "Connect device")
127131
device.find(By.text("Connect device"))
128132
device.find(UiSelector().instance(0).className(Button::class.java)).click()
129-
},
130-
)
133+
})
131134

132135
try {
133136
Log.d(TAG, "Accept Permission (Either Storage or Notifications)")

android/src/main/java/com/tailscale/ipn/App.kt

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import android.app.Application
77
import android.app.Notification
88
import android.app.NotificationChannel
99
import android.app.PendingIntent
10+
import android.content.BroadcastReceiver
1011
import android.content.Context
1112
import android.content.Intent
13+
import android.content.IntentFilter
1214
import android.content.SharedPreferences
1315
import android.content.pm.PackageManager
1416
import android.net.ConnectivityManager
@@ -423,10 +425,27 @@ open class UninitializedApp : Application() {
423425
}
424426
}
425427

426-
// Calls stopVPN() followed by startVPN() to restart the VPN.
427428
fun restartVPN() {
429+
// Register a receiver to listen for the completion of stopVPN
430+
TSLog.d("KARI", "hi")
431+
val stopReceiver =
432+
object : BroadcastReceiver() {
433+
override fun onReceive(context: Context?, intent: Intent?) {
434+
// Ensure stop intent is complete
435+
if (intent?.action == IPNService.ACTION_STOP_VPN) {
436+
// Unregister receiver after receiving the broadcast
437+
context?.unregisterReceiver(this)
438+
// Now start the VPN
439+
startVPN()
440+
}
441+
}
442+
}
443+
444+
// Register the receiver before stopping VPN
445+
val intentFilter = IntentFilter(IPNService.ACTION_STOP_VPN)
446+
this.registerReceiver(stopReceiver, intentFilter)
447+
428448
stopVPN()
429-
startVPN()
430449
}
431450

432451
fun createNotificationChannel(id: String, name: String, description: String, importance: Int) {

0 commit comments

Comments
 (0)