Bug 1880640 - Add pairs of logs to SettingsSubMenuAutofillRobot
[gecko.git] / mobile / android / fenix / app / src / androidTest / java / org / mozilla / fenix / ui / robots / SettingsSubMenuAutofillRobot.kt
blobc9af2fdc6dff77db2b874b0c97acc7ea5f83bcc2
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.fenix.ui.robots
7 import android.util.Log
8 import androidx.test.espresso.Espresso.onView
9 import androidx.test.espresso.assertion.ViewAssertions.matches
10 import androidx.test.espresso.matcher.RootMatchers
11 import androidx.test.espresso.matcher.ViewMatchers.isChecked
12 import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
13 import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
14 import androidx.test.espresso.matcher.ViewMatchers.withChild
15 import androidx.test.espresso.matcher.ViewMatchers.withClassName
16 import androidx.test.espresso.matcher.ViewMatchers.withId
17 import androidx.test.espresso.matcher.ViewMatchers.withText
18 import androidx.test.uiautomator.UiSelector
19 import org.hamcrest.CoreMatchers.allOf
20 import org.hamcrest.CoreMatchers.endsWith
21 import org.junit.Assert.assertEquals
22 import org.mozilla.fenix.R
23 import org.mozilla.fenix.helpers.Constants.TAG
24 import org.mozilla.fenix.helpers.DataGenerationHelper.getStringResource
25 import org.mozilla.fenix.helpers.MatcherHelper.assertUIObjectExists
26 import org.mozilla.fenix.helpers.MatcherHelper.itemContainingText
27 import org.mozilla.fenix.helpers.MatcherHelper.itemWithDescription
28 import org.mozilla.fenix.helpers.MatcherHelper.itemWithResId
29 import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
30 import org.mozilla.fenix.helpers.TestHelper.hasCousin
31 import org.mozilla.fenix.helpers.TestHelper.mDevice
32 import org.mozilla.fenix.helpers.TestHelper.packageName
33 import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
34 import org.mozilla.fenix.helpers.click
36 class SettingsSubMenuAutofillRobot {
38     fun verifyAutofillToolbarTitle() {
39         assertUIObjectExists(autofillToolbarTitle())
40     }
41     fun verifyManageAddressesToolbarTitle() {
42         Log.i(TAG, "verifyManageAddressesToolbarTitle: Trying to verify that the \"Manage addresses\" toolbar title is displayed")
43         onView(
44             allOf(
45                 withId(R.id.navigationToolbar),
46                 withChild(
47                     withText(R.string.preferences_addresses_manage_addresses),
48                 ),
49             ),
50         ).check(matches(isDisplayed()))
51         Log.i(TAG, "verifyManageAddressesToolbarTitle: Verified that the \"Manage addresses\" toolbar title is displayed")
52     }
54     fun verifyAddressAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedAddress: Boolean) {
55         assertUIObjectExists(
56             autofillToolbarTitle(),
57             addressesSectionTitle(),
58             saveAndAutofillAddressesOption(),
59             saveAndAutofillAddressesSummary(),
60         )
62         if (userHasSavedAddress) {
63             assertUIObjectExists(manageAddressesButton())
64         } else {
65             assertUIObjectExists(addAddressButton())
66         }
68         verifyAddressesAutofillToggle(isAddressAutofillEnabled)
69     }
71     fun verifyCreditCardsAutofillSection(isAddressAutofillEnabled: Boolean, userHasSavedCreditCard: Boolean) {
72         assertUIObjectExists(
73             autofillToolbarTitle(),
74             creditCardsSectionTitle(),
75             saveAndAutofillCreditCardsOption(),
76             saveAndAutofillCreditCardsSummary(),
77             syncCreditCardsAcrossDevicesButton(),
79         )
81         if (userHasSavedCreditCard) {
82             assertUIObjectExists(manageSavedCreditCardsButton())
83         } else {
84             assertUIObjectExists(addCreditCardButton())
85         }
87         verifySaveAndAutofillCreditCardsToggle(isAddressAutofillEnabled)
88     }
90     fun verifyManageAddressesSection(vararg savedAddressDetails: String) {
91         assertUIObjectExists(
92             navigateBackButton(),
93             manageAddressesToolbarTitle(),
94             addAddressButton(),
95         )
96         for (savedAddressDetail in savedAddressDetails) {
97             assertUIObjectExists(itemContainingText(savedAddressDetail))
98         }
99     }
101     fun verifySavedCreditCardsSection(creditCardLastDigits: String, creditCardExpiryDate: String) {
102         assertUIObjectExists(
103             navigateBackButton(),
104             savedCreditCardsToolbarTitle(),
105             addCreditCardButton(),
106             itemContainingText(creditCardLastDigits),
107             itemContainingText(creditCardExpiryDate),
108         )
109     }
111     fun verifyAddressesAutofillToggle(enabled: Boolean) {
112         Log.i(TAG, "verifyAddressesAutofillToggle: Trying to verify that the \"Save and autofill addresses\" toggle is checked: $enabled")
113         onView(withText(R.string.preferences_addresses_save_and_autofill_addresses))
114             .check(
115                 matches(
116                     hasCousin(
117                         allOf(
118                             withClassName(endsWith("Switch")),
119                             if (enabled) {
120                                 isChecked()
121                             } else {
122                                 isNotChecked()
123                             },
124                         ),
125                     ),
126                 ),
127             )
128         Log.i(TAG, "verifyAddressesAutofillToggle: Verified that the \"Save and autofill addresses\" toggle is checked: $enabled")
129     }
131     fun verifySaveAndAutofillCreditCardsToggle(enabled: Boolean) {
132         Log.i(TAG, "verifySaveAndAutofillCreditCardsToggle: Trying to verify that the \"Save and autofill cards\" toggle is checked: $enabled")
133         onView(withText(R.string.preferences_credit_cards_save_and_autofill_cards))
134             .check(
135                 matches(
136                     hasCousin(
137                         allOf(
138                             withClassName(endsWith("Switch")),
139                             if (enabled) {
140                                 isChecked()
141                             } else {
142                                 isNotChecked()
143                             },
144                         ),
145                     ),
146                 ),
147             )
148         Log.i(TAG, "verifySaveAndAutofillCreditCardsToggle: Verified that the \"Save and autofill cards\" toggle is checked: $enabled")
149     }
151     fun verifyAddAddressView() {
152         assertUIObjectExists(
153             addAddressToolbarTitle(),
154             navigateBackButton(),
155             toolbarCheckmarkButton(),
156             firstNameTextInput(),
157             middleNameTextInput(),
158         )
159         scrollToElementByText(getStringResource(R.string.addresses_street_address))
160         assertUIObjectExists(
161             lastNameTextInput(),
162             streetAddressTextInput(),
163         )
164         scrollToElementByText(getStringResource(R.string.addresses_country))
165         assertUIObjectExists(
166             cityTextInput(),
167             subRegionDropDown(),
168             zipCodeTextInput(),
169         )
170         scrollToElementByText(getStringResource(R.string.addresses_save_button))
171         assertUIObjectExists(
172             countryDropDown(),
173             phoneTextInput(),
174             emailTextInput(),
175         )
176         assertUIObjectExists(
177             saveButton(),
178             cancelButton(),
179         )
180     }
182     fun verifyCountryOption(country: String) {
183         scrollToElementByText(getStringResource(R.string.addresses_country))
184         Log.i(TAG, "verifyCountryOption: Trying to click device back button")
185         mDevice.pressBack()
186         Log.i(TAG, "verifyCountryOption: Clicked device back button")
187         assertUIObjectExists(itemContainingText(country))
188     }
190     fun verifyStateOption(state: String) {
191         assertUIObjectExists(itemContainingText(state))
192     }
194     fun verifyCountryOptions(vararg countries: String) {
195         Log.i(TAG, "verifyCountryOptions: Trying to click the \"Country or region\" dropdown")
196         countryDropDown().click()
197         Log.i(TAG, "verifyCountryOptions: Clicked the \"Country or region\" dropdown")
198         for (country in countries) {
199             assertUIObjectExists(itemContainingText(country))
200         }
201     }
203     fun selectCountry(country: String) {
204         Log.i(TAG, "selectCountry: Trying to click the \"Country or region\" dropdown")
205         countryDropDown().click()
206         Log.i(TAG, "selectCountry: Clicked the \"Country or region\" dropdown")
207         Log.i(TAG, "selectCountry: Trying to select $country dropdown option")
208         countryOption(country).click()
209         Log.i(TAG, "selectCountry: Selected $country dropdown option")
210     }
212     fun verifyEditAddressView() {
213         assertUIObjectExists(
214             editAddressToolbarTitle(),
215             navigateBackButton(),
216             toolbarDeleteAddressButton(),
217             toolbarCheckmarkButton(),
218             firstNameTextInput(),
219             middleNameTextInput(),
220         )
221         scrollToElementByText(getStringResource(R.string.addresses_street_address))
222         assertUIObjectExists(
223             lastNameTextInput(),
224             streetAddressTextInput(),
225         )
226         scrollToElementByText(getStringResource(R.string.addresses_country))
227         assertUIObjectExists(
228             cityTextInput(),
229             subRegionDropDown(),
230             zipCodeTextInput(),
231         )
232         scrollToElementByText(getStringResource(R.string.addresses_save_button))
233         assertUIObjectExists(
234             countryDropDown(),
235             phoneTextInput(),
236             emailTextInput(),
237         )
238         assertUIObjectExists(
239             saveButton(),
240             cancelButton(),
241         )
242         assertUIObjectExists(deleteAddressButton())
243     }
245     fun clickSaveAndAutofillAddressesOption() {
246         Log.i(TAG, "clickSaveAndAutofillAddressesOption: Trying to click the \"Save and autofill addresses\" button")
247         saveAndAutofillAddressesOption().click()
248         Log.i(TAG, "clickSaveAndAutofillAddressesOption: Clicked the \"Save and autofill addresses\" button")
249     }
250     fun clickAddAddressButton() {
251         Log.i(TAG, "clickAddAddressButton: Trying to click the \"Add address\" button")
252         addAddressButton().click()
253         Log.i(TAG, "clickAddAddressButton: Clicked the \"Add address\" button")
254     }
255     fun clickManageAddressesButton() {
256         Log.i(TAG, "clickManageAddressesButton: Trying to click the \"Manage addresses\" button")
257         manageAddressesButton().click()
258         Log.i(TAG, "clickManageAddressesButton: Clicked the \"Manage addresses\" button")
259     }
260     fun clickSavedAddress(firstName: String) {
261         Log.i(TAG, "clickSavedAddress: Trying to click the $firstName saved address and and wait for $waitingTime ms for a new window")
262         savedAddress(firstName).clickAndWaitForNewWindow(waitingTime)
263         Log.i(TAG, "clickSavedAddress: Clicked the $firstName saved address and and waited for $waitingTime ms for a new window")
264     }
265     fun clickDeleteAddressButton() {
266         Log.i(TAG, "clickDeleteAddressButton: Waiting for $waitingTime ms for the delete address toolbar button to exist")
267         toolbarDeleteAddressButton().waitForExists(waitingTime)
268         Log.i(TAG, "clickDeleteAddressButton: Waited for $waitingTime ms for the delete address toolbar button to exist")
269         Log.i(TAG, "clickDeleteAddressButton: Trying to click the delete address toolbar button")
270         toolbarDeleteAddressButton().click()
271         Log.i(TAG, "clickDeleteAddressButton: Clicked the delete address toolbar button")
272     }
273     fun clickCancelDeleteAddressButton() {
274         Log.i(TAG, "clickCancelDeleteAddressButton: Trying to click the \"CANCEL\" button from the delete address dialog")
275         cancelDeleteAddressButton().click()
276         Log.i(TAG, "clickCancelDeleteAddressButton: Clicked the \"CANCEL\" button from the delete address dialog")
277     }
279     fun clickConfirmDeleteAddressButton() {
280         Log.i(TAG, "clickConfirmDeleteAddressButton: Trying to click the \"DELETE\" button from the delete address dialog")
281         confirmDeleteAddressButton().click()
282         Log.i(TAG, "clickConfirmDeleteAddressButton: Clicked \"DELETE\" button from the delete address dialog")
283     }
285     fun clickSubRegionOption(subRegion: String) {
286         scrollToElementByText(subRegion)
287         subRegionOption(subRegion).also {
288             Log.i(TAG, "clickSubRegionOption: Waiting for $waitingTime ms for the \"State\" $subRegion dropdown option to exist")
289             it.waitForExists(waitingTime)
290             Log.i(TAG, "clickSubRegionOption: Waited for $waitingTime ms for the \"State\" $subRegion dropdown option to exist")
291             Log.i(TAG, "clickSubRegionOption: Trying to click the \"State\" $subRegion dropdown option")
292             it.click()
293             Log.i(TAG, "clickSubRegionOption: Clicked the \"State\" $subRegion dropdown option")
294         }
295     }
296     fun clickCountryOption(country: String) {
297         Log.i(TAG, "clickCountryOption: Waiting for $waitingTime ms for the \"Country or region\" $country dropdown option to exist")
298         countryOption(country).waitForExists(waitingTime)
299         Log.i(TAG, "clickCountryOption: Waited for $waitingTime ms for the \"Country or region\" $country dropdown option to exist")
300         Log.i(TAG, "clickCountryOption: Trying to click \"Country or region\" $country dropdown option")
301         countryOption(country).click()
302         Log.i(TAG, "clickCountryOption: Clicked \"Country or region\" $country dropdown option")
303     }
304     fun verifyAddAddressButton() = assertUIObjectExists(addAddressButton())
306     fun fillAndSaveAddress(
307         navigateToAutofillSettings: Boolean,
308         isAddressAutofillEnabled: Boolean = true,
309         userHasSavedAddress: Boolean = false,
310         firstName: String,
311         middleName: String,
312         lastName: String,
313         streetAddress: String,
314         city: String,
315         state: String,
316         zipCode: String,
317         country: String,
318         phoneNumber: String,
319         emailAddress: String,
320     ) {
321         if (navigateToAutofillSettings) {
322             homeScreen {
323             }.openThreeDotMenu {
324             }.openSettings {
325             }.openAutofillSubMenu {
326                 verifyAddressAutofillSection(isAddressAutofillEnabled, userHasSavedAddress)
327                 clickAddAddressButton()
328             }
329         }
330         Log.i(TAG, "fillAndSaveAddress: Waiting for $waitingTime ms for \"First Name\" text field to exist")
331         firstNameTextInput().waitForExists(waitingTime)
332         Log.i(TAG, "fillAndSaveAddress: Waited for $waitingTime ms for \"First Name\" text field to exist")
333         Log.i(TAG, "fillAndSaveAddress: Trying to click device back button to dismiss keyboard using device back button")
334         mDevice.pressBack()
335         Log.i(TAG, "fillAndSaveAddress: Clicked device back button to dismiss keyboard using device back button")
336         Log.i(TAG, "fillAndSaveAddress: Trying to set \"First Name\" to $firstName")
337         firstNameTextInput().setText(firstName)
338         Log.i(TAG, "fillAndSaveAddress: \"First Name\" was set to $firstName")
339         Log.i(TAG, "fillAndSaveAddress: Trying to set \"Middle Name\" to $middleName")
340         middleNameTextInput().setText(middleName)
341         Log.i(TAG, "fillAndSaveAddress: \"Middle Name\" was set to $middleName")
342         Log.i(TAG, "fillAndSaveAddress: Trying to set \"Last Name\" to $lastName")
343         lastNameTextInput().setText(lastName)
344         Log.i(TAG, "fillAndSaveAddress: \"Last Name\" was set to $lastName")
345         Log.i(TAG, "fillAndSaveAddress: Trying to set \"Street Address\" to $streetAddress")
346         streetAddressTextInput().setText(streetAddress)
347         Log.i(TAG, "fillAndSaveAddress: \"Street Address\" was set to $streetAddress")
348         Log.i(TAG, "fillAndSaveAddress: Trying to set \"City\" to $city")
349         cityTextInput().setText(city)
350         Log.i(TAG, "fillAndSaveAddress: \"City\" was set to $city")
351         Log.i(TAG, "fillAndSaveAddress: Trying to click \"State\" dropdown button")
352         subRegionDropDown().click()
353         Log.i(TAG, "fillAndSaveAddress: Clicked \"State\" dropdown button")
354         Log.i(TAG, "fillAndSaveAddress: Trying to click the $state dropdown option")
355         clickSubRegionOption(state)
356         Log.i(TAG, "fillAndSaveAddress: Clicked $state dropdown option")
357         Log.i(TAG, "fillAndSaveAddress: Trying to set \"Zip\" to $zipCode")
358         zipCodeTextInput().setText(zipCode)
359         Log.i(TAG, "fillAndSaveAddress: \"Zip\" was set to $zipCode")
360         Log.i(TAG, "fillAndSaveAddress: Trying to click \"Country or region\" dropdown button")
361         countryDropDown().click()
362         Log.i(TAG, "fillAndSaveAddress: Clicked \"Country or region\" dropdown button")
363         Log.i(TAG, "fillAndSaveAddress: Trying to click $country dropdown option")
364         clickCountryOption(country)
365         Log.i(TAG, "fillAndSaveAddress: Clicked $country dropdown option")
366         scrollToElementByText(getStringResource(R.string.addresses_save_button))
367         Log.i(TAG, "fillAndSaveAddress: Trying to set \"Phone\" to $phoneNumber")
368         phoneTextInput().setText(phoneNumber)
369         Log.i(TAG, "fillAndSaveAddress: \"Phone\" was set to $phoneNumber")
370         Log.i(TAG, "fillAndSaveAddress: Trying to set \"Email\" to $emailAddress")
371         emailTextInput().setText(emailAddress)
372         Log.i(TAG, "fillAndSaveAddress: \"Email\" was set to $emailAddress")
373         Log.i(TAG, "fillAndSaveAddress: Trying to click the \"Save\" button")
374         saveButton().click()
375         Log.i(TAG, "fillAndSaveAddress: Clicked the \"Save\" button")
376         Log.i(TAG, "fillAndSaveAddress: Waiting for $waitingTime ms for for \"Manage addresses\" button to exist")
377         manageAddressesButton().waitForExists(waitingTime)
378         Log.i(TAG, "fillAndSaveAddress: Waited for $waitingTime ms for for \"Manage addresses\" button to exist")
379     }
381     fun clickAddCreditCardButton() {
382         Log.i(TAG, "clickAddCreditCardButton: Trying to click the \"Add credit card\" button")
383         addCreditCardButton().click()
384         Log.i(TAG, "clickAddCreditCardButton: Clicked the \"Add credit card\" button")
385     }
386     fun clickManageSavedCreditCardsButton() {
387         Log.i(TAG, "clickManageSavedCreditCardsButton: Trying to click the \"Manage saved cards\" button")
388         manageSavedCreditCardsButton().click()
389         Log.i(TAG, "clickManageSavedCreditCardsButton: Clicked the \"Manage saved cards\" button")
390     }
391     fun clickSecuredCreditCardsLaterButton() {
392         Log.i(TAG, "clickSecuredCreditCardsLaterButton: Trying to click the \"Later\" button")
393         securedCreditCardsLaterButton().click()
394         Log.i(TAG, "clickSecuredCreditCardsLaterButton: Clicked the \"Later\" button")
395     }
396     fun clickSavedCreditCard() {
397         Log.i(TAG, "clickSavedCreditCard: Trying to click the saved credit card and and wait for $waitingTime ms for a new window")
398         savedCreditCardNumber().clickAndWaitForNewWindow(waitingTime)
399         Log.i(TAG, "clickSavedCreditCard: Clicked the saved credit card and and waited for $waitingTime ms for a new window")
400     }
401     fun clickDeleteCreditCardToolbarButton() {
402         Log.i(TAG, "clickDeleteCreditCardToolbarButton: Waiting for $waitingTime ms for the delete credit card toolbar button to exist")
403         deleteCreditCardToolbarButton().waitForExists(waitingTime)
404         Log.i(TAG, "clickDeleteCreditCardToolbarButton: Waited for $waitingTime ms for the delete credit card toolbar button to exist")
405         Log.i(TAG, "clickDeleteCreditCardToolbarButton: Trying to click the delete credit card toolbar button")
406         deleteCreditCardToolbarButton().click()
407         Log.i(TAG, "clickDeleteCreditCardToolbarButton: Clicked the delete credit card toolbar button")
408     }
409     fun clickDeleteCreditCardMenuButton() {
410         Log.i(TAG, "clickDeleteCreditCardMenuButton: Waiting for $waitingTime ms for the delete credit card menu button to exist")
411         deleteCreditCardMenuButton().waitForExists(waitingTime)
412         Log.i(TAG, "clickDeleteCreditCardMenuButton: Waited for $waitingTime ms for the delete credit card menu button to exist")
413         Log.i(TAG, "clickDeleteCreditCardMenuButton: Trying to click the delete credit card menu button")
414         deleteCreditCardMenuButton().click()
415         Log.i(TAG, "clickDeleteCreditCardMenuButton: Clicked the delete credit card menu button")
416     }
417     fun clickSaveAndAutofillCreditCardsOption() {
418         Log.i(TAG, "clickSaveAndAutofillCreditCardsOption: Trying to click the \"Save and autofill cards\" option")
419         saveAndAutofillCreditCardsOption().click()
420         Log.i(TAG, "clickSaveAndAutofillCreditCardsOption: Clicked the \"Save and autofill cards\" option")
421     }
423     fun clickConfirmDeleteCreditCardButton() {
424         Log.i(TAG, "clickConfirmDeleteCreditCardButton: Trying to click the \"Delete\" credit card dialog button")
425         confirmDeleteCreditCardButton().click()
426         Log.i(TAG, "clickConfirmDeleteCreditCardButton: Clicked the \"Delete\" credit card dialog button")
427     }
429     fun clickCancelDeleteCreditCardButton() {
430         Log.i(TAG, "clickCancelDeleteCreditCardButton: Trying to click the \"Cancel\" credit card dialog button")
431         cancelDeleteCreditCardButton().click()
432         Log.i(TAG, "clickCancelDeleteCreditCardButton: Clicked the \"Cancel\" credit card dialog button")
433     }
435     fun clickExpiryMonthOption(expiryMonth: String) {
436         Log.i(TAG, "clickExpiryMonthOption: Waiting for $waitingTime ms for the $expiryMonth expiry month option to exist")
437         expiryMonthOption(expiryMonth).waitForExists(waitingTime)
438         Log.i(TAG, "clickExpiryMonthOption: Waited for $waitingTime ms for the $expiryMonth expiry month option to exist")
439         Log.i(TAG, "clickExpiryMonthOption: Trying to click $expiryMonth expiry month option")
440         expiryMonthOption(expiryMonth).click()
441         Log.i(TAG, "clickExpiryMonthOption: Clicked $expiryMonth expiry month option")
442     }
444     fun clickExpiryYearOption(expiryYear: String) {
445         Log.i(TAG, "clickExpiryYearOption: Waiting for $waitingTime ms for the $expiryYear expiry year option to exist")
446         expiryYearOption(expiryYear).waitForExists(waitingTime)
447         Log.i(TAG, "clickExpiryYearOption: Waited for $waitingTime ms for the $expiryYear expiry year option to exist")
448         Log.i(TAG, "clickExpiryYearOption: Trying to click $expiryYear expiry year option")
449         expiryYearOption(expiryYear).click()
450         Log.i(TAG, "clickExpiryYearOption: Clicked $expiryYear expiry year option")
451     }
453     fun verifyAddCreditCardsButton() = assertUIObjectExists(addCreditCardButton())
455     fun fillAndSaveCreditCard(cardNumber: String, cardName: String, expiryMonth: String, expiryYear: String) {
456         Log.i(TAG, "fillAndSaveCreditCard: Waiting for $waitingTime ms for the credit card number text field to exist")
457         creditCardNumberTextInput().waitForExists(waitingTime)
458         Log.i(TAG, "fillAndSaveCreditCard: Waited for $waitingTime ms for the credit card number text field to exist")
459         Log.i(TAG, "fillAndSaveCreditCard: Trying to set the credit card number to: $cardNumber")
460         creditCardNumberTextInput().setText(cardNumber)
461         Log.i(TAG, "fillAndSaveCreditCard: The credit card number was set to: $cardNumber")
462         Log.i(TAG, "fillAndSaveCreditCard: Trying to set the name on card to: $cardName")
463         nameOnCreditCardTextInput().setText(cardName)
464         Log.i(TAG, "fillAndSaveCreditCard: The credit card name was set to: $cardName")
465         Log.i(TAG, "fillAndSaveCreditCard: Trying to click the expiry month dropdown")
466         expiryMonthDropDown().click()
467         Log.i(TAG, "fillAndSaveCreditCard: Clicked the expiry month dropdown")
468         Log.i(TAG, "fillAndSaveCreditCard: Trying to click $expiryMonth expiry month option")
469         clickExpiryMonthOption(expiryMonth)
470         Log.i(TAG, "fillAndSaveCreditCard: Clicked $expiryMonth expiry month option")
471         Log.i(TAG, "fillAndSaveCreditCard: Trying to click the expiry year dropdown")
472         expiryYearDropDown().click()
473         Log.i(TAG, "fillAndSaveCreditCard: Clicked the expiry year dropdown")
474         Log.i(TAG, "fillAndSaveCreditCard: Trying to click $expiryYear expiry year option")
475         clickExpiryYearOption(expiryYear)
476         Log.i(TAG, "fillAndSaveCreditCard: Clicked $expiryYear expiry year option")
477         Log.i(TAG, "fillAndSaveCreditCard: Trying to click the \"Save\" button")
478         saveButton().click()
479         Log.i(TAG, "fillAndSaveCreditCard: Clicked the \"Save\" button")
480         Log.i(TAG, "fillAndSaveCreditCard: Waiting for $waitingTime ms for the \"Manage saved cards\" button to exist")
481         manageSavedCreditCardsButton().waitForExists(waitingTime)
482         Log.i(TAG, "fillAndSaveCreditCard: Waited for $waitingTime ms for the \"Manage saved cards\" button to exist")
483     }
485     fun clearCreditCardNumber() =
486         creditCardNumberTextInput().also {
487             Log.i(TAG, "clearCreditCardNumber: Waiting for $waitingTime ms for the credit card number text field to exist")
488             it.waitForExists(waitingTime)
489             Log.i(TAG, "clearCreditCardNumber: Waited for $waitingTime ms for the credit card number text field to exist")
490             Log.i(TAG, "clearCreditCardNumber: Trying to clear the credit card number text field")
491             it.clearTextField()
492             Log.i(TAG, "clearCreditCardNumber: Cleared the credit card number text field")
493         }
495     fun clearNameOnCreditCard() =
496         nameOnCreditCardTextInput().also {
497             Log.i(TAG, "clearNameOnCreditCard: Waiting for $waitingTime ms for name on card text field to exist")
498             it.waitForExists(waitingTime)
499             Log.i(TAG, "clearNameOnCreditCard: Waited for $waitingTime ms for name on card text field to exist")
500             Log.i(TAG, "clearNameOnCreditCard: Trying to clear the name on card text field")
501             it.clearTextField()
502             Log.i(TAG, "clearNameOnCreditCard: Cleared the name on card text field")
503         }
505     fun clickSaveCreditCardToolbarButton() {
506         Log.i(TAG, "clickSaveCreditCardToolbarButton: Trying to click the save credit card toolbar button")
507         saveCreditCardToolbarButton().click()
508         Log.i(TAG, "clickSaveCreditCardToolbarButton: Clicked the save credit card toolbar button")
509     }
511     fun verifyEditCreditCardView(
512         cardNumber: String,
513         cardName: String,
514         expiryMonth: String,
515         expiryYear: String,
516     ) {
517         assertUIObjectExists(
518             editCreditCardToolbarTitle(),
519             navigateBackButton(),
520             deleteCreditCardToolbarButton(),
521             saveCreditCardToolbarButton(),
522         )
523         Log.i(TAG, "verifyEditCreditCardView: Trying to verify that the card number text field is set to: $cardNumber")
524         assertEquals(cardNumber, creditCardNumberTextInput().text)
525         Log.i(TAG, "verifyEditCreditCardView: Verified that the card number text field was set to: $cardNumber")
526         Log.i(TAG, "verifyEditCreditCardView: Trying to verify that the card name text field is set to: $cardName")
527         assertEquals(cardName, nameOnCreditCardTextInput().text)
528         Log.i(TAG, "verifyEditCreditCardView: Verified that the card card name text field was set to: $cardName")
530         // Can't get the text from the drop-down items, need to verify them individually
531         assertUIObjectExists(
532             expiryYearDropDown(),
533             expiryMonthDropDown(),
534         )
536         assertUIObjectExists(
537             itemContainingText(expiryMonth),
538             itemContainingText(expiryYear),
539         )
541         assertUIObjectExists(
542             saveButton(),
543             cancelButton(),
544         )
546         assertUIObjectExists(deleteCreditCardMenuButton())
547     }
549     fun verifyEditCreditCardToolbarTitle() = assertUIObjectExists(editCreditCardToolbarTitle())
551     fun verifyCreditCardNumberErrorMessage() =
552         assertUIObjectExists(itemContainingText(getStringResource(R.string.credit_cards_number_validation_error_message)))
554     fun verifyNameOnCreditCardErrorMessage() =
555         assertUIObjectExists(itemContainingText(getStringResource(R.string.credit_cards_name_on_card_validation_error_message)))
557     class Transition {
558         fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition {
559             Log.i(TAG, "goBack: Trying to click the device back button")
560             mDevice.pressBack()
561             Log.i(TAG, "goBack: Clicked the device back button")
563             SettingsRobot().interact()
564             return SettingsRobot.Transition()
565         }
567         fun goBackToAutofillSettings(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
568             Log.i(TAG, "goBackToAutofillSettings: Trying to click the navigate up toolbar button")
569             navigateBackButton().click()
570             Log.i(TAG, "goBackToAutofillSettings: Clicked the navigate up toolbar button")
572             SettingsSubMenuAutofillRobot().interact()
573             return SettingsSubMenuAutofillRobot.Transition()
574         }
576         fun goBackToSavedCreditCards(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
577             Log.i(TAG, "goBackToSavedCreditCards: Trying to click the navigate up toolbar button")
578             navigateBackButton().click()
579             Log.i(TAG, "goBackToSavedCreditCards: Clicked the navigate up toolbar button")
581             SettingsSubMenuAutofillRobot().interact()
582             return SettingsSubMenuAutofillRobot.Transition()
583         }
585         fun goBackToBrowser(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition {
586             Log.i(TAG, "goBackToBrowser: Trying to click the device back button")
587             mDevice.pressBack()
588             Log.i(TAG, "goBackToBrowser: Clicked the device back button")
590             BrowserRobot().interact()
591             return BrowserRobot.Transition()
592         }
593     }
596 fun autofillScreen(interact: SettingsSubMenuAutofillRobot.() -> Unit): SettingsSubMenuAutofillRobot.Transition {
597     SettingsSubMenuAutofillRobot().interact()
598     return SettingsSubMenuAutofillRobot.Transition()
601 private fun autofillToolbarTitle() = itemContainingText(getStringResource(R.string.preferences_autofill))
602 private fun addressesSectionTitle() = itemContainingText(getStringResource(R.string.preferences_addresses))
603 private fun manageAddressesToolbarTitle() =
604     mDevice.findObject(
605         UiSelector()
606             .resourceId("$packageName:id/navigationToolbar")
607             .childSelector(UiSelector().text(getStringResource(R.string.addresses_manage_addresses))),
608     )
610 private fun saveAndAutofillAddressesOption() = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses))
611 private fun saveAndAutofillAddressesSummary() = itemContainingText(getStringResource(R.string.preferences_addresses_save_and_autofill_addresses_summary))
612 private fun addAddressButton() = itemContainingText(getStringResource(R.string.preferences_addresses_add_address))
613 private fun manageAddressesButton() =
614     mDevice.findObject(
615         UiSelector()
616             .resourceId("android:id/title")
617             .text(getStringResource(R.string.preferences_addresses_manage_addresses)),
618     )
619 private fun addAddressToolbarTitle() = itemContainingText(getStringResource(R.string.addresses_add_address))
620 private fun editAddressToolbarTitle() = itemContainingText(getStringResource(R.string.addresses_edit_address))
621 private fun toolbarCheckmarkButton() = itemWithResId("$packageName:id/save_address_button")
622 private fun navigateBackButton() = itemWithDescription(getStringResource(R.string.action_bar_up_description))
623 private fun firstNameTextInput() = itemWithResId("$packageName:id/first_name_input")
624 private fun middleNameTextInput() = itemWithResId("$packageName:id/middle_name_input")
625 private fun lastNameTextInput() = itemWithResId("$packageName:id/last_name_input")
626 private fun streetAddressTextInput() = itemWithResId("$packageName:id/street_address_input")
627 private fun cityTextInput() = itemWithResId("$packageName:id/city_input")
628 private fun subRegionDropDown() = itemWithResId("$packageName:id/subregion_drop_down")
629 private fun zipCodeTextInput() = itemWithResId("$packageName:id/zip_input")
630 private fun countryDropDown() = itemWithResId("$packageName:id/country_drop_down")
631 private fun phoneTextInput() = itemWithResId("$packageName:id/phone_input")
632 private fun emailTextInput() = itemWithResId("$packageName:id/email_input")
633 private fun saveButton() = itemWithResId("$packageName:id/save_button")
634 private fun cancelButton() = itemWithResId("$packageName:id/cancel_button")
635 private fun deleteAddressButton() = itemContainingText(getStringResource(R.string.addressess_delete_address_button))
636 private fun toolbarDeleteAddressButton() = itemWithResId("$packageName:id/delete_address_button")
637 private fun cancelDeleteAddressButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
638 private fun confirmDeleteAddressButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
640 private fun creditCardsSectionTitle() = itemContainingText(getStringResource(R.string.preferences_credit_cards))
641 private fun saveAndAutofillCreditCardsOption() = itemContainingText(getStringResource(R.string.preferences_credit_cards_save_and_autofill_cards))
642 private fun saveAndAutofillCreditCardsSummary() = itemContainingText(getStringResource(R.string.preferences_credit_cards_save_and_autofill_cards_summary))
643 private fun syncCreditCardsAcrossDevicesButton() = itemContainingText(getStringResource(R.string.preferences_credit_cards_sync_cards_across_devices))
644 private fun addCreditCardButton() = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_add_credit_card)))
645 private fun savedCreditCardsToolbarTitle() = itemContainingText(getStringResource(R.string.credit_cards_saved_cards))
646 private fun editCreditCardToolbarTitle() = itemContainingText(getStringResource(R.string.credit_cards_edit_card))
647 private fun manageSavedCreditCardsButton() = mDevice.findObject(UiSelector().textContains(getStringResource(R.string.preferences_credit_cards_manage_saved_cards)))
648 private fun creditCardNumberTextInput() = mDevice.findObject(UiSelector().resourceId("$packageName:id/card_number_input"))
649 private fun nameOnCreditCardTextInput() = mDevice.findObject(UiSelector().resourceId("$packageName:id/name_on_card_input"))
650 private fun expiryMonthDropDown() = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_month_drop_down"))
651 private fun expiryYearDropDown() = mDevice.findObject(UiSelector().resourceId("$packageName:id/expiry_year_drop_down"))
652 private fun savedCreditCardNumber() = mDevice.findObject(UiSelector().resourceId("$packageName:id/credit_card_logo"))
653 private fun deleteCreditCardToolbarButton() = mDevice.findObject(UiSelector().resourceId("$packageName:id/delete_credit_card_button"))
654 private fun saveCreditCardToolbarButton() = itemWithResId("$packageName:id/save_credit_card_button")
655 private fun deleteCreditCardMenuButton() = itemContainingText(getStringResource(R.string.credit_cards_delete_card_button))
656 private fun confirmDeleteCreditCardButton() = onView(withId(android.R.id.button1)).inRoot(RootMatchers.isDialog())
657 private fun cancelDeleteCreditCardButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
658 private fun securedCreditCardsLaterButton() = onView(withId(android.R.id.button2)).inRoot(RootMatchers.isDialog())
660 private fun savedAddress(firstName: String) = mDevice.findObject(UiSelector().textContains(firstName))
661 private fun subRegionOption(subRegion: String) = mDevice.findObject(UiSelector().textContains(subRegion))
662 private fun countryOption(country: String) = mDevice.findObject(UiSelector().textContains(country))
664 private fun expiryMonthOption(expiryMonth: String) = mDevice.findObject(UiSelector().textContains(expiryMonth))
665 private fun expiryYearOption(expiryYear: String) = mDevice.findObject(UiSelector().textContains(expiryYear))