diff --git a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/AddTransferMethodTest.java b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/AddTransferMethodTest.java index c4af970ff..61cd031aa 100644 --- a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/AddTransferMethodTest.java +++ b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/AddTransferMethodTest.java @@ -2,8 +2,7 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.typeText; +import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.RootMatchers.isDialog; @@ -130,12 +129,9 @@ public void testAddTransferMethod_displaysErrorDialogOnDuplicateAccountFailure() mActivityTestRule.launchActivity(null); - onView(withId(R.id.branchId)) - .perform(typeText(ROUTING_NUMBER)).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)) - .perform(typeText(String.valueOf(ACCOUNT_NUMBER))) - .perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountPurpose)).perform(click()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText(ROUTING_NUMBER)); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText(ACCOUNT_NUMBER)); + onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo(), click()); onView(allOf(withId(R.id.select_name), withText("Savings"))).perform(click()); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); @@ -165,12 +161,9 @@ public void testAddTransferMethod_displaysUnexpectedErrorDialogOnException() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.branchId)).perform(typeText(ROUTING_NUMBER)).perform( - closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)) - .perform(typeText(ACCOUNT_NUMBER)) - .perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountPurpose)).perform(click()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText(ROUTING_NUMBER)); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText(ACCOUNT_NUMBER)); + onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo(), click()); onView(allOf(withId(R.id.select_name), withText("Savings"))).perform(click()); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); @@ -193,14 +186,9 @@ public void testAddTransferMethod_displaysNetworkErrorDialogOnConnectionTimeout( mActivityTestRule.launchActivity(null); - onView(withId(R.id.branchId)) - .perform(typeText(ROUTING_NUMBER)) - .perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)) - .perform(typeText(ACCOUNT_NUMBER)) - .perform(closeSoftKeyboard()); - - onView(withId(R.id.bankAccountPurpose)).perform(click()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText(ROUTING_NUMBER)); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText(ACCOUNT_NUMBER)); + onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo(), click()); onView(allOf(withId(R.id.select_name), withText("Savings"))).perform(click()); // initiate test diff --git a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankAccountTest.java b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankAccountTest.java index 3a6e23137..75b62af11 100644 --- a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankAccountTest.java +++ b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankAccountTest.java @@ -2,13 +2,11 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.typeText; +import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; -import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withParent; @@ -28,6 +26,7 @@ import static com.hyperwallet.android.model.transfermethod.HyperwalletBankAccount.Purpose.SAVINGS; import static com.hyperwallet.android.util.EspressoUtils.hasEmptyText; import static com.hyperwallet.android.util.EspressoUtils.hasErrorText; +import static com.hyperwallet.android.util.EspressoUtils.hasNoErrorText; import static com.hyperwallet.android.util.EspressoUtils.nestedScrollTo; import static com.hyperwallet.android.util.EspressoUtils.withHint; @@ -123,8 +122,9 @@ public void testAddTransferMethod_displaysElementsOnTmcResponse() { onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))) .check(matches(withText(R.string.title_add_bank_account))); - onView(allOf(withId(R.id.section_header_title), withText("Account Information - United States (USD)"))).check( - matches(isDisplayed())); + onView(allOf(withId(R.id.section_header_title), withText("Account Information - United States (USD)"))) + .perform(nestedScrollTo()) + .check(matches(isDisplayed())); onView(withId(R.id.branchId)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.branchIdLabel)).check(matches(isDisplayed())); onView(withId(R.id.branchIdLabel)).check(matches(withHint("Routing Number"))); @@ -133,11 +133,11 @@ public void testAddTransferMethod_displaysElementsOnTmcResponse() { onView(withId(R.id.bankAccountIdLabel)).check(matches(withHint("Account Number"))); onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.bankAccountPurposeLabel)).check(matches(isDisplayed())); - onView(withId(R.id.bankAccountPurposeLabel)).check( - matches(withHint("Account Type"))); + onView(withId(R.id.bankAccountPurposeLabel)).check(matches(withHint("Account Type"))); - onView(allOf(withId(R.id.section_header_title), withText("Account Holder"))).perform(nestedScrollTo()).check( - matches(isDisplayed())); + onView(allOf(withId(R.id.section_header_title), withText("Account Holder"))) + .perform(nestedScrollTo()) + .check(matches(isDisplayed())); onView(withId(R.id.firstName)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.firstNameLabel)).check(matches(isDisplayed())); onView(withId(R.id.firstNameLabel)).check(matches(withHint("First Name"))); @@ -151,8 +151,9 @@ public void testAddTransferMethod_displaysElementsOnTmcResponse() { onView(withId(R.id.dateOfBirthLabel)).check(matches(isDisplayed())); onView(withId(R.id.dateOfBirthLabel)).check(matches(withHint("Date of Birth"))); - onView(allOf(withId(R.id.section_header_title), withText("Contact Information"))).perform( - nestedScrollTo()).check(matches(isDisplayed())); + onView(allOf(withId(R.id.section_header_title), withText("Contact Information"))) + .perform(nestedScrollTo()) + .check(matches(isDisplayed())); onView(withId(R.id.phoneNumber)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.phoneNumberLabel)).check(matches(isDisplayed())); onView(withId(R.id.phoneNumberLabel)).check(matches(withHint("Phone Number"))); @@ -160,8 +161,9 @@ public void testAddTransferMethod_displaysElementsOnTmcResponse() { onView(withId(R.id.mobileNumberLabel)).check(matches(isDisplayed())); onView(withId(R.id.mobileNumberLabel)).check(matches(withHint("Mobile Number"))); - onView(allOf(withId(R.id.section_header_title), withText("Address"))).perform(nestedScrollTo()).check( - matches(isDisplayed())); + onView(allOf(withId(R.id.section_header_title), withText("Address"))) + .perform(nestedScrollTo()) + .check(matches(isDisplayed())); onView(withId(R.id.country)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.countryLabel)).check(matches(isDisplayed())); onView(withId(R.id.countryLabel)).check(matches(withHint("Country"))); @@ -214,7 +216,7 @@ public void testAddTransferMethod_verifyDefaultValues() { onView(withId(R.id.firstName)).check(matches(withText("Brody"))); onView(withId(R.id.middleName)).check(matches(hasEmptyText())); onView(withId(R.id.lastName)).check(matches(withText("Nehru"))); - onView(withId(R.id.dateOfBirth)).check(matches(withText("2000-01-01"))); + onView(withId(R.id.dateOfBirth)).check(matches(withText("January 01, 2000"))); onView(withId(R.id.phoneNumber)).check(matches(withText("+1 604 6666666"))); onView(withId(R.id.mobileNumber)).check(matches(withText("604 666 6666"))); @@ -298,11 +300,9 @@ public void onReceive(Context context, Intent intent) { LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()) .registerReceiver(br, new IntentFilter("ACTION_HYPERWALLET_TRANSFER_METHOD_ADDED")); - onView(withId(R.id.branchId)) - .perform(typeText(ROUTING_NUMBER)).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)) - .perform(typeText(ACCOUNT_NUMBER)).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountPurpose)).perform(click()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText(ROUTING_NUMBER)); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText(ACCOUNT_NUMBER)); + onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo(), click()); onView(withId(R.id.search_button)).check(doesNotExist()); onView(withId(R.id.input_selection_list)).check(new RecyclerViewCountAssertion(2)); onView(allOf(withId(R.id.select_name), withText("Savings"))).perform(click()); @@ -321,21 +321,53 @@ public void onReceive(Context context, Intent intent) { @Test public void testAddTransferMethod_returnsErrorOnInvalidPattern() { mActivityTestRule.launchActivity(null); - // Number input should not allow non numeric values - onView(withId(R.id.branchId)).perform(typeText("a12-345")); - onView(withId(R.id.branchId)).check(matches(withText("12345"))); + + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText("ewrd{123")); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText("{dfghfgh}")); + onView(withId(R.id.firstName)).perform(nestedScrollTo(), replaceText("ewrd{1{2")); + onView(withId(R.id.lastName)).perform(nestedScrollTo(), replaceText("ewrd{1{2345")); + onView(withId(R.id.addressLine1)).perform(nestedScrollTo(), replaceText("950 {G}ranville Street")); + onView(withId(R.id.city)).perform(nestedScrollTo(), replaceText("Vancouve{r}")); + onView(withId(R.id.stateProvince)).perform(nestedScrollTo(), replaceText("df{r}")); + onView(withId(R.id.postalCode)).perform(nestedScrollTo(), replaceText("df{r}")); + + onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); + + onView(withId(R.id.branchIdLabel)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.bankAccountIdLabel)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.firstNameLabel)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.lastNameLabel)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.addressLine1Label)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.cityLabel)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.stateProvinceLabel)) + .check(matches(hasErrorText("is invalid length or format."))); + onView(withId(R.id.postalCodeLabel)) + .check(matches(hasErrorText("is invalid length or format."))); } @Test public void testAddTransferMethod_returnsErrorOnInvalidPresence() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.branchId)).perform(click()).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)).perform(click()).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountPurpose)).perform(click()); - - onView(allOf(withContentDescription(R.string.abc_action_bar_up_description), - withParent(withId(R.id.input_selection_toolbar)))).perform(click()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.firstName)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.middleName)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.lastName)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.dateOfBirth)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.phoneNumber)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.mobileNumber)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.addressLine1)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.city)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.stateProvince)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.postalCode)).perform(nestedScrollTo(), replaceText("")); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); @@ -345,16 +377,31 @@ public void testAddTransferMethod_returnsErrorOnInvalidPresence() { .check(matches(hasErrorText("You must provide a value for this field"))); onView(withId(R.id.bankAccountPurposeLabel)) .check(matches(hasErrorText("You must provide a value for this field"))); + onView(withId(R.id.firstNameLabel)) + .check(matches(hasErrorText("You must provide a value for this field"))); + onView(withId(R.id.lastNameLabel)) + .check(matches(hasErrorText("You must provide a value for this field"))); + onView(withId(R.id.addressLine1Label)) + .check(matches(hasErrorText("You must provide a value for this field"))); + onView(withId(R.id.cityLabel)) + .check(matches(hasErrorText("You must provide a value for this field"))); + onView(withId(R.id.stateProvinceLabel)) + .check(matches(hasErrorText("You must provide a value for this field"))); + onView(withId(R.id.postalCodeLabel)) + .check(matches(hasErrorText("You must provide a value for this field"))); + + onView(withId(R.id.middleNameLabel)).check(matches(hasNoErrorText())); + onView(withId(R.id.dateOfBirthLabel)).check(matches(hasNoErrorText())); + onView(withId(R.id.phoneNumberLabel)).check(matches(hasNoErrorText())); + onView(withId(R.id.mobileNumberLabel)).check(matches(hasNoErrorText())); } @Test public void testAddTransferMethod_returnsErrorOnInvalidLength() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.branchId)) - .perform(typeText("2111795311")).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)) - .perform(typeText("1")).perform(closeSoftKeyboard()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText("2111795311")); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText("1")); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); @@ -371,12 +418,9 @@ public void testAddTransferMethod_displaysErrorOnInvalidRoutingNumber() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.branchId)) - .perform(typeText(INVALID_ROUTING_NUMBER)).perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountId)) - .perform(typeText(ACCOUNT_NUMBER)) - .perform(closeSoftKeyboard()); - onView(withId(R.id.bankAccountPurpose)).perform(click()); + onView(withId(R.id.branchId)).perform(nestedScrollTo(), replaceText(INVALID_ROUTING_NUMBER)); + onView(withId(R.id.bankAccountId)).perform(nestedScrollTo(), replaceText(ACCOUNT_NUMBER)); + onView(withId(R.id.bankAccountPurpose)).perform(nestedScrollTo(), click()); onView(allOf(withId(R.id.select_name), withText("Checking"))).perform(click()); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); diff --git a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankCardTest.java b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankCardTest.java index 7ec4d7326..3003b01b3 100644 --- a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankCardTest.java +++ b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/BankCardTest.java @@ -2,11 +2,11 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.pressImeActionButton; +import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.action.ViewActions.typeText; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withParent; @@ -22,6 +22,7 @@ import static java.net.HttpURLConnection.HTTP_OK; import static java.util.concurrent.TimeUnit.SECONDS; +import static com.hyperwallet.android.util.EspressoUtils.hasEmptyText; import static com.hyperwallet.android.util.EspressoUtils.hasErrorText; import static com.hyperwallet.android.util.EspressoUtils.nestedScrollTo; import static com.hyperwallet.android.util.EspressoUtils.withHint; @@ -122,16 +123,19 @@ public void unregisterIdlingResource() { public void testAddTransferMethod_displaysElementsOnTmcResponse() { mActivityTestRule.launchActivity(null); - onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))).check( - matches(withText(R.string.title_add_bank_card))); + onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))) + .check(matches(withText(R.string.title_add_bank_card))); - onView(withId(R.id.cardNumber)).check(matches(isDisplayed())); + onView(allOf(withId(R.id.section_header_title), withText("Account Information - United States (USD)"))) + .perform(nestedScrollTo()) + .check(matches(isDisplayed())); + onView(withId(R.id.cardNumber)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.cardNumberLabel)).check(matches(isDisplayed())); onView(withId(R.id.cardNumberLabel)).check(matches(withHint(CARD_NUMBER_LABEL))); - onView(withId(R.id.dateOfExpiry)).check(matches(isDisplayed())); + onView(withId(R.id.dateOfExpiry)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.dateOfExpiryLabel)).check(matches(isDisplayed())); onView(withId(R.id.dateOfExpiryLabel)).check(matches(withHint(EXPIRY_DATE_LABEL))); - onView(withId(R.id.cvv)).check(matches(isDisplayed())); + onView(withId(R.id.cvv)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.cvvLabel)).check(matches(isDisplayed())); onView(withId(R.id.cvvLabel)).check(matches(withHint(CVV_LABEL))); @@ -160,6 +164,24 @@ public void testAddTransferMethod_displaysFeeElementsOnTmcResponse() { // onView(withId(R.id.add_transfer_method_fee_value)).check(matches(withText("1 - 2 Business Days"))); } + @Test + public void testAddTransferMethod_verifyDefaultValues() { + mActivityTestRule.launchActivity(null); + + onView(withId(R.id.cardNumber)).check(matches(hasEmptyText())); + onView(withId(R.id.dateOfExpiry)).check(matches(hasEmptyText())); + onView(withId(R.id.cvv)).check(matches(hasEmptyText())); + } + + @Test + public void testAddTransferMethod_verifyEditableFields() { + mActivityTestRule.launchActivity(null); + + onView(withId(R.id.cardNumber)).check(matches(isEnabled())); + onView(withId(R.id.dateOfExpiry)).check(matches(isEnabled())); + onView(withId(R.id.cvv)).check(matches(isEnabled())); + } + @Test public void testAddTransferMethod_returnsTokenOnBankCardCreation() throws InterruptedException { mMockWebServer.mockResponse().withHttpResponseCode(HTTP_CREATED).withBody(sResourceManager @@ -185,12 +207,11 @@ public void onReceive(Context context, Intent intent) { LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()) .registerReceiver(br, new IntentFilter("ACTION_HYPERWALLET_TRANSFER_METHOD_ADDED")); - onView(withId(R.id.cardNumber)).perform(typeText(VALID_CARD_NUMBER)).perform(closeSoftKeyboard()); - onView(withId(R.id.dateOfExpiry)).perform(typeText(VALID_EXPIRATION_DATE)).perform(closeSoftKeyboard()); - + onView(withId(R.id.cardNumber)).perform(nestedScrollTo(), replaceText(VALID_CARD_NUMBER)); + // Type text here instead to trigger auto-formatting + onView(withId(R.id.dateOfExpiry)).perform(nestedScrollTo(), typeText(VALID_EXPIRATION_DATE)); onView(withId(R.id.dateOfExpiry)).check(matches(withText(VALID_EXPIRATION_DATE_FORMATTED))); - - onView(withId(R.id.cvv)).perform(typeText(VALID_CVV)).perform(closeSoftKeyboard()); + onView(withId(R.id.cvv)).perform(nestedScrollTo(), replaceText(VALID_CVV)); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); gate.await(5, SECONDS); @@ -198,8 +219,8 @@ public void onReceive(Context context, Intent intent) { assertThat("Result code is incorrect", mActivityTestRule.getActivityResult().getResultCode(), is(Activity.RESULT_OK)); - LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver( - br); + LocalBroadcastManager.getInstance( + mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver(br); assertThat("Action is not broadcasted", gate.getCount(), is(0L)); } @@ -207,20 +228,24 @@ public void onReceive(Context context, Intent intent) { public void testAddTransferMethod_returnsErrorOnInvalidPattern() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.dateOfExpiry)) - .perform(typeText(INVALID_PATTERN_EXPIRATION_DATE)) - .perform(closeSoftKeyboard(), pressImeActionButton()); + onView(withId(R.id.cardNumber)).perform(nestedScrollTo(), replaceText("abc12341234cb")); + onView(withId(R.id.dateOfExpiry)).perform(nestedScrollTo(), replaceText(INVALID_PATTERN_EXPIRATION_DATE)); + onView(withId(R.id.cvv)).perform(nestedScrollTo(), replaceText("9-09")); + onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); + + onView(withId(R.id.cardNumberLabel)).check(matches(hasErrorText("is invalid length or format."))); onView(withId(R.id.dateOfExpiryLabel)).check(matches(hasErrorText("Expiry Date is invalid."))); + onView(withId(R.id.cvvLabel)).check(matches(hasErrorText("is invalid length or format."))); } @Test public void testAddTransferMethod_returnsErrorOnInvalidPresence() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.cardNumber)).perform(click()).perform(closeSoftKeyboard()); - onView(withId(R.id.dateOfExpiry)).perform(click()).perform(closeSoftKeyboard()); - onView(withId(R.id.cvv)).perform(click()).perform(closeSoftKeyboard()); + onView(withId(R.id.cardNumber)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.dateOfExpiry)).perform(nestedScrollTo(), replaceText("")); + onView(withId(R.id.cvv)).perform(nestedScrollTo(), replaceText("")); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); @@ -236,11 +261,18 @@ public void testAddTransferMethod_returnsErrorOnInvalidPresence() { public void testAddTransferMethod_returnsErrorOnInvalidLength() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.cardNumber)).perform(typeText(WRONG_LENGTH_CARD_NUMBER)).perform(closeSoftKeyboard()); + onView(withId(R.id.cardNumber)).perform(nestedScrollTo(), replaceText(WRONG_LENGTH_CARD_NUMBER)); + onView(withId(R.id.dateOfExpiry)).perform(nestedScrollTo(), replaceText("1")); + onView(withId(R.id.cvv)).perform(nestedScrollTo(), replaceText("1")); + onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); onView(withId(R.id.cardNumberLabel)).check( matches(hasErrorText("The minimum length of this field is 13 and maximum length is 19."))); + onView(withId(R.id.dateOfExpiryLabel)).check( + matches(hasErrorText("The length of this field is exactly 5."))); + onView(withId(R.id.cvvLabel)).check( + matches(hasErrorText("The minimum length of this field is 3 and maximum length is 4."))); } @Test @@ -250,9 +282,9 @@ public void testAddTransferMethod_returnsErrorOnInvalidCardNumber() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.cardNumber)).perform(typeText(NOT_VALID_CARD_NUMBER)).perform(closeSoftKeyboard()); - onView(withId(R.id.dateOfExpiry)).perform(typeText(VALID_EXPIRATION_DATE)).perform(closeSoftKeyboard()); - onView(withId(R.id.cvv)).perform(typeText(VALID_CVV)).perform(closeSoftKeyboard()); + onView(withId(R.id.cardNumber)).perform(nestedScrollTo(), replaceText(NOT_VALID_CARD_NUMBER)); + onView(withId(R.id.dateOfExpiry)).perform(nestedScrollTo(), replaceText(VALID_EXPIRATION_DATE)); + onView(withId(R.id.cvv)).perform(nestedScrollTo(), replaceText(VALID_CVV)); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); onView(withId(R.id.cardNumberLabel)).check(matches(hasErrorText( diff --git a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/PayPalTest.java b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/PayPalTest.java index 6b888844c..ee49a0163 100644 --- a/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/PayPalTest.java +++ b/ui/src/androidTest/java/com/hyperwallet/android/transfermethod/ui/PayPalTest.java @@ -2,12 +2,12 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; -import static androidx.test.espresso.action.ViewActions.typeText; +import static androidx.test.espresso.action.ViewActions.replaceText; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.RootMatchers.isDialog; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withParent; @@ -24,6 +24,7 @@ import static java.net.HttpURLConnection.HTTP_OK; import static java.util.concurrent.TimeUnit.SECONDS; +import static com.hyperwallet.android.util.EspressoUtils.hasEmptyText; import static com.hyperwallet.android.util.EspressoUtils.hasErrorText; import static com.hyperwallet.android.util.EspressoUtils.nestedScrollTo; import static com.hyperwallet.android.util.EspressoUtils.withHint; @@ -112,10 +113,10 @@ public void unregisterIdlingResource() { public void testAddTransferMethod_displaysElementsOnTmcResponse() { mActivityTestRule.launchActivity(null); - onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))).check( - matches(withText(R.string.paypal_account))); + onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar)))) + .check(matches(withText(R.string.paypal_account))); - onView(withId(R.id.email)).check(matches(isDisplayed())); + onView(withId(R.id.email)).perform(nestedScrollTo()).check(matches(isDisplayed())); onView(withId(R.id.emailLabel)).check(matches(isDisplayed())); onView(withId(R.id.emailLabel)).check(matches(withHint("Email"))); @@ -123,6 +124,20 @@ public void testAddTransferMethod_displaysElementsOnTmcResponse() { matches(withText(R.string.button_create_transfer_method))); } + @Test + public void testAddTransferMethod_verifyDefaultValues() { + mActivityTestRule.launchActivity(null); + + onView(withId(R.id.email)).check(matches(hasEmptyText())); + } + + @Test + public void testAddTransferMethod_verifyEditableFields() { + mActivityTestRule.launchActivity(null); + + onView(withId(R.id.email)).check(matches(isEnabled())); + } + @Test public void testAddTransferMethod_displaysFeeElementsOnTmcResponse() { mActivityTestRule.launchActivity(null); @@ -161,33 +176,32 @@ public void onReceive(Context context, Intent intent) { HyperwalletTransferMethod transferMethod = intent.getParcelableExtra( "hyperwallet-local-broadcast-payload"); assertThat("Bank Account Id is incorrect", transferMethod.getField( - HyperwalletTransferMethod.TransferMethodFields.EMAIL), is("sunshine.carreiro@hyperwallet.com")); + HyperwalletTransferMethod.TransferMethodFields.EMAIL), + is("sunshine.carreiro@hyperwallet.com")); } }; LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()) .registerReceiver(br, new IntentFilter("ACTION_HYPERWALLET_TRANSFER_METHOD_ADDED")); - onView(withId(R.id.email)) - .perform(typeText("sunshine.carreiro@hyperwallet.com")) - .perform(closeSoftKeyboard()); - + onView(withId(R.id.email)).perform(nestedScrollTo(), replaceText("sunshine.carreiro@hyperwallet.com")); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); assertThat("Result code is incorrect", mActivityTestRule.getActivityResult().getResultCode(), is(Activity.RESULT_OK)); gate.await(5, SECONDS); - LocalBroadcastManager.getInstance(mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver( - br); + LocalBroadcastManager + .getInstance(mActivityTestRule.getActivity().getApplicationContext()).unregisterReceiver(br); assertThat("Action is not broadcasted", gate.getCount(), is(0L)); } @Test public void testAddTransferMethod_returnsErrorOnInvalidPattern() { mActivityTestRule.launchActivity(null); - // Number input should not allow non numeric values - onView(withId(R.id.email)).perform(typeText("abc1test")); + + onView(withId(R.id.email)).perform(nestedScrollTo(), replaceText("abc1test")); + onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); onView(withId(R.id.emailLabel)) @@ -211,8 +225,7 @@ public void testAddTransferMethod_displaysErrorOnInvalidEmailAddress() { mActivityTestRule.launchActivity(null); - onView(withId(R.id.email)) - .perform(typeText("invalidEmail@gmail.com")).perform(closeSoftKeyboard()); + onView(withId(R.id.email)).perform(nestedScrollTo(), replaceText("invalidEmail@gmail.com")); onView(withId(R.id.add_transfer_method_button)).perform(nestedScrollTo(), click()); // check dialog content diff --git a/ui/src/androidTest/java/com/hyperwallet/android/util/EspressoUtils.java b/ui/src/androidTest/java/com/hyperwallet/android/util/EspressoUtils.java index 28fb0b590..92a711f96 100644 --- a/ui/src/androidTest/java/com/hyperwallet/android/util/EspressoUtils.java +++ b/ui/src/androidTest/java/com/hyperwallet/android/util/EspressoUtils.java @@ -19,6 +19,8 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; +import java.util.Objects; + public class EspressoUtils { public static Matcher withHint(final String expectedHint) { @@ -30,8 +32,7 @@ public boolean matchesSafely(View view) { return false; } - String hint = ((TextInputLayout) view).getHint().toString(); - + String hint = Objects.toString(((TextInputLayout) view).getHint()); return expectedHint.equals(hint); } @@ -51,8 +52,7 @@ public boolean matchesSafely(View view) { return false; } - String errorMessage = ((TextInputLayout) view).getError().toString(); - + String errorMessage = Objects.toString(((TextInputLayout) view).getError()); return expectedErrorMessage.equals(errorMessage); } @@ -72,7 +72,7 @@ public boolean matchesSafely(View view) { return false; } String expectedErrorMessage = view.getResources().getString(resourceId); - String errorMessage = ((TextInputLayout) view).getError().toString(); + String errorMessage = Objects.toString(((TextInputLayout) view).getError()); return expectedErrorMessage.equals(errorMessage); } @@ -132,37 +132,56 @@ public void describeTo(Description description) { }; } - public static Matcher hasEmptyText() { + public static ViewAction nestedScrollTo() { + return ViewActions.actionWithAssertions(new NestedScrollToAction()); + } + + private static Bitmap getBitmap(Drawable drawable) { + Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), + drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + + return bitmap; + } + + public static Matcher hasNoErrorText() { return new TypeSafeMatcher() { @Override public boolean matchesSafely(View view) { - if (!(view instanceof EditText)) { + if (!(view instanceof TextInputLayout)) { return false; } - String text = ((EditText) view).getText().toString(); - - return text.isEmpty(); + return ((TextInputLayout) view).getError() == null; } @Override public void describeTo(Description description) { + description.appendText("has no error text: "); } }; } - public static ViewAction nestedScrollTo() { - return ViewActions.actionWithAssertions(new NestedScrollToAction()); - } + public static Matcher hasEmptyText() { + return new TypeSafeMatcher() { - private static Bitmap getBitmap(Drawable drawable) { - Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), - drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + @Override + public boolean matchesSafely(View view) { + if (!(view instanceof EditText)) { + return false; + } + String text = ((EditText) view).getText().toString(); - Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); + return text.isEmpty(); + } - return bitmap; + @Override + public void describeTo(Description description) { + } + }; } } +