Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.LocalActivity
import androidx.appcompat.app.AppCompatActivity
import com.mitteloupe.whoami.di.testAppDependenciesEntryPoint
import com.mitteloupe.whoami.test.test.BaseTest.AppLauncher
import com.mitteloupe.whoami.test.launcher.AppLauncher
import com.mitteloupe.whoami.test.launcher.fromComposable
import com.mitteloupe.whoami.test.test.TypedAndroidComposeTestRule
import com.mitteloupe.whoami.ui.main.AppNavHost
import com.mitteloupe.whoami.ui.theme.WhoAmITheme

data class FromScreen<ACTIVITY : ComponentActivity>(
private val composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
private val startDestination: Any
) : AppLauncher() {
private val composableAppLauncher = FromComposable(composeContentTestRule) {
fun <ACTIVITY : ComponentActivity> fromScreen(
composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
startDestination: Any
) = AppLauncher {
fromComposable(composeContentTestRule) {
WhoAmITheme {
val activity = LocalActivity.current as AppCompatActivity
with(testAppDependenciesEntryPoint(activity).appNavHostDependencies) {
Expand All @@ -23,7 +24,5 @@ data class FromScreen<ACTIVITY : ComponentActivity>(
)
}
}
}

override fun launch() = composableAppLauncher.launch()
}.launch()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package com.mitteloupe.whoami.test

import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import com.mitteloupe.whoami.launcher.FromScreen
import com.mitteloupe.whoami.launcher.fromScreen
import com.mitteloupe.whoami.localstore.KEY_VALUE_SAVED_HISTORY
import com.mitteloupe.whoami.screen.HistoryScreen
import com.mitteloupe.whoami.test.annotation.LocalStore
import com.mitteloupe.whoami.test.launcher.AppLauncher
import com.mitteloupe.whoami.test.test.BaseTest
import com.mitteloupe.whoami.test.test.retry
import com.mitteloupe.whoami.ui.main.MainActivity
Expand All @@ -22,16 +23,14 @@ class HistoryHighlightedIpAddressTest : BaseTest() {
override val composeTestRule = createAndroidComposeRule<MainActivity>()

override val startActivityLauncher: AppLauncher by lazy {
FromScreen(composeTestRule, History(highlightedIpAddress = HIGHLIGHTED_IP_ADDRESS))
fromScreen(composeTestRule, History(highlightedIpAddress = HIGHLIGHTED_IP_ADDRESS))
}

@Inject
lateinit var historyScreen: HistoryScreen

@Test
@LocalStore(
localStoreDataIds = [KEY_VALUE_SAVED_HISTORY]
)
@LocalStore(localStoreDataIds = [KEY_VALUE_SAVED_HISTORY])
fun givenSavedHistoryAndHighlightedIpAddressWhenOnHistoryScreenTheSeesHighlight() {
with(historyScreen) {
retry(repeat = 20) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package com.mitteloupe.whoami.test

import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import com.mitteloupe.whoami.launcher.FromScreen
import com.mitteloupe.whoami.launcher.fromScreen
import com.mitteloupe.whoami.localstore.KEY_VALUE_NO_HISTORY
import com.mitteloupe.whoami.localstore.KEY_VALUE_SAVED_HISTORY
import com.mitteloupe.whoami.screen.HistoryScreen
import com.mitteloupe.whoami.test.annotation.LocalStore
import com.mitteloupe.whoami.test.launcher.AppLauncher
import com.mitteloupe.whoami.test.test.BaseTest
import com.mitteloupe.whoami.test.test.doesNot
import com.mitteloupe.whoami.test.test.retry
Expand All @@ -22,7 +23,7 @@ class HistoryTest : BaseTest() {
override val composeTestRule = createAndroidComposeRule<MainActivity>()

override val startActivityLauncher: AppLauncher by lazy {
FromScreen(composeTestRule, History(highlightedIpAddress = null))
fromScreen(composeTestRule, History(highlightedIpAddress = null))
}

@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package com.mitteloupe.whoami.test
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.espresso.intent.Intents
import com.mitteloupe.whoami.launcher.FromScreen
import com.mitteloupe.whoami.launcher.fromScreen
import com.mitteloupe.whoami.screen.HomeScreen
import com.mitteloupe.whoami.screen.OpenSourceNoticesScreen
import com.mitteloupe.whoami.server.REQUEST_RESPONSE_GET_IP
import com.mitteloupe.whoami.server.REQUEST_RESPONSE_GET_IP_DETAILS
import com.mitteloupe.whoami.test.annotation.ServerRequestResponse
import com.mitteloupe.whoami.test.launcher.AppLauncher
import com.mitteloupe.whoami.test.test.BaseTest
import com.mitteloupe.whoami.ui.main.MainActivity
import com.mitteloupe.whoami.ui.main.route.Home
Expand All @@ -22,7 +23,7 @@ class HomeTest : BaseTest() {
override val composeTestRule = createAndroidComposeRule<MainActivity>()

override val startActivityLauncher: AppLauncher by lazy {
FromScreen(composeTestRule, Home)
fromScreen(composeTestRule, Home)
}

@Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.mitteloupe.whoami.test.launcher

fun interface AppLauncher {
fun launch()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.mitteloupe.whoami.test.launcher

import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.compose.runtime.Composable
import com.mitteloupe.whoami.test.test.TypedAndroidComposeTestRule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking

fun <ACTIVITY : ComponentActivity> fromComposable(
composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
composable: @Composable () -> Unit
) = AppLauncher {
val activity = composeContentTestRule.activity
val root = activity.findViewById<ViewGroup>(android.R.id.content)
if (root != null) {
runBlocking(Dispatchers.Main) {
root.removeAllViews()
}
}
composeContentTestRule.setContent(composable)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,19 @@ package com.mitteloupe.whoami.test.test

import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.content.SharedPreferences
import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.annotation.CallSuper
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.IdlingResource as ComposeIdlingResource
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.IdlingResource as EspressoIdlingResource
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
import com.mitteloupe.whoami.test.idlingresource.findAndCloseAppNotRespondingDialog
import com.mitteloupe.whoami.test.idlingresource.registerAppNotRespondingWatcher
import com.mitteloupe.whoami.test.launcher.AppLauncher
import com.mitteloupe.whoami.test.localstore.KeyValueStore
import com.mitteloupe.whoami.test.rule.DisableAnimationsRule
import com.mitteloupe.whoami.test.rule.HiltInjectorRule
Expand All @@ -32,8 +27,6 @@ import com.mitteloupe.whoami.test.server.MockWebServerProvider
import com.mitteloupe.whoami.test.server.ResponseStore
import dagger.hilt.android.testing.HiltAndroidRule
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Rule
Expand All @@ -49,13 +42,13 @@ abstract class BaseTest {
lateinit var mockDispatcher: MockDispatcher

@Inject
lateinit var mockWebServerProvider: MockWebServerProvider
lateinit var responseStore: ResponseStore

@Inject
lateinit var sharedPreferences: SharedPreferences
lateinit var mockWebServerProvider: MockWebServerProvider

@Inject
lateinit var responseStore: ResponseStore
lateinit var sharedPreferences: SharedPreferences

@Inject
lateinit var keyValueStore: KeyValueStore
Expand All @@ -80,8 +73,10 @@ abstract class BaseTest {
)
}

abstract val composeTestRule: ComposeContentTestRule

@get:Rule
open val testRules: RuleChain by lazy {
val testRules: RuleChain by lazy {
@SuppressLint("UnsafeOptInUsageError")
val grantPermissionRule = SdkAwareGrantPermissionRule.grant(
WRITE_EXTERNAL_STORAGE
Expand All @@ -97,8 +92,6 @@ abstract class BaseTest {
.around(grantPermissionRule)
}

abstract val composeTestRule: ComposeContentTestRule

abstract val startActivityLauncher: AppLauncher

@Before
Expand All @@ -116,40 +109,6 @@ abstract class BaseTest {
composeIdlingResources.forEach(composeTestRule::registerIdlingResource)
}

abstract class AppLauncher {
abstract fun launch()

data class FromIntent(private val intent: Intent) : AppLauncher() {
override fun launch() {
ActivityScenario.launch<Activity>(intent)
}
}

data class FromClass<ACTIVITY : Activity>(private val activityClass: Class<out ACTIVITY>) :
AppLauncher() {
@Suppress("UNCHECKED_CAST")
override fun launch() {
ActivityScenario.launch(activityClass) as ActivityScenario<Activity>
}
}

data class FromComposable<ACTIVITY : ComponentActivity>(
private val composeContentTestRule: TypedAndroidComposeTestRule<ACTIVITY>,
private val composable: @Composable () -> Unit
) : AppLauncher() {
override fun launch() {
val activity = composeContentTestRule.activity
val root = activity.findViewById<ViewGroup>(android.R.id.content)
if (root != null) {
runBlocking(Dispatchers.Main) {
root.removeAllViews()
}
}
composeContentTestRule.setContent(composable)
}
}
}

companion object {
@BeforeClass
@CallSuper
Expand Down