Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ This module contains End-to-End UI tests for the Accounts Journey, connected to

> [!IMPORTANT]
> A test account must be configured before running tests.
> Provide credentials by editing [accounts-demo/build.gradle.kts](accounts-demo/build.gradle.kts) using the [EBP Sandbox user credentials](https://backbase.io/ebp-sandbox/user-credentials?experience=retail).
> Provide credentials by editing the global `./gradle/gradle.properties` using the [EBP Sandbox user credentials](https://backbase.io/ebp-sandbox/user-credentials?experience=retail):
- `systemProp.TEST_ACCOUNT_USERNAME="username"`
- `systemProp.TEST_ACCOUNT_PASSWORD="password"`


```sh
./gradlew accounts-demo:cAT
Expand Down
6 changes: 4 additions & 2 deletions accounts-demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ android {

buildTypes {
debug {
buildConfigField("String", "TEST_ACCOUNT_USERNAME", "\"ADD USER NAME HERE\"")
buildConfigField("String", "TEST_ACCOUNT_PASSWORD", "\"ADD PASSWORD HERE\"")
val testAccountUserName = System.getProperty("TEST_ACCOUNT_USERNAME") ?: "unknown"
val testAccountPassword = System.getProperty("TEST_ACCOUNT_PASSWORD") ?: "unknown"
buildConfigField("String", "TEST_ACCOUNT_USERNAME", testAccountUserName)
buildConfigField("String", "TEST_ACCOUNT_PASSWORD", testAccountPassword)
}
release {
isMinifyEnabled = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package com.backbase.accounts_demo

import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewInteraction
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.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.backbase.accounts_demo.presentation.MainActivity
import com.backbase.accounts_journey.R
import com.backbase.android.test_data.click
import com.backbase.android.test_data.clickOnRecyclerViewItem
import com.backbase.android.test_data.hasItems
import com.backbase.android.test_data.shouldBeDisplayed
import com.backbase.android.test_data.shouldHaveDescendant
import com.backbase.android.test_data.shouldMatchText
import com.backbase.android.test_data.typeTextInInput
import com.backbase.android.test_data.waitForRecyclerViewToHaveItems
Expand Down Expand Up @@ -72,15 +69,16 @@ class AccountsJourneyE2ETest {
@Test
fun accountListShouldBeDisplayed() {
accountHeader.shouldBeDisplayed()
accountList.shouldBeDisplayed()
accountList.check(hasItems())
accountList
.shouldBeDisplayed()
.hasItems()
}

@Test
fun successfulSearchAccountsAreDisplayed() {
searchInput.typeTextInInput("Sara")
searchInput.typeTextInInput("John")

accountList.check(matches(hasDescendant(withText("Sara's Current Account 1"))))
accountList.shouldHaveDescendant("John's Current Account 1")
}

@Test
Expand All @@ -93,9 +91,7 @@ class AccountsJourneyE2ETest {

@Test
fun accountDetailShouldBeDisplayed() {
accountList.perform(
RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(1, click())
)
accountList.clickOnRecyclerViewItem(1)
accountDetailHeader.waitForView()

accountDetailHeader.shouldBeDisplayed()
Expand All @@ -104,20 +100,20 @@ class AccountsJourneyE2ETest {
private fun login() {
usernameInput.typeTextInInput(BuildConfig.TEST_ACCOUNT_USERNAME)
passwordInput.typeTextInInput(BuildConfig.TEST_ACCOUNT_PASSWORD)
loginButton.perform(click())
loginButton.click()
}

private fun setupPasscode() {
enterPasscode() // Enter the passcode
enterPasscode() // Confirm the passcode
confirmButton.perform(click())
confirmButton.click()
}

private fun enterPasscode() {
keyboard1Button.perform(click())
keyboard4Button.perform(click())
keyboard7Button.perform(click())
keyboard8Button.perform(click())
keyboard9Button.perform(click())
keyboard1Button.click()
keyboard4Button.click()
keyboard7Button.click()
keyboard8Button.click()
keyboard9Button.click()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ class AccountsJourneyE2ETest : BaseE2ETest() {
@Test
fun accountListShouldBeDisplayed() {
accountHeader.shouldBeDisplayed()
accountList.shouldBeDisplayed()
accountList.check(hasItems())
accountList
.shouldBeDisplayed()
.hasItems()
}

@Test
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ detekt-formatting = { group = "io.gitlab.arturbosch.detekt", name = "detekt-form

## E
espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
espressoContrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "espresso" }

## G
gradle = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" }
Expand Down Expand Up @@ -171,6 +172,7 @@ test-instrumented = [
"coroutines",
"coroutinesTest",
"espresso",
"espressoContrib",
"junit4-android",
"koinTest",
"testParameterInjector",
Expand Down
1 change: 1 addition & 0 deletions test-data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ dependencies {
implementation(libs.junit.jupiter)

implementation(libs.espresso)
implementation(libs.espressoContrib)
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package com.backbase.android.test_data

import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewAssertion
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.swipeDown
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.isClickable
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.isEnabled
Expand Down Expand Up @@ -77,4 +81,30 @@ fun ViewInteraction.typeTextInInput(text: String): ViewInteraction =
perform(typeText(text)).perform(closeSoftKeyboard())

fun ViewInteraction.pullToRefresh(): ViewInteraction =
perform(androidx.test.espresso.action.ViewActions.swipeDown())
perform(swipeDown())

fun ViewInteraction.click(): ViewInteraction =
perform(androidx.test.espresso.action.ViewActions.click())

fun ViewInteraction.shouldHaveDescendant(text: String): ViewInteraction =
check(matches(hasDescendant(withText(text))))

fun ViewInteraction.clickOnRecyclerViewItem(position: Int): ViewInteraction =
perform(
RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(
position,
androidx.test.espresso.action.ViewActions.click()
)
)

fun ViewInteraction.hasItems(): ViewInteraction {
ViewAssertion { view, noViewFoundException ->
if (noViewFoundException != null) throw noViewFoundException
val recyclerView = view as RecyclerView
val itemCount = recyclerView.adapter?.itemCount ?: 0
assert(itemCount > 0) {
"RecyclerView has no items. Item count = $itemCount"
}
}
return this
}