From 6acbe341eaab840c5f64b25a239264225df96393 Mon Sep 17 00:00:00 2001 From: graial Date: Wed, 6 Mar 2024 06:48:38 +0800 Subject: [PATCH] add first intrumentation test --- demo/build.gradle.kts | 12 ++++ .../turbo/demo/TurboNativeFeatureTest.kt | 72 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 demo/src/androidTest/kotlin/dev/hotwire/turbo/demo/TurboNativeFeatureTest.kt diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index aa81aec5..76dfc4f3 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -25,6 +25,8 @@ android { versionCode = 1 versionName = "1.0" vectorDrawables.useSupportLibrary = true + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildFeatures { @@ -55,6 +57,7 @@ android { sourceSets { named("main") { java { srcDirs("src/main/kotlin") } } named("test") { java { srcDirs("src/test/kotlin") } } + named("androidTest") { java { srcDirs("src/androidTest/kotlin") } } named("debug") { java { srcDirs("src/debug/kotlin") } } } @@ -76,6 +79,15 @@ dependencies { implementation("dev.hotwire:strada:1.0.0-beta3") implementation(project(":turbo")) + + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.ext:junit-ktx:1.1.5") + androidTestImplementation("androidx.test:core-ktx:1.5.0") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation("com.adevinta.android:barista:4.2.0") { + exclude(group = "org.jetbrains.kotlin") // Only if you already use Kotlin in your project + } + androidTestImplementation("androidx.test.espresso:espresso-web:3.5.1") } repositories { diff --git a/demo/src/androidTest/kotlin/dev/hotwire/turbo/demo/TurboNativeFeatureTest.kt b/demo/src/androidTest/kotlin/dev/hotwire/turbo/demo/TurboNativeFeatureTest.kt new file mode 100644 index 00000000..b43b5f9d --- /dev/null +++ b/demo/src/androidTest/kotlin/dev/hotwire/turbo/demo/TurboNativeFeatureTest.kt @@ -0,0 +1,72 @@ +package dev.hotwire.turbo.demo + +import android.view.View +import android.view.ViewGroup +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.web.sugar.Web.onWebView +import androidx.test.espresso.web.webdriver.DriverAtoms.findElement +import androidx.test.espresso.web.webdriver.DriverAtoms.getText +import androidx.test.espresso.web.webdriver.Locator +import androidx.test.ext.junit.rules.activityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed +import com.adevinta.android.barista.internal.matcher.DrawableMatcher.Companion.withDrawable +import dev.hotwire.turbo.demo.main.MainActivity +import junit.framework.TestCase.assertEquals +import org.hamcrest.CoreMatchers.containsString +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.TypeSafeMatcher +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class TurboNativeFeatureTest { + @get:Rule + val activityScenarioRule = + activityScenarioRule() + + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("dev.hotwire.turbo.demo", + appContext.packageName) + } + + @Test + fun displayScreenTitle() { + onView(withId(R.id.app_bar_logo)) + .check(matches(withDrawable(R.drawable.ic_turbo_logo))) + } + + @Test + fun displayMainTurboView() { + onView(withId(R.id.app_bar_logo)) + Thread.sleep(1000) + onWebView().forceJavascriptEnabled() + .withElement(findElement(Locator.LINK_TEXT, "Navigate to another webpage")) + } + + fun nthChildOf(parentMatcher: Matcher, childPosition: Int): Matcher { + return object : TypeSafeMatcher() { + override fun describeTo(description: Description) { + description.appendText("position $childPosition of parent ") + parentMatcher.describeTo(description) + } + + public override fun matchesSafely(view: View): Boolean { + if (view.parent !is ViewGroup) return false + val parent = view.parent as ViewGroup + + return (parentMatcher.matches(parent) + && parent.childCount > childPosition + && parent.getChildAt(childPosition) == view) + } + } + } +}