diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt index e101b527d0..8cfc796c4a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/AddressAutofillTest.kt @@ -9,6 +9,7 @@ import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestHelper.exitMenu import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar @@ -95,4 +96,183 @@ class AddressAutofillTest { verifyAddAddressButton() } } + + @Test + fun verifyAddAddressViewTest() { + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + clickAddAddressButton() + verifyAddAddressView() + }.goBackToAutofillSettings { + verifyAutofillToolbarTitle() + } + } + + @Test + fun verifyEditAddressViewTest() { + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + clickAddAddressButton() + fillAndSaveAddress( + "Mozilla", + "Fenix", + "Firefox", + "Harrison Street", + "San Francisco", + "Alaska", + "94105", + "United States", + "555-5555", + "foo@bar.com", + ) + clickManageAddressesButton() + clickSavedAddress("Mozilla") + verifyEditAddressView() + } + } + + @Test + fun verifyAddressAutofillToggleTest() { + val addressFormPage = + TestAssetHelper.getAddressFormAsset(mockWebServer) + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + verifyAddressAutofillSection(true, false) + clickAddAddressButton() + fillAndSaveAddress( + "Mozilla", + "Fenix", + "Firefox", + "Harrison Street", + "San Francisco", + "Alaska", + "94105", + "United States", + "555-5555", + "foo@bar.com", + ) + } + + exitMenu() + + navigationToolbar { + }.enterURLAndEnterToBrowser(addressFormPage.url) { + clickStreetAddressTextBox() + verifySelectAddressButtonExists(true) + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + clickSaveAndAutofillAddressesOption() + verifyAddressAutofillSection(false, true) + } + + exitMenu() + + navigationToolbar { + }.enterURLAndEnterToBrowser(addressFormPage.url) { + clickStreetAddressTextBox() + verifySelectAddressButtonExists(false) + } + } + + @Test + fun verifyManageAddressesPromptOptionTest() { + val addressFormPage = + TestAssetHelper.getAddressFormAsset(mockWebServer) + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + verifyAddressAutofillSection(true, false) + clickAddAddressButton() + fillAndSaveAddress( + "Mozilla", + "Fenix", + "Firefox", + "Harrison Street", + "San Francisco", + "Alaska", + "94105", + "United States", + "555-5555", + "foo@bar.com", + ) + } + + exitMenu() + + navigationToolbar { + }.enterURLAndEnterToBrowser(addressFormPage.url) { + clickStreetAddressTextBox() + clickSelectAddressButton() + }.clickManageAddressButton { + verifyAutofillToolbarTitle() + }.goBackToBrowser { + verifySaveLoginPromptIsNotDisplayed() + } + } + + @Test + fun verifyAddressAutofillSelectionTest() { + val addressFormPage = + TestAssetHelper.getAddressFormAsset(mockWebServer) + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openAutofillSubMenu { + verifyAddressAutofillSection(true, false) + clickAddAddressButton() + fillAndSaveAddress( + "Mozilla", + "Fenix", + "Firefox", + "Harrison Street", + "San Francisco", + "Alaska", + "94105", + "United States", + "555-5555", + "foo@bar.com", + ) + clickManageAddressesButton() + clickAddAddressButton() + fillAndSaveAddress( + "Android", + "Test", + "Name", + "Fort Street", + "San Jose", + "Arizona", + "95141", + "United States", + "777-7777", + "fuu@bar.org", + ) + verifyManageAddressesToolbarTitle() + } + + exitMenu() + + navigationToolbar { + }.enterURLAndEnterToBrowser(addressFormPage.url) { + clickStreetAddressTextBox() + clickSelectAddressButton() + clickAddressSuggestion("Harrison Street") + verifyAutofilledAddress("Harrison Street") + clearAddressForm() + clickStreetAddressTextBox() + clickSelectAddressButton() + clickAddressSuggestion("Fort Street") + verifyAutofilledAddress("Fort Street") + } + } } 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 30670aa8a6..d13d3c3c13 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 @@ -523,11 +523,22 @@ class BrowserRobot { fun clickStreetAddressTextBox() = clickPageObject(webPageItemWithResourceId("streetAddress")) + fun clearAddressForm() { + webPageItemWithResourceId("streetAddress").clearTextField() + webPageItemWithResourceId("city").clearTextField() + webPageItemWithResourceId("zipCode").clearTextField() + webPageItemWithResourceId("country").clearTextField() + webPageItemWithResourceId("telephone").clearTextField() + webPageItemWithResourceId("email").clearTextField() + } + fun clickSelectAddressButton() { selectAddressButton.waitForExists(waitingTime) selectAddressButton.clickAndWaitForNewWindow(waitingTime) } + fun verifySelectAddressButtonExists(exists: Boolean) = assertItemWithResIdExists(selectAddressButton, exists = exists) + fun clickCardNumberTextBox() = clickPageObject(webPageItemWithResourceId("cardNumber")) fun clickSelectCreditCardButton() { @@ -1130,6 +1141,13 @@ class BrowserRobot { SiteSecurityRobot().interact() return SiteSecurityRobot.Transition() } + + fun clickManageAddressButton(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { + itemWithResId("$packageName:id/manage_addresses").clickAndWaitForNewWindow(waitingTime) + + SettingsSubMenuAutofillRobot().interact() + return SettingsSubMenuAutofillRobot.Transition() + } } } 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 f85402855c..10f7647470 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 @@ -5,13 +5,27 @@ package org.mozilla.fenix.ui.robots import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.RootMatchers +import androidx.test.espresso.matcher.ViewMatchers.isChecked +import androidx.test.espresso.matcher.ViewMatchers.isNotChecked +import androidx.test.espresso.matcher.ViewMatchers.withClassName import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.uiautomator.UiSelector +import org.hamcrest.CoreMatchers.allOf +import org.hamcrest.CoreMatchers.endsWith import org.junit.Assert.assertTrue import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.MatcherHelper.assertItemContainingTextExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithDescriptionExists +import org.mozilla.fenix.helpers.MatcherHelper.assertItemWithResIdExists +import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText +import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription +import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.getStringResource +import org.mozilla.fenix.helpers.TestHelper.hasCousin import org.mozilla.fenix.helpers.TestHelper.mDevice import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText @@ -19,12 +33,129 @@ import org.mozilla.fenix.helpers.click class SettingsSubMenuAutofillRobot { + fun verifyAutofillToolbarTitle() = assertItemContainingTextExists(autofillToolbarTitle) + fun verifyManageAddressesToolbarTitle() = assertItemContainingTextExists(manageAddressesToolbarTitle) + + fun verifyAddressAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedAddress: Boolean) { + assertItemContainingTextExists( + autofillToolbarTitle, + addressesSectionTitle, + saveAndAutofillAddressesOption, + saveAndAutofillAddressesSummary, + ) + + if (userHasSavedAddress) { + assertItemContainingTextExists(manageAddressesButton) + } else { + assertItemContainingTextExists(addAddressButton) + } + + verifyAddressesAutofillToggle(isAddressAutofillEnabled) + } + + fun verifyManageAddressesSection(vararg savedAddressDetails: String) { + assertItemWithDescriptionExists(navigateBackButton) + assertItemContainingTextExists( + manageAddressesToolbarTitle, + addAddressButton, + ) + for (savedAddressDetail in savedAddressDetails) { + assertTrue( + mDevice.findObject( + UiSelector().textContains(savedAddressDetail), + ).waitForExists(waitingTime), + ) + } + } + + fun verifyAddressesAutofillToggle(enabled: Boolean) = + onView(withText(R.string.preferences_addresses_save_and_autofill_addresses)) + .check( + matches( + hasCousin( + allOf( + withClassName(endsWith("Switch")), + if (enabled) { + isChecked() + } else { + isNotChecked() + }, + ), + ), + ), + ) + + fun verifyAddAddressView() { + assertItemContainingTextExists(addAddressToolbarTitle) + assertItemWithDescriptionExists(navigateBackButton) + assertItemWithResIdExists( + toolbarCheckmarkButton, + firstNameTextInput, + middleNameTextInput, + ) + scrollToElementByText(getStringResource(R.string.addresses_street_address)) + assertItemWithResIdExists( + lastNameTextInput, + streetAddressTextInput, + ) + scrollToElementByText(getStringResource(R.string.addresses_country)) + assertItemWithResIdExists( + cityTextInput, + subRegionDropDown, + zipCodeTextInput, + ) + scrollToElementByText(getStringResource(R.string.addresses_save_button)) + assertItemWithResIdExists( + countryDropDown, + phoneTextInput, + emailTextInput, + ) + assertItemWithResIdExists( + saveButton, + cancelButton, + ) + } + + fun verifyEditAddressView() { + assertItemContainingTextExists(editAddressToolbarTitle) + assertItemWithDescriptionExists(navigateBackButton) + assertItemWithResIdExists( + toolbarDeleteAddressButton, + toolbarCheckmarkButton, + firstNameTextInput, + middleNameTextInput, + ) + scrollToElementByText(getStringResource(R.string.addresses_street_address)) + assertItemWithResIdExists( + lastNameTextInput, + streetAddressTextInput, + ) + scrollToElementByText(getStringResource(R.string.addresses_country)) + assertItemWithResIdExists( + cityTextInput, + subRegionDropDown, + zipCodeTextInput, + ) + scrollToElementByText(getStringResource(R.string.addresses_save_button)) + assertItemWithResIdExists( + countryDropDown, + phoneTextInput, + emailTextInput, + ) + assertItemWithResIdExists( + saveButton, + cancelButton, + ) + assertItemContainingTextExists(deleteAddressButton) + } + + fun clickSaveAndAutofillAddressesOption() = saveAndAutofillAddressesOption.click() fun clickAddAddressButton() = addAddressButton.click() fun clickManageAddressesButton() = manageAddressesButton.click() fun clickSavedAddress(firstName: String) = savedAddress(firstName).clickAndWaitForNewWindow(waitingTime) fun clickDeleteAddressButton() { - deleteAddressButton.waitForExists(waitingTime) - deleteAddressButton.click() + toolbarDeleteAddressButton.waitForExists(waitingTime) + toolbarDeleteAddressButton.click() } fun clickCancelDeleteAddressButton() = cancelDeleteAddressButton.click() @@ -117,28 +248,46 @@ class SettingsSubMenuAutofillRobot { } fun goBackToAutofillSettings(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition { - mDevice.pressBack() + navigateBackButton.click() SettingsSubMenuAutofillRobot().interact() return SettingsSubMenuAutofillRobot.Transition() } + + fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + mDevice.pressBack() + + BrowserRobot().interact() + return BrowserRobot.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")) -private val streetAddressTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/street_address_input")) -private val cityTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/city_input")) -private val subRegionDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/subregion_drop_down")) -private val zipCodeTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/zip_input")) -private val countryDropDown = mDevice.findObject(UiSelector().resourceId("$packageName:id/country_drop_down")) -private val phoneTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/phone_input")) -private val emailTextInput = mDevice.findObject(UiSelector().resourceId("$packageName:id/email_input")) -private val saveButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/save_button")) -private val deleteAddressButton = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_address_button")) +private val autofillToolbarTitle = itemContainingText(getStringResource(R.string.preferences_autofill)) +private val addressesSectionTitle = itemContainingText(getStringResource(R.string.preferences_addresses)) +private val manageAddressesToolbarTitle = itemContainingText(getStringResource(R.string.addresses_manage_addresses)) +private val saveAndAutofillAddressesOption = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses)) +private val saveAndAutofillAddressesSummary = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses_summary)) +private val addAddressButton = itemContainingText(getStringResource(R.string.preferences_addresses_add_address)) +private val manageAddressesButton = itemContainingText(getStringResource(R.string.preferences_addresses_manage_addresses)) +private val addAddressToolbarTitle = itemContainingText(getStringResource(R.string.addresses_add_address)) +private val editAddressToolbarTitle = itemContainingText(getStringResource(R.string.addresses_edit_address)) +private val toolbarCheckmarkButton = itemWithResId("$packageName:id/save_address_button") +private val navigateBackButton = itemWithDescription(getStringResource(R.string.action_bar_up_description)) +private val firstNameTextInput = itemWithResId("$packageName:id/first_name_input") +private val middleNameTextInput = itemWithResId("$packageName:id/middle_name_input") +private val lastNameTextInput = itemWithResId("$packageName:id/last_name_input") +private val streetAddressTextInput = itemWithResId("$packageName:id/street_address_input") +private val cityTextInput = itemWithResId("$packageName:id/city_input") +private val subRegionDropDown = itemWithResId("$packageName:id/subregion_drop_down") +private val zipCodeTextInput = itemWithResId("$packageName:id/zip_input") +private val countryDropDown = itemWithResId("$packageName:id/country_drop_down") +private val phoneTextInput = itemWithResId("$packageName:id/phone_input") +private val emailTextInput = itemWithResId("$packageName:id/email_input") +private val saveButton = itemWithResId("$packageName:id/save_button") +private val cancelButton = itemWithResId("$packageName:id/cancel_button") +private val deleteAddressButton = itemContainingText(getStringResource(R.string.addressess_delete_address_button)) +private val toolbarDeleteAddressButton = itemWithResId("$packageName:id/delete_address_button") private val cancelDeleteAddressButton = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog()) private val confirmDeleteAddressButton = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())