From d2ffcb86ee607a70db50e06c6a2b1367968b7000 Mon Sep 17 00:00:00 2001 From: Syeda Date: Thu, 11 Jul 2024 17:41:50 +0200 Subject: [PATCH] ci(bank-sdk): Introduce new test and resource classes. --- bank-sdk/example-app/build.gradle.kts | 1 + .../ui/resources/SimpleIdlingResource.kt | 36 +++++ .../sdk/exampleapp/ui/screens/HelpScreen.kt | 43 +++++- .../sdk/exampleapp/ui/screens/MainScreen.kt | 25 +--- .../exampleapp/ui/screens/OnboardingScreen.kt | 29 ++++- .../ui/testcases/HelpScreenTests.kt | 62 +++++++++ ...MainActivityTest.kt => MainScreenTests.kt} | 61 +-------- .../ui/testcases/OnboardingScreenTests.kt | 123 ++++++++++++++++++ gradle/libs.versions.toml | 3 +- 9 files changed, 294 insertions(+), 89 deletions(-) create mode 100644 bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/resources/SimpleIdlingResource.kt create mode 100644 bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/HelpScreenTests.kt rename bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/{MainActivityTest.kt => MainScreenTests.kt} (53%) create mode 100644 bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/OnboardingScreenTests.kt diff --git a/bank-sdk/example-app/build.gradle.kts b/bank-sdk/example-app/build.gradle.kts index 86071f57d..74dc4eb02 100644 --- a/bank-sdk/example-app/build.gradle.kts +++ b/bank-sdk/example-app/build.gradle.kts @@ -72,6 +72,7 @@ android { // Use the test runner with JUnit4 support testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + testInstrumentationRunnerArguments["clearPackageData"] = "true" multiDexEnabled = true } diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/resources/SimpleIdlingResource.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/resources/SimpleIdlingResource.kt new file mode 100644 index 000000000..72875c4aa --- /dev/null +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/resources/SimpleIdlingResource.kt @@ -0,0 +1,36 @@ +package net.gini.android.bank.sdk.exampleapp.ui.resources +import androidx.test.espresso.IdlingResource + +class SimpleIdlingResource(private val waitTime: Long) : IdlingResource { + + @Volatile + private var isIdleNow = true + private var callback: IdlingResource.ResourceCallback? = null + + override fun getName() = SimpleIdlingResource::class.java.name + + override fun isIdleNow() = isIdleNow + + override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback) { + this.callback = callback + } + + fun setIdleState(isIdleNow: Boolean) { + this.isIdleNow = isIdleNow + if (isIdleNow && callback != null) { + callback!!.onTransitionToIdle() + } + } + + fun waitForIdle() { + isIdleNow = false + Thread { + try { + Thread.sleep(waitTime) + } catch (e: InterruptedException) { + e.printStackTrace() + } + setIdleState(true) + }.start() + } +} diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/HelpScreen.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/HelpScreen.kt index 73d4a3912..81ed7c3f8 100644 --- a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/HelpScreen.kt +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/HelpScreen.kt @@ -18,11 +18,22 @@ class HelpScreen { isDescendantOfA(withId(net.gini.android.capture.R.id.gc_help_items)) ) ) - .check(matches(withText("Tips for best results from photos"))) .perform(click()); return this } + fun assertTipsForBestResultsExists(): HelpScreen { + onView( + allOf( + withId(net.gini.android.capture.R.id.gc_help_item_title), + withText("Tips for best results from photos"), + isDescendantOfA(withId(net.gini.android.capture.R.id.gc_help_items)) + ) + ) + .check(matches(withText("Tips for best results from photos"))) + return this + } + fun clickSupportedFormats(): HelpScreen { onView( allOf( @@ -31,11 +42,22 @@ class HelpScreen { isDescendantOfA(withId(net.gini.android.capture.R.id.gc_help_items)) ) ) - .check(matches(withText("Supported formats"))) .perform(click()); return this } + fun assertSupportedFormatsExists(): HelpScreen { + onView( + allOf( + withId(net.gini.android.capture.R.id.gc_help_item_title), + withText("Supported formats"), + isDescendantOfA(withId(net.gini.android.capture.R.id.gc_help_items)) + ) + ) + .check(matches(withText("Supported formats"))) + return this + } + fun clickImportDocs(): HelpScreen { onView( allOf( @@ -44,13 +66,26 @@ class HelpScreen { isDescendantOfA(withId(net.gini.android.capture.R.id.gc_help_items)) ) ) - .check(matches(withText("Import documents from other apps"))) .perform(click()); return this } + fun assertImportDocsExists(): HelpScreen { + onView( + allOf( + withId(net.gini.android.capture.R.id.gc_help_item_title), + withText("Import documents from other apps"), + isDescendantOfA(withId(net.gini.android.capture.R.id.gc_help_items)) + ) + ) + .check(matches(withText("Import documents from other apps"))) + return this + } + fun clickBackButton(): HelpScreen { - onView(withContentDescription(net.gini.android.capture.R.string.gc_back_button_description)).perform(click()) + onView(withContentDescription(net.gini.android.capture.R.string.gc_back_button_description)).perform( + click() + ) return this } } \ No newline at end of file diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/MainScreen.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/MainScreen.kt index aab5b2383..4699fb2ad 100644 --- a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/MainScreen.kt +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/MainScreen.kt @@ -2,38 +2,17 @@ package net.gini.android.bank.sdk.exampleapp.ui.screens import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId import net.gini.android.bank.sdk.exampleapp.R +import androidx.test.espresso.assertion.ViewAssertions.matches class MainScreen { - - fun checkWelcomeTitleIsDisplayed(): MainScreen { - onView(withId(R.id.tv_welcomeToGini)).check(matches(isDisplayed())) - return this - } - fun assertDescriptionTitle(): MainScreen { onView(withId(R.id.tv_exampleOfPhotoPayment)).check(matches(isDisplayed())) return this } - fun checkCheckIconDisplayed(): MainScreen { - onView(withId(R.id.til_fieldEntryPoint)).check(matches(isDisplayed())) - return this - } - - fun clickCameraIcon(): MainScreen { - onView(withId(R.id.til_fieldEntryPoint)).perform(click()) - return this - } - - fun checkScannerButtonDisplayed(): MainScreen { - onView(withId(R.id.button_startScanner)).check(matches(isDisplayed())) - return this - } - fun clickPhotoPaymentButton(): MainScreen { onView(withId(R.id.button_startScanner)).perform(click()) return this diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/OnboardingScreen.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/OnboardingScreen.kt index 894eddb3c..c51a169f4 100644 --- a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/OnboardingScreen.kt +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/screens/OnboardingScreen.kt @@ -5,10 +5,32 @@ import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isClickable +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import org.hamcrest.CoreMatchers.allOf class OnboardingScreen { + fun checkOnboardingScreenTitle(onboardingTitle: String): OnboardingScreen { + onView( + allOf( + withId(net.gini.android.capture.R.id.gc_title), withText(onboardingTitle) + ) + ).check(matches(isDisplayed())) + return this + } + + fun checkNextButtonText(): OnboardingScreen { + onView(withId(net.gini.android.capture.R.id.gc_next)).check(matches(withText("Next"))) + return this + } - fun assertSkipButtonText(): OnboardingScreen { + fun clickNextButton(): OnboardingScreen { + onView(withId(net.gini.android.capture.R.id.gc_next)).check(matches(isDisplayed())) + .check(matches(isClickable())).perform(click()) + return this + } + + fun checkSkipButtonText(): OnboardingScreen { onView(withId(net.gini.android.capture.R.id.gc_skip)).check(matches(withText("Skip"))) return this } @@ -17,4 +39,9 @@ class OnboardingScreen { onView(withId(net.gini.android.capture.R.id.gc_skip)).perform(click()) return this } + + fun checkGetStartedButton(): OnboardingScreen { + onView(withId(net.gini.android.capture.R.id.gc_get_started)).check(matches(withText("Get Started"))) + return this + } } \ No newline at end of file diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/HelpScreenTests.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/HelpScreenTests.kt new file mode 100644 index 000000000..af27e5949 --- /dev/null +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/HelpScreenTests.kt @@ -0,0 +1,62 @@ +package net.gini.android.bank.sdk.exampleapp.ui.testcases + +import android.Manifest +import androidx.test.ext.junit.rules.activityScenarioRule +import androidx.test.rule.GrantPermissionRule +import net.gini.android.bank.sdk.exampleapp.ui.MainActivity +import net.gini.android.bank.sdk.exampleapp.ui.screens.CaptureScreen +import net.gini.android.bank.sdk.exampleapp.ui.screens.HelpScreen +import net.gini.android.bank.sdk.exampleapp.ui.screens.MainScreen +import net.gini.android.bank.sdk.exampleapp.ui.screens.OnboardingScreen +import org.junit.Rule +import org.junit.Test + +/** + * Test class for help screen flow. + * + * Jira link for test case: [https://ginis.atlassian.net/browse/PM-23](https://ginis.atlassian.net/browse/PM-23) + */ +class HelpScreenTests { + + @get:Rule + val activityRule = activityScenarioRule() + + @get: Rule + val grantPermissionRule: GrantPermissionRule = + GrantPermissionRule.grant(Manifest.permission.CAMERA) + + private val mainScreen = MainScreen() + private val onboardingScreen = OnboardingScreen() + private val captureScreen = CaptureScreen() + private val helpScreen = HelpScreen() + + @Test + fun test2_verifyHelpItemTipsForBestResult() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickSkipButton() + captureScreen.clickHelpButton() + helpScreen.assertTipsForBestResultsExists() + helpScreen.clickTipsForBestResults() + helpScreen.clickBackButton() + } + + @Test + fun test3_verifyHelpItemSupportedFormats() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickSkipButton() + captureScreen.clickHelpButton() + helpScreen.assertSupportedFormatsExists() + helpScreen.clickSupportedFormats() + helpScreen.clickBackButton() + } + + @Test + fun test4_verifyHelpItemImportDocuments() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickSkipButton() + captureScreen.clickHelpButton() + helpScreen.assertImportDocsExists() + helpScreen.clickImportDocs() + helpScreen.clickBackButton() + } +} \ No newline at end of file diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/MainActivityTest.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/MainScreenTests.kt similarity index 53% rename from bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/MainActivityTest.kt rename to bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/MainScreenTests.kt index 6b90d99f5..f336ed285 100644 --- a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/MainActivityTest.kt +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/MainScreenTests.kt @@ -11,7 +11,6 @@ import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction import androidx.test.espresso.intent.matcher.IntentMatchers.hasType import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.LargeTest import androidx.test.rule.GrantPermissionRule import net.gini.android.bank.sdk.exampleapp.ui.MainActivity import net.gini.android.bank.sdk.exampleapp.ui.screens.CaptureScreen @@ -21,17 +20,13 @@ import net.gini.android.bank.sdk.exampleapp.ui.screens.OnboardingScreen import org.hamcrest.Matchers.allOf import org.junit.After import org.junit.Before -import org.junit.FixMethodOrder import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -@FixMethodOrder(MethodSorters.NAME_ASCENDING) @RunWith(AndroidJUnit4::class) -@LargeTest -class MainActivityTest { +class MainScreenTests { @get: Rule val activityRule = ActivityScenarioRule(MainActivity::class.java) @@ -41,62 +36,14 @@ class MainActivityTest { GrantPermissionRule.grant(Manifest.permission.CAMERA) private val mainScreen = MainScreen() - private val onboardingScreen = OnboardingScreen() - private val captureScreen = CaptureScreen() - private val helpScreen = HelpScreen() @Before fun setUp() { Intents.init() } - @Test - fun test1_assertTitlesOnMainScreen() { - mainScreen.checkWelcomeTitleIsDisplayed() - mainScreen.assertDescriptionTitle() - } - @Test - fun test2_clickPhotoPaymentButton() { - mainScreen.checkScannerButtonDisplayed() - mainScreen.clickPhotoPaymentButton() - onboardingScreen.assertSkipButtonText() - onboardingScreen.clickSkipButton() - captureScreen.assertCameraTitle() - captureScreen.clickCancelButton() - } - - @Test - fun test3_clickHelpButton() { - mainScreen.clickPhotoPaymentButton() - captureScreen.clickHelpButton() - } - - @Test - fun test4_verifyHelpItemTipsForBestResult() { - mainScreen.clickPhotoPaymentButton() - captureScreen.clickHelpButton() - helpScreen.clickTipsForBestResults() - helpScreen.clickBackButton() - } - - @Test - fun test5_verifyHelpItemSupportedFormats() { - mainScreen.clickPhotoPaymentButton() - captureScreen.clickHelpButton() - helpScreen.clickSupportedFormats() - helpScreen.clickBackButton() - } - - @Test - fun test6_verifyHelpItemImportDocuments() { - mainScreen.clickPhotoPaymentButton() - captureScreen.clickHelpButton() - helpScreen.clickImportDocs() - helpScreen.clickBackButton() - } - @Test - fun test7_pdfImportFromFiles() { + fun test1_pdfImportFromFiles() { mainScreen.clickPhotoPaymentButton() val resultData = Intent() val fileUri = @@ -110,8 +57,4 @@ class MainActivityTest { ) ).respondWith(result) } - - @After - fun tearDown() { - } } \ No newline at end of file diff --git a/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/OnboardingScreenTests.kt b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/OnboardingScreenTests.kt new file mode 100644 index 000000000..51cc4fa83 --- /dev/null +++ b/bank-sdk/example-app/src/androidTest/java/net/gini/android/bank/sdk/exampleapp/ui/testcases/OnboardingScreenTests.kt @@ -0,0 +1,123 @@ +package net.gini.android.bank.sdk.exampleapp.ui.testcases + +import android.Manifest +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.IdlingRegistry +import androidx.test.ext.junit.rules.activityScenarioRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.rule.GrantPermissionRule +import net.gini.android.bank.sdk.exampleapp.ui.MainActivity +import net.gini.android.bank.sdk.exampleapp.ui.resources.SimpleIdlingResource +import net.gini.android.bank.sdk.exampleapp.ui.screens.CaptureScreen +import net.gini.android.bank.sdk.exampleapp.ui.screens.MainScreen +import net.gini.android.bank.sdk.exampleapp.ui.screens.OnboardingScreen +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Test class for onboarding screen flow. + * + * Jira link for test case: [https://ginis.atlassian.net/browse/PM-18](https://ginis.atlassian.net/browse/PM-18) + */ + +@RunWith(AndroidJUnit4::class) +class OnboardingScreenTests { + @get:Rule + val activityRule = activityScenarioRule() + + @get: Rule + val grantPermissionRule: GrantPermissionRule = + GrantPermissionRule.grant(Manifest.permission.CAMERA) + + private val mainScreen = MainScreen() + private val onboardingScreen = OnboardingScreen() + private val captureScreen = CaptureScreen() + private lateinit var idlingResource: SimpleIdlingResource + + @Before + fun setUp() { + idlingResource = SimpleIdlingResource(2000) + IdlingRegistry.getInstance().register(idlingResource) + } + + @Test + fun test1_assertFlatPaperTitle() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.checkOnboardingScreenTitle("Flat paper within the frame") + } + + @Test + fun test2_clickNextButtonAndAssertGoodLightningTitle() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickNextButton() + onboardingScreen.checkOnboardingScreenTitle("Good lighting") + } + + @Test + fun test3_clickNextButtonAndAssertAddMultiPageTitle() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickNextButton() + idlingResource.waitForIdle() + onboardingScreen.clickNextButton() + onboardingScreen.checkOnboardingScreenTitle("Add multiple pages") + } + + @Test + fun test4_clickNextButtonAndAssertQRCodeTitle() { + mainScreen.clickPhotoPaymentButton() + idlingResource.waitForIdle() + onboardingScreen.clickNextButton() + idlingResource.waitForIdle() + onboardingScreen.clickNextButton() + idlingResource.waitForIdle() + onboardingScreen.clickNextButton() + idlingResource.waitForIdle() + onboardingScreen.checkOnboardingScreenTitle("QR codes supported") + } + + @Test + fun test5_assertNextButton() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.checkNextButtonText() + } + + @Test + fun test6_assertSkipButton() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.checkSkipButtonText() + } + + @Test + fun test7_assertGetStartedButton() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickNextButton() + onboardingScreen.clickNextButton() + onboardingScreen.clickNextButton() + onboardingScreen.checkGetStartedButton() + } + + @Test + fun test8a_assertOnboardingOnFirstLaunch() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.checkOnboardingScreenTitle("Flat paper within the frame") + onboardingScreen.checkSkipButtonText() + } + + @Test + fun test8b_skipsOnboardingAndShowsCameraScreenOnSubsequentLaunches() { + mainScreen.clickPhotoPaymentButton() + onboardingScreen.clickSkipButton() + pressBack() + mainScreen.assertDescriptionTitle() + mainScreen.clickPhotoPaymentButton() + captureScreen.assertCameraTitle() + } + + @After + fun tearDown() { + IdlingRegistry.getInstance().unregister(idlingResource) + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c0ca287bb..5794398ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,6 @@ jacoco = "0.8.10" hilt = "2.46.1" navigation_component = "2.7.6" - [libraries] android-gradle = { module = "com.android.tools.build:gradle", version.ref = "android-gradle-plugin" } kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } @@ -112,4 +111,4 @@ navigation_ui_ktx = { module = "androidx.navigation:navigation-ui-ktx", version. navigation_safe_args = { module = "androidx.navigation:navigation-safe-args-gradle-plugin", version.ref = "navigation_component" } datastore-preferences = "androidx.datastore:datastore-preferences:1.0.0" tomlj = "org.tomlj:tomlj:1.1.1" -json-testing = "org.json:json:20231013" +json-testing = "org.json:json:20231013" \ No newline at end of file