diff --git a/app/src/androidTest/assets/pages/addressForm.html b/app/src/androidTest/assets/pages/addressForm.html index f88f731749..d1aa851518 100644 --- a/app/src/androidTest/assets/pages/addressForm.html +++ b/app/src/androidTest/assets/pages/addressForm.html @@ -4,14 +4,13 @@ Address_Form - -
+

Street Address:

City:

Zip Code:

Country:

Telephone:

Email:

-
+ \ No newline at end of file diff --git a/app/src/androidTest/assets/pages/creditCardForm.html b/app/src/androidTest/assets/pages/creditCardForm.html new file mode 100644 index 0000000000..c7b49ea2cf --- /dev/null +++ b/app/src/androidTest/assets/pages/creditCardForm.html @@ -0,0 +1,13 @@ + + + + Credit_Card_Form + + +
+

Card information

+

Card Number:

+

Name on card:

+
+ + \ No newline at end of file diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt index 586ca8a342..295395e571 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt @@ -93,6 +93,12 @@ object TestAssetHelper { return TestAsset(url, "", "") } + fun getCreditCardFormAsset(server: MockWebServer): TestAsset { + val url = server.url("pages/creditCardForm.html").toString().toUri()!! + + return TestAsset(url, "", "") + } + fun getAudioPageAsset(server: MockWebServer): TestAsset { val url = server.url("pages/audioMediaPage.html").toString().toUri()!! val title = "Audio_Test_Page" diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsBasicsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsBasicsTest.kt index 4f6aa65ecc..aed05835d6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsBasicsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsBasicsTest.kt @@ -17,9 +17,15 @@ import org.mozilla.fenix.helpers.FeatureSettingsHelper import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.getLoremIpsumAsset +import org.mozilla.fenix.ui.SettingsBasicsTest.creditCard.MOCK_CREDIT_CARD_NUMBER +import org.mozilla.fenix.ui.SettingsBasicsTest.creditCard.MOCK_EXPIRATION_MONTH +import org.mozilla.fenix.ui.SettingsBasicsTest.creditCard.MOCK_EXPIRATION_YEAR +import org.mozilla.fenix.ui.SettingsBasicsTest.creditCard.MOCK_LAST_CARD_DIGITS +import org.mozilla.fenix.ui.SettingsBasicsTest.creditCard.MOCK_NAME_ON_CARD import org.mozilla.fenix.ui.robots.checkTextSizeOnWebsite import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar +import java.time.LocalDate /** * Tests for verifying the General section of the Settings menu @@ -30,6 +36,14 @@ class SettingsBasicsTest { private lateinit var mockWebServer: MockWebServer private val featureSettingsHelper = FeatureSettingsHelper() + object creditCard { + const val MOCK_CREDIT_CARD_NUMBER = "5555555555554444" + const val MOCK_LAST_CARD_DIGITS = "4444" + const val MOCK_NAME_ON_CARD = "Mastercard" + const val MOCK_EXPIRATION_MONTH = "February" + val MOCK_EXPIRATION_YEAR = (LocalDate.now().year + 1).toString() + } + @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule() @@ -190,4 +204,49 @@ class SettingsBasicsTest { verifyAddAddressButton() } } + + @SmokeTest + @Test + fun verifyCreditCardAutofillTest() { + val creditCardFormPage = TestAssetHelper.getCreditCardFormAsset(mockWebServer) + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + clickAddCreditCardButton() + fillAndSaveCreditCard(MOCK_CREDIT_CARD_NUMBER, MOCK_NAME_ON_CARD, MOCK_EXPIRATION_MONTH, MOCK_EXPIRATION_YEAR) + // Opening Manage saved cards to dismiss here the Secure your credit prompt + clickManageSavedCardsButton() + clickSecuredCreditCardsLaterButton() + }.goBackToAutofillSettings { + }.goBack { + }.goBack { + } + navigationToolbar { + }.enterURLAndEnterToBrowser(creditCardFormPage.url) { + clickCardNumberTextBox() + clickSelectCreditCardButton() + clickCreditCardSuggestion(MOCK_LAST_CARD_DIGITS) + verifyAutofilledCreditCard(MOCK_CREDIT_CARD_NUMBER) + } + } + + @SmokeTest + @Test + fun deleteSavedCreditCardTest() { + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + clickAddCreditCardButton() + fillAndSaveCreditCard(MOCK_CREDIT_CARD_NUMBER, MOCK_NAME_ON_CARD, MOCK_EXPIRATION_MONTH, MOCK_EXPIRATION_YEAR) + clickManageSavedCardsButton() + clickSecuredCreditCardsLaterButton() + clickSavedCreditCard() + clickDeleteCreditCardButton() + clickConfirmDeleteCreditCardButton() + verifyAddCreditCardsButton() + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index 87b1746d72..442a14aa1a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -609,6 +609,16 @@ class BrowserRobot { selectAddressButton.clickAndWaitForNewWindow(waitingTime) } + fun clickCardNumberTextBox() { + creditCardNumberTextBox().waitForExists(waitingTime) + creditCardNumberTextBox().click() + } + + fun clickSelectCreditCardButton() { + selectCreditCardButton.waitForExists(waitingTime) + selectCreditCardButton.clickAndWaitForNewWindow(waitingTime) + } + fun clickLoginSuggestion(userName: String) { val loginSuggestion = mDevice.findObject( @@ -625,6 +635,11 @@ class BrowserRobot { addressSuggestion(streetName).click() } + fun clickCreditCardSuggestion(creditCardNumber: String) { + creditCardSuggestion(creditCardNumber).waitForExists(waitingTime) + creditCardSuggestion(creditCardNumber).click() + } + fun verifySuggestedUserName(userName: String) { mDevice.findObject( UiSelector() @@ -665,6 +680,11 @@ class BrowserRobot { assertTrue(streetAddressTextBox(streetAddress).waitForExists(waitingTime)) } + fun verifyAutofilledCreditCard(creditCardNumber: String) { + mDevice.waitForObjects(creditCardNumberTextBox(creditCardNumber)) + assertTrue(creditCardNumberTextBox(creditCardNumber).waitForExists(waitingTime)) + } + fun verifyPrefilledPWALoginCredentials(userName: String, shortcutTitle: String) { mDevice.waitForIdle(waitingTime) @@ -927,6 +947,7 @@ private var progressBar = private val suggestedLogins = mDevice.findObject(UiSelector().resourceId("$packageName:id/loginSelectBar")) private val selectAddressButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/select_address_header")) +private val selectCreditCardButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/select_credit_card_header")) private fun addressSuggestion(streetName: String) = mDevice.findObject( @@ -944,6 +965,22 @@ private fun streetAddressTextBox(streetAddress: String = "") = .packageName("$packageName") ) +private fun creditCardNumberTextBox(creditCardNumber: String = "") = + mDevice.findObject( + UiSelector() + .resourceId("cardNumber") + .textContains(creditCardNumber) + .className("android.widget.EditText") + .packageName("$packageName") + ) + +private fun creditCardSuggestion(creditCardNumber: String) = + mDevice.findObject( + UiSelector() + .resourceId("$packageName:id/credit_card_number") + .textContains(creditCardNumber) + ) + // Permissions test page elements & prompts // Test page used located at https://mozilla-mobile.github.io/testapp/permissions private val cameraButton = mDevice.findObject(UiSelector().text("Open camera")) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt index c99e893898..23eef99d8c 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAutofillRobot.kt @@ -72,6 +72,45 @@ class SettingsSubMenuAutofillRobot { manageAddressesButton.waitForExists(waitingTime) } + fun clickAddCreditCardButton() = addCreditCardButton.click() + fun clickManageSavedCardsButton() = manageSavedCardsButton.click() + fun clickSecuredCreditCardsLaterButton() = securedCreditCardsLaterButton.click() + fun clickSavedCreditCard() = savedCreditCardNumber.clickAndWaitForNewWindow(waitingTime) + fun clickDeleteCreditCardButton() { + deleteCreditCardButton.waitForExists(waitingTime) + deleteCreditCardButton.click() + } + + fun clickConfirmDeleteCreditCardButton() { + confirmDeleteCreditCardButton.waitForExists(waitingTime) + confirmDeleteCreditCardButton.click() + } + + fun clickExpiryMonthOption(expiryMonth: String) { + expiryMonthOption(expiryMonth).waitForExists(waitingTime) + expiryMonthOption(expiryMonth).click() + } + + fun clickExpiryYearOption(expiryYear: String) { + expiryYearOption(expiryYear).waitForExists(waitingTime) + expiryYearOption(expiryYear).click() + } + + fun verifyAddCreditCardsButton() = assertTrue(addCreditCardButton.waitForExists(waitingTime)) + + fun fillAndSaveCreditCard(cardNumber: String, cardName: String, expiryMonth: String, expiryYear: String) { + cardNumberTextInput.waitForExists(waitingTime) + cardNumberTextInput.setText(cardNumber) + nameOnCardTextInput.setText(cardName) + expiryMonthDropDown.click() + clickExpiryMonthOption(expiryMonth) + expiryYearDropDown.click() + clickExpiryYearOption(expiryYear) + + saveButton.click() + manageSavedCardsButton.waitForExists(waitingTime) + } + class Transition { fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { mDevice.pressBack() @@ -79,12 +118,18 @@ class SettingsSubMenuAutofillRobot { SettingsRobot().interact() return SettingsRobot.Transition() } + + fun goBackToAutofillSettings(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { + mDevice.pressBack() + + SettingsSubMenuAutofillRobot().interact() + return SettingsSubMenuAutofillRobot.Transition() + } } } private val addAddressButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_addresses_add_address))) private val manageAddressesButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_addresses_manage_addresses))) - private val firstNameTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/first_name_input")) private val middleNameTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/middle_name_input")) private val lastNameTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/last_name_input")) @@ -100,6 +145,20 @@ private val deleteAddressButton = mDevice.findObject(UiSelector().resourceId("$p private val cancelDeleteAddressButton = mDevice.findObject(UiSelector().resourceId("android:id/button2")) private val confirmDeleteAddressButton = mDevice.findObject(UiSelector().resourceId("android:id/button1")) +private val addCreditCardButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_add_credit_card))) +private val manageSavedCardsButton = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_manage_saved_cards))) +private val cardNumberTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/card_number_input")) +private val nameOnCardTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/name_on_card_input")) +private val expiryMonthDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_month_drop_down")) +private val expiryYearDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_year_drop_down")) +private val savedCreditCardNumber = mDevice.findObject(UiSelector().resourceId("$packageName:id/credit_card_logo")) +private val deleteCreditCardButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_credit_card_button")) +private val confirmDeleteCreditCardButton = mDevice.findObject(UiSelector().resourceId("android:id/button1")) +private val securedCreditCardsLaterButton = mDevice.findObject(UiSelector().resourceId("android:id/button2")) + private fun savedAddress(firstName: String) = mDevice.findObject(UiSelector().textContains(firstName)) private fun subRegionOption(subRegion: String) = mDevice.findObject(UiSelector().textContains(subRegion)) private fun countryOption(country: String) = mDevice.findObject(UiSelector().textContains(country)) + +private fun expiryMonthOption(expiryMonth: String) = mDevice.findObject(UiSelector().textContains(expiryMonth)) +private fun expiryYearOption(expiryYear: String) = mDevice.findObject(UiSelector().textContains(expiryYear))