- Approver for documents as Admin (#19)

- Approver for documents as Admin
 - UI tests for document approving
 - update config.yml
 - update android test suite
 - idling resources added for toast
 - toast methods refactored
 - tests for approving updated
This commit is contained in:
2023-06-20 09:12:47 +01:00
committed by GitHub
parent 786761f67c
commit 600f82d2a1
45 changed files with 715 additions and 189 deletions

View File

@@ -60,7 +60,7 @@ open class BaseTestRobot {
}
fun <VH : ViewHolder> scrollToRecyclerItem(recyclerId: Int, text: String): ViewInteraction? {
return onView(withId(recyclerId))
return matchView(recyclerId)
.perform(
// scrollTo will fail the test if no item matches.
RecyclerViewActions.scrollTo<VH>(
@@ -69,8 +69,38 @@ open class BaseTestRobot {
)
}
fun <VH : ViewHolder> scrollToRecyclerItem(recyclerId: Int, resIdForString: Int): ViewInteraction? {
return matchView(recyclerId)
.perform(
// scrollTo will fail the test if no item matches.
RecyclerViewActions.scrollTo<VH>(
hasDescendant(withText(resIdForString))
)
)
}
fun <VH : ViewHolder> scrollToRecyclerItemByPosition(recyclerId: Int, position: Int): ViewInteraction? {
return matchView(recyclerId)
.perform(
// scrollTo will fail the test if no item matches.
RecyclerViewActions.scrollToPosition<VH>(position)
)
}
fun <VH : ViewHolder> clickViewInRecycler(recyclerId: Int, text: String) {
scrollToRecyclerItem<VH>(recyclerId, text)?.perform(click())
matchView(recyclerId)
.perform(
// scrollTo will fail the test if no item matches.
RecyclerViewActions.actionOnItem<VH>(hasDescendant(withText(text)), click())
)
}
fun <VH : ViewHolder> clickViewInRecycler(recyclerId: Int, resIdForString: Int) {
matchView(recyclerId)
.perform(
// scrollTo will fail the test if no item matches.
RecyclerViewActions.actionOnItem<VH>(hasDescendant(withText(resIdForString)), click())
)
}
fun <VH : ViewHolder> clickSubViewInRecycler(recyclerId: Int, text: String, subView: Int) {

View File

@@ -1,17 +1,26 @@
package h_mal.appttude.com.driver
import android.R
import android.app.Activity
import android.content.Context
import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.*
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.IdlingResource
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers.isRoot
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import h_mal.appttude.com.driver.base.BaseActivity
import h_mal.appttude.com.driver.helpers.BaseViewAction
import org.hamcrest.CoreMatchers
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher
import org.hamcrest.core.AllOf
import org.junit.After
import org.junit.Before
@@ -23,6 +32,8 @@ open class BaseUiTest<T : BaseActivity<*, *>>(
private lateinit var mActivityScenarioRule: ActivityScenario<T>
private var mIdlingResource: IdlingResource? = null
private lateinit var currentActivity: Activity
@Before
fun setup() {
beforeLaunch()
@@ -30,7 +41,7 @@ open class BaseUiTest<T : BaseActivity<*, *>>(
mActivityScenarioRule.onActivity {
mIdlingResource = it.getIdlingResource()!!
IdlingRegistry.getInstance().register(mIdlingResource)
afterLaunch()
afterLaunch(it)
}
}
@@ -42,7 +53,7 @@ open class BaseUiTest<T : BaseActivity<*, *>>(
}
fun getResourceString(@StringRes stringRes: Int): String {
return InstrumentationRegistry.getInstrumentation().targetContext.resources.getString(
return getInstrumentation().targetContext.resources.getString(
stringRes
)
}
@@ -58,5 +69,50 @@ open class BaseUiTest<T : BaseActivity<*, *>>(
}
open fun beforeLaunch() {}
open fun afterLaunch() {}
open fun afterLaunch(context: Context) {}
fun checkToastMessage(message: String) {
onView(withText(message)).inRoot(object : TypeSafeMatcher<Root>() {
override fun describeTo(description: Description?) {
description?.appendText("is toast")
}
override fun matchesSafely(root: Root): Boolean {
root.run {
if (windowLayoutParams.get().type === WindowManager.LayoutParams.TYPE_TOAST) {
decorView.run {
if (windowToken === applicationWindowToken) {
// windowToken == appToken means this window isn't contained by any other windows.
// if it was a window for an activity, it would have TYPE_BASE_APPLICATION.
return true
}
}
}
}
return false
}
}
).check(matches(isDisplayed()))
}
fun checkSnackBarDisplayedByMessage(message: String) {
onView(
CoreMatchers.allOf(
withId(com.google.android.material.R.id.snackbar_text),
withText(message)
)
).check(matches(isDisplayed()))
}
private fun getCurrentActivity(): Activity {
onView(AllOf.allOf(withId(R.id.content), isDisplayed()))
.perform(object : BaseViewAction() {
override fun setPerform(uiController: UiController?, view: View?) {
if (view?.context is Activity) {
currentActivity = view.context as Activity
}
}
})
return currentActivity
}
}

View File

@@ -5,6 +5,8 @@ import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import h_mal.appttude.com.driver.base.BaseActivity
import h_mal.appttude.com.driver.data.FirebaseAuthSource
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
import h_mal.appttude.com.driver.data.FirebaseStorageSource
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.tasks.await
import org.junit.After
@@ -16,7 +18,11 @@ open class FirebaseTest<T : BaseActivity<*, *>>(
private val signedIn: Boolean = false,
private val signOutAfterTest: Boolean = true
) : BaseUiTest<T>(activity) {
private val firebaseAuthSource by lazy { FirebaseAuthSource() }
private val firebaseDatabaseSource by lazy { FirebaseDatabaseSource() }
private val firebaseStorageSource by lazy { FirebaseStorageSource() }
private var email: String? = null
companion object {
@@ -58,6 +64,14 @@ open class FirebaseTest<T : BaseActivity<*, *>>(
firebaseAuthSource.registerUser(signInEmail, password).await().user
}
suspend fun login(
signInEmail: String,
password: String
) {
email = signInEmail
firebaseAuthSource.signIn(signInEmail, password).await()
}
// remove the user we created for testing
suspend fun removeUser() {
try {

View File

@@ -0,0 +1,27 @@
package h_mal.appttude.com.driver.helpers
import android.view.View
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
import org.hamcrest.Matcher
open class BaseViewAction: ViewAction {
override fun getDescription(): String? = setDescription()
override fun getConstraints(): Matcher<View> = setConstraints()
override fun perform(uiController: UiController?, view: View?) {
setPerform(uiController, view)
}
open fun setDescription(): String? {
return null
}
open fun setConstraints(): Matcher<View> {
return isAssignableFrom(View::class.java)
}
open fun setPerform(uiController: UiController?, view: View?) { }
}