From 07117211bc98e53b4ec2a6a29b7a8a8927081717 Mon Sep 17 00:00:00 2001 From: Lucas Ribolli Date: Wed, 20 Apr 2022 19:40:12 -0300 Subject: [PATCH 1/2] add Kotlin dependencies --- ui/espresso/RecyclerViewSample/app/build.gradle | 13 +++++++++++++ ui/espresso/RecyclerViewSample/build.gradle | 2 ++ 2 files changed, 15 insertions(+) diff --git a/ui/espresso/RecyclerViewSample/app/build.gradle b/ui/espresso/RecyclerViewSample/app/build.gradle index abc7ba7b9..17328232f 100644 --- a/ui/espresso/RecyclerViewSample/app/build.gradle +++ b/ui/espresso/RecyclerViewSample/app/build.gradle @@ -16,6 +16,10 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + android { compileSdkVersion 30 buildToolsVersion rootProject.buildToolsVersion @@ -40,6 +44,12 @@ android { } } +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { + kotlinOptions { + jvmTarget = "1.8" + } +} + dependencies { // App dependencies implementation 'androidx.annotation:annotation:' + rootProject.androidxAnnotationVersion; @@ -47,8 +57,11 @@ dependencies { implementation 'androidx.multidex:multidex:2.0.1' // Testing-only dependencies + androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"; androidTestImplementation 'androidx.test:core:' + rootProject.coreVersion; + androidTestImplementation 'androidx.test:core-ktx:' + rootProject.coreVersion; androidTestImplementation 'androidx.test.ext:junit:' + rootProject.extJUnitVersion; + androidTestImplementation 'androidx.test.ext:junit-ktx:' + rootProject.extJUnitVersion; androidTestImplementation 'androidx.test:runner:' + rootProject.runnerVersion; androidTestImplementation 'androidx.test.espresso:espresso-core:' + rootProject.espressoVersion; androidTestImplementation 'androidx.test.espresso:espresso-contrib:' + rootProject.espressoVersion; diff --git a/ui/espresso/RecyclerViewSample/build.gradle b/ui/espresso/RecyclerViewSample/build.gradle index 0e31c8118..4a8097aeb 100644 --- a/ui/espresso/RecyclerViewSample/build.gradle +++ b/ui/espresso/RecyclerViewSample/build.gradle @@ -17,6 +17,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlinVersion = "1.6.10" ext.agpVersion = "7.3.0-alpha07" repositories { // Insert local test repo here @@ -25,6 +26,7 @@ buildscript { } dependencies { classpath "com.android.tools.build:gradle:$agpVersion" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From c4a754c1d5cbc0bad562ad43e3825e319f7044a7 Mon Sep 17 00:00:00 2001 From: Lucas Ribolli Date: Wed, 20 Apr 2022 19:40:47 -0300 Subject: [PATCH 2/2] add RecyclerViewSampleKtTest --- .../RecyclerViewSampleKtTest.kt | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 ui/espresso/RecyclerViewSample/app/src/androidTest/java/com/example/android/testing/espresso/RecyclerViewSample/RecyclerViewSampleKtTest.kt diff --git a/ui/espresso/RecyclerViewSample/app/src/androidTest/java/com/example/android/testing/espresso/RecyclerViewSample/RecyclerViewSampleKtTest.kt b/ui/espresso/RecyclerViewSample/app/src/androidTest/java/com/example/android/testing/espresso/RecyclerViewSample/RecyclerViewSampleKtTest.kt new file mode 100644 index 000000000..d954e5756 --- /dev/null +++ b/ui/espresso/RecyclerViewSample/app/src/androidTest/java/com/example/android/testing/espresso/RecyclerViewSample/RecyclerViewSampleKtTest.kt @@ -0,0 +1,81 @@ +package com.example.android.testing.espresso.RecyclerViewSample + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.PerformException +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.contrib.RecyclerViewActions +import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.ext.junit.rules.activityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +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) +@LargeTest +class RecyclerViewSampleKtTest { + + /** + * Use {@link ActivityScenario} to create and launch the activity under test. This is a + * replacement for {@link androidx.test.rule.ActivityTestRule}. + */ + @get:Rule + var activityScenarioRule = activityScenarioRule() + + @Test(expected = PerformException::class) + fun itemWithText_doesNotExist() { + // Attempt to scroll to an item that contains the special text. + onView(withId(R.id.recyclerView)) + // scrollTo will fail the test if no item matches. + .perform(RecyclerViewActions.scrollTo( + hasDescendant(withText("not in the list")) + )) + } + + @Test + fun scrollToItemBelowFold_checkItsText() { + // First scroll to the position that needs to be matched and click on it. + onView(withId(R.id.recyclerView)) + .perform(RecyclerViewActions.actionOnItemAtPosition(ITEM_BELOW_THE_FOLD, click())) + + // Match the text in an item below the fold and check that it's displayed. + val itemElementText = "This is element #${ITEM_BELOW_THE_FOLD}" + onView(withText(itemElementText)).check(matches(isDisplayed())) + } + + @Test + fun itemInMiddleOfList_hasSpecialText() { + // First, scroll to the view holder using the isInTheMiddle matcher. + onView(withId(R.id.recyclerView)) + .perform(RecyclerViewActions.scrollToHolder(isInTheMiddle())) + + // Check that the item has the special text. + val middleElementText = "This is the middle!" + onView(withText(middleElementText)).check(matches(isDisplayed())) + } + + /** + * Matches the {@link CustomAdapter.ViewHolder}s in the middle of the list. + */ + private fun isInTheMiddle(): Matcher { + return object: TypeSafeMatcher() { + override fun matchesSafely(customHolder: CustomAdapter.ViewHolder): Boolean { + return customHolder.isInTheMiddle + } + + override fun describeTo(description: Description) { + description.appendText("item in the middle") + } + } + } + + companion object { + val ITEM_BELOW_THE_FOLD = 40 + } + +} \ No newline at end of file