From be75a1cc46738284e895f5dbac8cc05e06aeb4bb Mon Sep 17 00:00:00 2001 From: Lee Dong-Yeon Date: Thu, 12 Dec 2024 00:49:07 +0900 Subject: [PATCH] Add AndroidView test in Android --- .../eungabi/navigation/CachedWebViewTest.kt | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 eungabi/src/androidTest/kotlin/com/easternkite/eungabi/navigation/CachedWebViewTest.kt diff --git a/eungabi/src/androidTest/kotlin/com/easternkite/eungabi/navigation/CachedWebViewTest.kt b/eungabi/src/androidTest/kotlin/com/easternkite/eungabi/navigation/CachedWebViewTest.kt new file mode 100644 index 0000000..7b88c74 --- /dev/null +++ b/eungabi/src/androidTest/kotlin/com/easternkite/eungabi/navigation/CachedWebViewTest.kt @@ -0,0 +1,114 @@ +package com.easternkite.eungabi.navigation + +import android.content.Context +import android.view.ViewGroup +import android.webkit.WebChromeClient +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.test.isDisplayed +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.performClick +import androidx.compose.ui.viewinterop.AndroidView +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class CachedWebViewTest { + + @get:Rule + val composeRule = createComposeRule() + + @Test + fun cached_webView_test() { + composeRule.setContent { + val controller = rememberEunGabiController() + EunGabiNavHost( + controller = controller, + startDestination = "A" + ) { + composable("A") { + println("it.id = ${it.id}") + Box { + WebView( + id = "A", + url = "https://www.google.com" + ) + Button( + onClick = { controller.navigate("A?url=https://easternkite.medium.com") }, + modifier = Modifier.testTag("Button_A") + ) { + Text("next") + } + } + } + } + } + composeRule.waitForIdle() + composeRule.onNodeWithTag("Button_A") + .performClick() + composeRule.waitForIdle() + composeRule + .onNodeWithTag("Button_A") + .isDisplayed() + } +} + +@Composable +fun WebView( + id: String, + url: String +) { + val context = LocalContext.current + val webView = remember(id, url) { + WebViewManager.getOrCreateWebView(context, id, url) + } + + DisposableEffect(webView) { + onDispose { + (webView.parent as? ViewGroup)?.removeView(webView) + } + } + + AndroidView( + modifier = Modifier.fillMaxSize(), + factory = { + val parent = webView.parent as? ViewGroup + parent?.removeView(webView) + webView + }, + update = { + it.url ?: it.loadUrl(url) + } + ) +} + +object WebViewManager { + private val cache = mutableMapOf() + + fun getOrCreateWebView( + context: Context, + id: String, + url: String + ): WebView { + return cache.getOrPut(id) { + WebView(context).apply { + webViewClient = WebViewClient() + webChromeClient = WebChromeClient() + loadUrl(url) + } + } + } +} \ No newline at end of file