1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.payments;
6 
7 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.DECEMBER;
8 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.FIRST_BILLING_ADDRESS;
9 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.NEXT_YEAR;
10 
11 import androidx.test.filters.MediumTest;
12 
13 import org.junit.Assert;
14 import org.junit.ClassRule;
15 import org.junit.Rule;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 
19 import org.chromium.base.metrics.RecordHistogram;
20 import org.chromium.base.test.util.CommandLineFlags;
21 import org.chromium.base.test.util.Feature;
22 import org.chromium.chrome.R;
23 import org.chromium.chrome.browser.autofill.AutofillTestHelper;
24 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
25 import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
26 import org.chromium.chrome.browser.flags.ChromeSwitches;
27 import org.chromium.chrome.browser.payments.PaymentRequestTestRule.MainActivityStartCallback;
28 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
29 import org.chromium.components.payments.Event;
30 import org.chromium.content_public.browser.test.util.TestThreadUtils;
31 import org.chromium.ui.modaldialog.ModalDialogProperties;
32 import org.chromium.ui.test.util.DisableAnimationsTestRule;
33 
34 import java.util.concurrent.TimeoutException;
35 
36 /**
37  * A payment integration test for a merchant that does not require shipping address.
38  */
39 @RunWith(ChromeJUnit4ClassRunner.class)
40 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
41 public class PaymentRequestNoShippingTest implements MainActivityStartCallback {
42     // Disable animations to reduce flakiness.
43     @ClassRule
44     public static DisableAnimationsTestRule sNoAnimationsRule = new DisableAnimationsTestRule();
45 
46     @Rule
47     public PaymentRequestTestRule mPaymentRequestTestRule =
48             new PaymentRequestTestRule("payment_request_no_shipping_test.html", this);
49 
50     @Override
onMainActivityStarted()51     public void onMainActivityStarted() throws TimeoutException {
52         AutofillTestHelper helper = new AutofillTestHelper();
53         String billingAddressId = helper.setProfile(
54                 new AutofillProfile("", "https://example.com", true, "" /* honorific prefix */,
55                         "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "",
56                         "US", "650-253-0000", "jon.doe@gmail.com", "en-US"));
57         helper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe",
58                 "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card,
59                 billingAddressId, "" /* serverId */));
60     }
61 
62     /** Click [X] to cancel payment. */
63     @Test
64     @MediumTest
65     @Feature({"Payments"})
testCloseDialog()66     public void testCloseDialog() throws TimeoutException {
67         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
68         mPaymentRequestTestRule.clickAndWait(
69                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
70         mPaymentRequestTestRule.expectResultContains(
71                 new String[] {"User closed the Payment Request UI."});
72     }
73 
74     /** Click [EDIT] to expand the dialog, then click [X] to cancel payment. */
75     @Test
76     @MediumTest
77     @Feature({"Payments"})
testEditAndCloseDialog()78     public void testEditAndCloseDialog() throws TimeoutException {
79         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
80         mPaymentRequestTestRule.clickAndWait(
81                 R.id.button_secondary, mPaymentRequestTestRule.getReadyForInput());
82         mPaymentRequestTestRule.clickAndWait(
83                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
84         mPaymentRequestTestRule.expectResultContains(
85                 new String[] {"User closed the Payment Request UI."});
86     }
87 
88     /** Click [EDIT] to expand the dialog, then click [CANCEL] to cancel payment. */
89     @Test
90     @MediumTest
91     @Feature({"Payments"})
testEditAndCancelDialog()92     public void testEditAndCancelDialog() throws TimeoutException {
93         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyForInput());
94         mPaymentRequestTestRule.clickAndWait(
95                 R.id.button_secondary, mPaymentRequestTestRule.getReadyForInput());
96         mPaymentRequestTestRule.clickAndWait(
97                 R.id.button_secondary, mPaymentRequestTestRule.getDismissed());
98         mPaymentRequestTestRule.expectResultContains(
99                 new String[] {"User closed the Payment Request UI."});
100     }
101 
102     /** Click [PAY] and dismiss the card unmask dialog. */
103     @Test
104     @MediumTest
105     @Feature({"Payments"})
testPay()106     public void testPay() throws TimeoutException {
107         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
108         mPaymentRequestTestRule.clickAndWait(
109                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
110         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
111                 R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
112         mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
113                 ModalDialogProperties.ButtonType.POSITIVE, mPaymentRequestTestRule.getDismissed());
114         mPaymentRequestTestRule.expectResultContains(
115                 new String[] {"Jon Doe", "4111111111111111", "12", "2050", "basic-card", "123"});
116     }
117 
118     /** Click [PAY], type in "123" into the CVC dialog, then submit the payment. */
119     @Test
120     @MediumTest
121     @Feature({"Payments"})
testCancelUnmaskAndRetry()122     public void testCancelUnmaskAndRetry() throws TimeoutException {
123         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
124         mPaymentRequestTestRule.clickAndWait(
125                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
126         mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
127                 ModalDialogProperties.ButtonType.NEGATIVE, mPaymentRequestTestRule.getReadyToPay());
128         mPaymentRequestTestRule.clickAndWait(
129                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
130         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
131                 R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
132         mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
133                 ModalDialogProperties.ButtonType.POSITIVE, mPaymentRequestTestRule.getDismissed());
134         mPaymentRequestTestRule.expectResultContains(
135                 new String[] {"Jon Doe", "4111111111111111", "12", "2050", "basic-card", "123"});
136     }
137 
138     /** Attempt to add an invalid credit card number and cancel payment. */
139     @Test
140     @MediumTest
141     @Feature({"Payments"})
testAddInvalidCardNumberAndCancel()142     public void testAddInvalidCardNumberAndCancel() throws TimeoutException {
143         // Attempting to add an invalid card and cancelling out of the flow will result in the user
144         // still being ready to pay with the previously selected credit card.
145         fillNewCardForm("123", "Bob", DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS);
146         mPaymentRequestTestRule.clickInCardEditorAndWait(
147                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getEditorValidationError());
148         mPaymentRequestTestRule.clickInCardEditorAndWait(
149                 R.id.payments_edit_cancel_button, mPaymentRequestTestRule.getReadyToPay());
150         mPaymentRequestTestRule.clickAndWait(
151                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
152         mPaymentRequestTestRule.expectResultContains(
153                 new String[] {"User closed the Payment Request UI."});
154     }
155 
156     /** Attempt to add a credit card with an empty name on card and cancel payment. */
157     @Test
158     @MediumTest
159     @Feature({"Payments"})
testAddEmptyNameOnCardAndCancel()160     public void testAddEmptyNameOnCardAndCancel() throws TimeoutException {
161         fillNewCardForm("5454-5454-5454-5454", "", DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS);
162         mPaymentRequestTestRule.clickInCardEditorAndWait(
163                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getEditorValidationError());
164         mPaymentRequestTestRule.clickInCardEditorAndWait(
165                 R.id.payments_edit_cancel_button, mPaymentRequestTestRule.getReadyForInput());
166         mPaymentRequestTestRule.clickAndWait(
167                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
168         mPaymentRequestTestRule.expectResultContains(
169                 new String[] {"User closed the Payment Request UI."});
170     }
171 
172     /** Save a new card on disk and pay. */
173     @Test
174     @MediumTest
175     @Feature({"Payments"})
testSaveNewCardAndPay()176     public void testSaveNewCardAndPay() throws TimeoutException {
177         fillNewCardForm("5454-5454-5454-5454", "Bob", DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS);
178         mPaymentRequestTestRule.clickInCardEditorAndWait(
179                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToPay());
180         mPaymentRequestTestRule.clickAndWait(
181                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
182         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
183                 R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
184         mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
185                 ModalDialogProperties.ButtonType.POSITIVE, mPaymentRequestTestRule.getDismissed());
186         mPaymentRequestTestRule.expectResultContains(
187                 new String[] {"5454545454545454", "12", "Bob"});
188     }
189 
190     /** Use a temporary credit card to complete payment. */
191     @Test
192     @MediumTest
193     @Feature({"Payments"})
testAddTemporaryCardAndPay()194     public void testAddTemporaryCardAndPay() throws TimeoutException {
195         fillNewCardForm("5454-5454-5454-5454", "Bob", DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS);
196 
197         // Uncheck the "Save this card on this device" checkbox, so the card is temporary.
198         mPaymentRequestTestRule.selectCheckboxAndWait(
199                 R.id.payments_edit_checkbox, false, mPaymentRequestTestRule.getReadyToEdit());
200 
201         mPaymentRequestTestRule.clickInCardEditorAndWait(
202                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToPay());
203         mPaymentRequestTestRule.clickAndWait(
204                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
205         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
206                 R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
207         mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
208                 ModalDialogProperties.ButtonType.POSITIVE, mPaymentRequestTestRule.getDismissed());
209         mPaymentRequestTestRule.expectResultContains(
210                 new String[] {"5454545454545454", "12", "Bob"});
211     }
212 
fillNewCardForm(String cardNumber, String nameOnCard, int month, int year, int billingAddress)213     private void fillNewCardForm(String cardNumber, String nameOnCard, int month, int year,
214             int billingAddress) throws TimeoutException {
215         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
216         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
217                 R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
218         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
219                 R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit());
220         mPaymentRequestTestRule.setTextInCardEditorAndWait(new String[] {cardNumber, nameOnCard},
221                 mPaymentRequestTestRule.getEditorTextUpdate());
222         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
223                 new int[] {month, year, billingAddress},
224                 mPaymentRequestTestRule.getBillingAddressChangeProcessed());
225     }
226 
227     /** Add a new card together with a new billing address and pay. */
228     @Test
229     @MediumTest
230     @Feature({"Payments"})
testSaveNewCardAndNewBillingAddressAndPay()231     public void testSaveNewCardAndNewBillingAddressAndPay() throws TimeoutException {
232         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
233         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
234                 R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
235         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
236                 R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit());
237         mPaymentRequestTestRule.setTextInCardEditorAndWait(
238                 new String[] {"5454 5454 5454 5454", "Bob"},
239                 mPaymentRequestTestRule.getEditorTextUpdate());
240 
241         // Select December of next year for expiration and [Add address] in the billing address
242         // dropdown.
243         int addBillingAddress = 2;
244         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
245                 new int[] {DECEMBER, NEXT_YEAR, addBillingAddress},
246                 mPaymentRequestTestRule.getReadyToEdit());
247         mPaymentRequestTestRule.setTextInEditorAndWait(
248                 new String[] {"Bob", "Google", "1600 Amphitheatre Pkwy", "Mountain View", "CA",
249                         "94043", "650-253-0000"},
250                 mPaymentRequestTestRule.getEditorTextUpdate());
251         mPaymentRequestTestRule.clickInEditorAndWait(
252                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToEdit());
253 
254         mPaymentRequestTestRule.clickInCardEditorAndWait(
255                 R.id.editor_dialog_done_button, mPaymentRequestTestRule.getReadyToPay());
256         mPaymentRequestTestRule.clickAndWait(
257                 R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput());
258         mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait(
259                 R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask());
260         mPaymentRequestTestRule.clickCardUnmaskButtonAndWait(
261                 ModalDialogProperties.ButtonType.POSITIVE, mPaymentRequestTestRule.getDismissed());
262         mPaymentRequestTestRule.expectResultContains(
263                 new String[] {"5454545454545454", "12", "Bob", "Google", "1600 Amphitheatre Pkwy",
264                         "Mountain View", "CA", "94043", "+16502530000"});
265     }
266 
267     /** Quickly pressing on "add card" and then [X] should not crash. */
268     @Test
269     @MediumTest
270     @Feature({"Payments"})
testQuickAddCardAndCloseShouldNotCrash()271     public void testQuickAddCardAndCloseShouldNotCrash() throws TimeoutException {
272         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
273         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
274                 R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
275 
276         // Quickly press on "add card" and then [X].
277         int callCount = mPaymentRequestTestRule.getReadyToEdit().getCallCount();
278         TestThreadUtils.runOnUiThreadBlocking(() -> {
279             mPaymentRequestTestRule.getPaymentRequestUI()
280                     .getPaymentMethodSectionForTest()
281                     .findViewById(R.id.payments_add_option_button)
282                     .performClick();
283             mPaymentRequestTestRule.getPaymentRequestUI()
284                     .getDialogForTest()
285                     .findViewById(R.id.close_button)
286                     .performClick();
287         });
288         mPaymentRequestTestRule.getReadyToEdit().waitForCallback(callCount);
289 
290         mPaymentRequestTestRule.clickInCardEditorAndWait(
291                 R.id.payments_edit_cancel_button, mPaymentRequestTestRule.getReadyToPay());
292         mPaymentRequestTestRule.clickAndWait(
293                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
294         mPaymentRequestTestRule.expectResultContains(
295                 new String[] {"User closed the Payment Request UI."});
296     }
297 
298     /** Quickly pressing on [X] and then "add card" should not crash. */
299     @Test
300     @MediumTest
301     @Feature({"Payments"})
testQuickCloseAndAddCardShouldNotCrash()302     public void testQuickCloseAndAddCardShouldNotCrash() throws TimeoutException {
303         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
304         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
305                 R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
306 
307         // Quickly press on [X] and then "add card."
308         int callCount = mPaymentRequestTestRule.getDismissed().getCallCount();
309         TestThreadUtils.runOnUiThreadBlocking(() -> {
310             mPaymentRequestTestRule.getPaymentRequestUI()
311                     .getDialogForTest()
312                     .findViewById(R.id.close_button)
313                     .performClick();
314             mPaymentRequestTestRule.getPaymentRequestUI()
315                     .getPaymentMethodSectionForTest()
316                     .findViewById(R.id.payments_add_option_button)
317                     .performClick();
318         });
319         mPaymentRequestTestRule.getDismissed().waitForCallback(callCount);
320 
321         mPaymentRequestTestRule.expectResultContains(
322                 new String[] {"User closed the Payment Request UI."});
323     }
324 
325     /** Quickly pressing on "add card" and then "cancel" should not crash. */
326     @Test
327     @MediumTest
328     @Feature({"Payments"})
testQuickAddCardAndCancelShouldNotCrash()329     public void testQuickAddCardAndCancelShouldNotCrash() throws TimeoutException {
330         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
331         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
332                 R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
333 
334         // Quickly press on "add card" and then "cancel."
335         int callCount = mPaymentRequestTestRule.getReadyToEdit().getCallCount();
336         TestThreadUtils.runOnUiThreadBlocking(() -> {
337             mPaymentRequestTestRule.getPaymentRequestUI()
338                     .getPaymentMethodSectionForTest()
339                     .findViewById(R.id.payments_add_option_button)
340                     .performClick();
341             mPaymentRequestTestRule.getPaymentRequestUI()
342                     .getDialogForTest()
343                     .findViewById(R.id.button_secondary)
344                     .performClick();
345         });
346         mPaymentRequestTestRule.getReadyToEdit().waitForCallback(callCount);
347 
348         mPaymentRequestTestRule.clickInCardEditorAndWait(
349                 R.id.payments_edit_cancel_button, mPaymentRequestTestRule.getReadyToPay());
350         mPaymentRequestTestRule.clickAndWait(
351                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
352         mPaymentRequestTestRule.expectResultContains(
353                 new String[] {"User closed the Payment Request UI."});
354     }
355 
356     /** Quickly pressing on "cancel" and then "add card" should not crash. */
357     @Test
358     @MediumTest
359     @Feature({"Payments"})
testQuickCancelAndAddCardShouldNotCrash()360     public void testQuickCancelAndAddCardShouldNotCrash() throws TimeoutException {
361         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
362         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
363                 R.id.payments_section, mPaymentRequestTestRule.getReadyForInput());
364 
365         // Quickly press on "cancel" and then "add card."
366         int callCount = mPaymentRequestTestRule.getDismissed().getCallCount();
367         TestThreadUtils.runOnUiThreadBlocking(() -> {
368             mPaymentRequestTestRule.getPaymentRequestUI()
369                     .getDialogForTest()
370                     .findViewById(R.id.button_secondary)
371                     .performClick();
372             mPaymentRequestTestRule.getPaymentRequestUI()
373                     .getPaymentMethodSectionForTest()
374                     .findViewById(R.id.payments_add_option_button)
375                     .performClick();
376         });
377         mPaymentRequestTestRule.getDismissed().waitForCallback(callCount);
378 
379         mPaymentRequestTestRule.expectResultContains(
380                 new String[] {"User closed the Payment Request UI."});
381     }
382 
383     /**
384      * Quickly dismissing the dialog (via Android's back button, for example) and then pressing on
385      * "pay" should not crash.
386      */
387     @Test
388     @MediumTest
389     @Feature({"Payments"})
testQuickDismissAndPayShouldNotCrash()390     public void testQuickDismissAndPayShouldNotCrash() throws TimeoutException {
391         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
392 
393         // Quickly dismiss and then press on "pay."
394         int callCount = mPaymentRequestTestRule.getDismissed().getCallCount();
395         TestThreadUtils.runOnUiThreadBlocking(() -> {
396             mPaymentRequestTestRule.getPaymentRequestUI().getDialogForTest().onBackPressed();
397             mPaymentRequestTestRule.getPaymentRequestUI()
398                     .getDialogForTest()
399                     .findViewById(R.id.button_primary)
400                     .performClick();
401         });
402         mPaymentRequestTestRule.getDismissed().waitForCallback(callCount);
403 
404         mPaymentRequestTestRule.expectResultContains(
405                 new String[] {"User closed the Payment Request UI."});
406     }
407 
408     /**
409      * Quickly dismissing the dialog (via Android's back button, for example) and then pressing on
410      * [X] should not crash.
411      */
412     @Test
413     @MediumTest
414     @Feature({"Payments"})
testQuickDismissAndCloseShouldNotCrash()415     public void testQuickDismissAndCloseShouldNotCrash() throws TimeoutException {
416         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
417 
418         // Quickly dismiss and then press on [X].
419         int callCount = mPaymentRequestTestRule.getDismissed().getCallCount();
420         TestThreadUtils.runOnUiThreadBlocking(() -> {
421             mPaymentRequestTestRule.getPaymentRequestUI().getDialogForTest().onBackPressed();
422             mPaymentRequestTestRule.getPaymentRequestUI()
423                     .getDialogForTest()
424                     .findViewById(R.id.close_button)
425                     .performClick();
426         });
427         mPaymentRequestTestRule.getDismissed().waitForCallback(callCount);
428 
429         mPaymentRequestTestRule.expectResultContains(
430                 new String[] {"User closed the Payment Request UI."});
431     }
432 
433     /**
434      * Quickly pressing on [X] and then dismissing the dialog (via Android's back button, for
435      * example) should not crash.
436      */
437     @Test
438     @MediumTest
439     @Feature({"Payments"})
testQuickCloseAndDismissShouldNotCrash()440     public void testQuickCloseAndDismissShouldNotCrash() throws TimeoutException {
441         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
442 
443         // Quickly press on [X] and then dismiss.
444         int callCount = mPaymentRequestTestRule.getDismissed().getCallCount();
445         TestThreadUtils.runOnUiThreadBlocking(() -> {
446             mPaymentRequestTestRule.getPaymentRequestUI()
447                     .getDialogForTest()
448                     .findViewById(R.id.close_button)
449                     .performClick();
450             mPaymentRequestTestRule.getPaymentRequestUI().getDialogForTest().onBackPressed();
451         });
452         mPaymentRequestTestRule.getDismissed().waitForCallback(callCount);
453 
454         mPaymentRequestTestRule.expectResultContains(
455                 new String[] {"User closed the Payment Request UI."});
456     }
457 
458     /**
459      * Test that ending a payment request that requires user information except for the payment
460      * results in the appropriate metric being logged in PaymentRequest.Events.
461      * histogram.
462      */
463     @Test
464     @MediumTest
465     @Feature({"Payments"})
testPaymentRequestEventsMetric()466     public void testPaymentRequestEventsMetric() throws TimeoutException {
467         // Start and cancel the Payment Request.
468         mPaymentRequestTestRule.triggerUIAndWait(mPaymentRequestTestRule.getReadyToPay());
469         mPaymentRequestTestRule.clickAndWait(
470                 R.id.close_button, mPaymentRequestTestRule.getDismissed());
471         mPaymentRequestTestRule.expectResultContains(
472                 new String[] {"User closed the Payment Request UI."});
473 
474         int expectedSample = Event.SHOWN | Event.USER_ABORTED | Event.HAD_INITIAL_FORM_OF_PAYMENT
475                 | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS | Event.REQUEST_METHOD_BASIC_CARD
476                 | Event.AVAILABLE_METHOD_BASIC_CARD;
477         Assert.assertEquals(1,
478                 RecordHistogram.getHistogramValueCountForTesting(
479                         "PaymentRequest.Events", expectedSample));
480     }
481 }
482