Issue
I'm trying to port the Espresso sample from Java to Kotlin, I got an error for the WebView version
I'm using the name MainActivity.kt
as is, it just simple and works well:
class MainActivity : AppCompatActivity() {
@VisibleForTesting
val keyUrl2Load = "KEY_URL_TO_LOAD"
@VisibleForTesting
val webFormUrl = "file:///android_asset/web_form.html"
private var mWebView: WebView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mWebView = findViewById<View>(R.id.web_view) as WebView
true.also { mWebView!!.settings.javaScriptEnabled = it }
urlFromIntent(intent)?.let { mWebView!!.loadUrl(it) }
mWebView!!.requestFocus()
mWebView!!.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
return false
}
}
}
private fun urlFromIntent(intent: Intent): String? {
val url = intent.getStringExtra(keyUrl2Load)
return if (!TextUtils.isEmpty(url)) url else webFormUrl
}
}
However, the MainActivityTest.kt
looks not that easy to port, as:
package com.example.espressowebview101
import android.content.Intent
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.web.assertion.WebViewAssertions
import androidx.test.espresso.web.sugar.Web
import androidx.test.espresso.web.webdriver.DriverAtoms
import androidx.test.espresso.web.webdriver.Locator
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.hamcrest.Matchers
import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
//https://github.com/android/testing-samples/tree/main/ui/espresso/WebBasicSample/app/src
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
private val MACCHIATO = "Macchiato"
private val DOPPIO = "Doppio"
lateinit var scenario: ActivityScenario<MainActivity>
@get:Rule
var mActivityRule = activityScenarioRule<MainActivity>()
@After
fun enableJS() {
Web.onWebView().forceJavascriptEnabled()
}
@Test
fun typeTextInInput_clickButton_SubmitsForm() {
val intent = withWebFormIntent()
scenario = ActivityScenario.launch(intent)
// Selects the WebView in your layout. If you have multiple WebViews you can also use a
// matcher to select a given WebView, onWebView(withId(R.id.web_view)).
Web.onWebView() // Find the input element by ID
.withElement(DriverAtoms.findElement(Locator.ID, "text_input")) // Clear previous input
.perform(DriverAtoms.clearElement()) // Enter text into the input element
.perform(DriverAtoms.webKeys(MACCHIATO)) // Find the submit button
.withElement(
DriverAtoms.findElement(
Locator.ID,
"submitBtn"
)
) // Simulate a click via javascript
.perform(DriverAtoms.webClick()) // Find the response element by ID
.withElement(
DriverAtoms.findElement(
Locator.ID,
"response"
)
) // Verify that the response page contains the entered text
.check(
WebViewAssertions.webMatches(
DriverAtoms.getText(),
Matchers.containsString(MACCHIATO)
)
)
}
private fun withWebFormIntent(): Intent {
return Intent().also {
val keyUrl2Load = "KEY_URL_TO_LOAD"
val webFormUrl = "file:///android_asset/web_form.html"
it.putExtra(keyUrl2Load, webFormUrl)
}
}
}
And I got error as:
Connected to process 8963 on device 'google-pixel_3_xl-8AJY0LJFQ'.
java.lang.RuntimeException: Unable to resolve activity for: Intent { (has extras) }
at androidx.test.core.app.InstrumentationActivityInvoker.startActivity(InstrumentationActivityInvoker.java:387)
at androidx.test.core.app.InstrumentationActivityInvoker.startActivity(InstrumentationActivityInvoker.java:416)
at androidx.test.core.app.ActivityScenario.launchInternal(ActivityScenario.java:265)
at androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:226)
at com.example.espressowebview101.MainActivityTest.typeTextInInput_clickButton_SubmitsForm(MainActivityTest.kt:36)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:154)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2205)
Solution
You are trying to launch an Intent
which is not related to MainActivity whatsoever. It doesn't know that it should launch this activity.
Your withWebFormIntent
should return an Intent
that tells it to launch MainActivity
.
E.g.
private fun withWebFormIntent(context: Context): Intent {
return Intent(context, MainActivity::class.java).also {
val keyUrl2Load = "KEY_URL_TO_LOAD"
val webFormUrl = "file:///android_asset/web_form.html"
it.putExtra(keyUrl2Load, webFormUrl)
}
}
See this for more documentation on how to construct an intent for an activity.
Answered By - gosr
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.