Issue#67 Extract ViewActions into Library
This commit is contained in:
parent
a27f19302a
commit
99141c0f17
12 changed files with 46 additions and 40 deletions
|
|
@ -10,14 +10,13 @@ import androidx.test.espresso.matcher.ViewMatchers
|
|||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import org.fnives.test.showcase.R
|
||||
import org.fnives.test.showcase.testutils.configuration.SnackbarVerificationHelper
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.intent.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.snackbar.SnackbarVerificationHelper.assertSnackBarIsNotShown
|
||||
import org.fnives.test.showcase.android.testutil.snackbar.SnackbarVerificationHelper.assertSnackBarIsShownWithText
|
||||
import org.fnives.test.showcase.ui.home.MainActivity
|
||||
import org.hamcrest.core.IsNot.not
|
||||
|
||||
class RobolectricLoginRobot(
|
||||
private val snackbarVerificationHelper: SnackbarVerificationHelper = SnackbarVerificationHelper()
|
||||
) {
|
||||
class RobolectricLoginRobot {
|
||||
|
||||
fun setUsername(username: String): RobolectricLoginRobot = apply {
|
||||
onView(withId(R.id.user_edit_text))
|
||||
|
|
@ -55,11 +54,11 @@ class RobolectricLoginRobot(
|
|||
}
|
||||
|
||||
fun assertErrorIsShown(@StringRes stringResID: Int) = apply {
|
||||
snackbarVerificationHelper.assertIsShownWithText(stringResID)
|
||||
assertSnackBarIsShownWithText(stringResID)
|
||||
}
|
||||
|
||||
fun assertErrorIsNotShown() = apply {
|
||||
snackbarVerificationHelper.assertIsNotShown()
|
||||
assertSnackBarIsNotShown()
|
||||
}
|
||||
|
||||
fun assertNavigatedToHome() = apply {
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
package org.fnives.test.showcase.testutils.configuration
|
||||
|
||||
import android.view.View
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.test.espresso.Espresso
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import com.google.android.material.R
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.hamcrest.Matcher
|
||||
import org.hamcrest.Matchers
|
||||
|
||||
class SnackbarVerificationHelper {
|
||||
|
||||
fun assertIsShownWithText(@StringRes stringResID: Int, doDismiss: Boolean = true) {
|
||||
Espresso.onView(ViewMatchers.withId(R.id.snackbar_text))
|
||||
.check(ViewAssertions.matches(ViewMatchers.withText(stringResID)))
|
||||
if (doDismiss) {
|
||||
Espresso.onView(ViewMatchers.isAssignableFrom(Snackbar.SnackbarLayout::class.java)).perform(ViewActions.swipeRight())
|
||||
Espresso.onView(ViewMatchers.isRoot()).perform(LoopMainUntilSnackbarDismissed())
|
||||
}
|
||||
}
|
||||
|
||||
fun assertIsNotShown() {
|
||||
Espresso.onView(ViewMatchers.withId(R.id.snackbar_text)).check(ViewAssertions.doesNotExist())
|
||||
}
|
||||
|
||||
class LoopMainUntilSnackbarDismissed : ViewAction {
|
||||
override fun getConstraints(): Matcher<View> = Matchers.isA(View::class.java)
|
||||
|
||||
override fun getDescription(): String = "loop MainThread until Snackbar is Dismissed"
|
||||
|
||||
override fun perform(uiController: UiController, view: View?) {
|
||||
while (view?.findViewById<View>(com.google.android.material.R.id.snackbar_text) != null) {
|
||||
uiController.loopMainThreadForAtLeast(100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
package org.fnives.test.showcase.testutils.viewactions
|
||||
|
||||
import android.view.View
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import androidx.swiperefreshlayout.widget.listener
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import org.fnives.test.showcase.android.testutil.synchronization.runOnUIAwaitOnCurrent
|
||||
import org.hamcrest.BaseMatcher
|
||||
import org.hamcrest.CoreMatchers.isA
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Matcher
|
||||
|
||||
// swipe-refresh-layout swipe-down doesn't work, inspired by https://github.com/robolectric/robolectric/issues/5375
|
||||
class PullToRefresh : ViewAction {
|
||||
|
||||
override fun getConstraints(): Matcher<View> {
|
||||
return object : BaseMatcher<View>() {
|
||||
override fun matches(item: Any): Boolean {
|
||||
return isA(SwipeRefreshLayout::class.java).matches(item)
|
||||
}
|
||||
|
||||
override fun describeMismatch(item: Any, mismatchDescription: Description) {
|
||||
mismatchDescription.appendText("Expected SwipeRefreshLayout or its Descendant, but got other View")
|
||||
}
|
||||
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("Action SwipeToRefresh to view SwipeRefreshLayout or its descendant")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDescription(): String {
|
||||
return "Perform pull-to-refresh on the SwipeRefreshLayout"
|
||||
}
|
||||
|
||||
override fun perform(uiController: UiController, view: View) {
|
||||
val swipeRefreshLayout = view as SwipeRefreshLayout
|
||||
runOnUIAwaitOnCurrent {
|
||||
swipeRefreshLayout.isRefreshing = true
|
||||
swipeRefreshLayout.listener().onRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package org.fnives.test.showcase.testutils.viewactions
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
|
||||
import org.hamcrest.Matcher
|
||||
|
||||
class ReplaceProgressBarDrawableToStatic : ViewAction {
|
||||
override fun getConstraints(): Matcher<View> =
|
||||
isAssignableFrom(ProgressBar::class.java)
|
||||
|
||||
override fun getDescription(): String =
|
||||
"replace the ProgressBar drawable"
|
||||
|
||||
override fun perform(uiController: UiController, view: View) {
|
||||
val progressBar: ProgressBar = view as ProgressBar
|
||||
progressBar.indeterminateDrawable = ColorDrawable(Color.GREEN)
|
||||
uiController.loopMainThreadUntilIdle()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
@file:Suppress("PackageDirectoryMismatch")
|
||||
|
||||
package androidx.swiperefreshlayout.widget
|
||||
|
||||
fun SwipeRefreshLayout.listener() = mListener
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package org.fnives.test.showcase.testutils.viewactions
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.PorterDuff
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.TypeSafeMatcher
|
||||
|
||||
class WithDrawable(
|
||||
@DrawableRes
|
||||
private val id: Int,
|
||||
@ColorRes
|
||||
private val tint: Int? = null,
|
||||
private val tintMode: PorterDuff.Mode = PorterDuff.Mode.SRC_IN
|
||||
) : TypeSafeMatcher<View>() {
|
||||
override fun describeTo(description: Description) {
|
||||
description.appendText("ImageView with drawable same as drawable with id $id")
|
||||
tint?.let { description.appendText(", tint color id: $tint, mode: $tintMode") }
|
||||
}
|
||||
|
||||
override fun matchesSafely(view: View): Boolean {
|
||||
val context = view.context
|
||||
val tintColor = tint?.let { ContextCompat.getColor(view.context, it) }
|
||||
val expectedBitmap = context.getDrawable(id)?.apply {
|
||||
if (tintColor != null) {
|
||||
setTintList(ColorStateList.valueOf(tintColor))
|
||||
setTintMode(tintMode)
|
||||
}
|
||||
}
|
||||
return view is ImageView && view.drawable.toBitmap().sameAs(expectedBitmap?.toBitmap())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
package org.fnives.test.showcase.testutils.viewactions
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.test.espresso.intent.Intents.intended
|
||||
import org.hamcrest.Matcher
|
||||
import org.hamcrest.StringDescription
|
||||
|
||||
fun notIntended(matcher: Matcher<Intent>) {
|
||||
try {
|
||||
intended(matcher)
|
||||
} catch (assertionError: AssertionError) {
|
||||
return
|
||||
}
|
||||
val description = StringDescription()
|
||||
matcher.describeMismatch(null, description)
|
||||
throw IllegalStateException("Navigate to intent found matching $description")
|
||||
}
|
||||
|
|
@ -19,11 +19,11 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
|
|||
import androidx.test.espresso.matcher.ViewMatchers.withParent
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import org.fnives.test.showcase.R
|
||||
import org.fnives.test.showcase.android.testutil.intent.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.viewaction.imageview.WithDrawable
|
||||
import org.fnives.test.showcase.android.testutil.viewaction.swiperefresh.PullToRefresh
|
||||
import org.fnives.test.showcase.model.content.Content
|
||||
import org.fnives.test.showcase.model.content.FavouriteContent
|
||||
import org.fnives.test.showcase.testutils.viewactions.PullToRefresh
|
||||
import org.fnives.test.showcase.testutils.viewactions.WithDrawable
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
import org.fnives.test.showcase.ui.auth.AuthActivity
|
||||
import org.hamcrest.Matchers.allOf
|
||||
|
||||
|
|
|
|||
|
|
@ -14,15 +14,14 @@ import androidx.test.espresso.matcher.ViewMatchers
|
|||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import org.fnives.test.showcase.R
|
||||
import org.fnives.test.showcase.testutils.configuration.SnackbarVerificationHelper
|
||||
import org.fnives.test.showcase.testutils.viewactions.ReplaceProgressBarDrawableToStatic
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.intent.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.snackbar.SnackbarVerificationHelper.assertSnackBarIsNotShown
|
||||
import org.fnives.test.showcase.android.testutil.snackbar.SnackbarVerificationHelper.assertSnackBarIsShownWithText
|
||||
import org.fnives.test.showcase.android.testutil.viewaction.progressbar.ReplaceProgressBarDrawableToStatic
|
||||
import org.fnives.test.showcase.ui.home.MainActivity
|
||||
import org.hamcrest.core.IsNot.not
|
||||
|
||||
class LoginRobot(
|
||||
private val snackbarVerificationHelper: SnackbarVerificationHelper = SnackbarVerificationHelper()
|
||||
) {
|
||||
class LoginRobot {
|
||||
|
||||
fun setupIntentResults() {
|
||||
Intents.intending(hasComponent(MainActivity::class.java.canonicalName))
|
||||
|
|
@ -68,7 +67,7 @@ class LoginRobot(
|
|||
}
|
||||
|
||||
fun assertErrorIsShown(@StringRes stringResID: Int) = apply {
|
||||
snackbarVerificationHelper.assertIsShownWithText(stringResID)
|
||||
assertSnackBarIsShownWithText(stringResID)
|
||||
}
|
||||
|
||||
fun assertLoadingBeforeRequests() = apply {
|
||||
|
|
@ -82,7 +81,7 @@ class LoginRobot(
|
|||
}
|
||||
|
||||
fun assertErrorIsNotShown() = apply {
|
||||
snackbarVerificationHelper.assertIsNotShown()
|
||||
assertSnackBarIsNotShown()
|
||||
}
|
||||
|
||||
fun assertNavigatedToHome() = apply {
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ import androidx.test.espresso.intent.Intents
|
|||
import androidx.test.espresso.intent.matcher.IntentMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import org.fnives.test.showcase.R
|
||||
import org.fnives.test.showcase.testutils.configuration.SnackbarVerificationHelper
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.snackbar.SnackbarVerificationHelper.assertSnackBarIsNotShown
|
||||
import org.fnives.test.showcase.android.testutil.snackbar.SnackbarVerificationHelper.assertSnackBarIsShownWithText
|
||||
import org.fnives.test.showcase.android.testutil.intent.notIntended
|
||||
import org.fnives.test.showcase.ui.home.MainActivity
|
||||
import org.hamcrest.core.IsNot
|
||||
|
||||
class CodeKataSharedRobotTest(
|
||||
private val snackbarVerificationHelper: SnackbarVerificationHelper = SnackbarVerificationHelper()
|
||||
) {
|
||||
class CodeKataSharedRobotTest {
|
||||
|
||||
fun setUsername(username: String): CodeKataSharedRobotTest = apply {
|
||||
Espresso.onView(ViewMatchers.withId(R.id.user_edit_text))
|
||||
|
|
@ -53,11 +52,11 @@ class CodeKataSharedRobotTest(
|
|||
}
|
||||
|
||||
fun assertErrorIsShown(@StringRes stringResID: Int): CodeKataSharedRobotTest = apply {
|
||||
snackbarVerificationHelper.assertIsShownWithText(stringResID)
|
||||
assertSnackBarIsShownWithText(stringResID)
|
||||
}
|
||||
|
||||
fun assertErrorIsNotShown(): CodeKataSharedRobotTest = apply {
|
||||
snackbarVerificationHelper.assertIsNotShown()
|
||||
assertSnackBarIsNotShown()
|
||||
}
|
||||
|
||||
fun assertNavigatedToHome(): CodeKataSharedRobotTest = apply {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.app.Instrumentation
|
|||
import android.content.Intent
|
||||
import androidx.test.espresso.intent.Intents
|
||||
import androidx.test.espresso.intent.matcher.IntentMatchers
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
import org.fnives.test.showcase.android.testutil.intent.notIntended
|
||||
import org.fnives.test.showcase.ui.auth.AuthActivity
|
||||
import org.fnives.test.showcase.ui.home.MainActivity
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue