1 // Copyright (c) 2012 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.
6 #include "base/command_line.h"
7 #include "base/logging.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/histogram_tester.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/autofill/personal_data_manager_factory.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/signin/account_tracker_service_factory.h"
18 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
19 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
20 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
21 #include "chrome/browser/ui/autofill/autofill_dialog_view_tester.h"
22 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
23 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
24 #include "chrome/browser/ui/autofill/mock_address_validator.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_tabstrip.h"
27 #include "chrome/browser/ui/tabs/tab_strip_model.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/pref_names.h"
30 #include "chrome/common/url_constants.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
34 #include "components/autofill/core/browser/autofill_metrics.h"
35 #include "components/autofill/core/browser/autofill_test_utils.h"
36 #include "components/autofill/core/browser/test_personal_data_manager.h"
37 #include "components/autofill/core/browser/validation.h"
38 #include "components/autofill/core/common/autofill_switches.h"
39 #include "components/autofill/core/common/form_data.h"
40 #include "components/autofill/core/common/form_field_data.h"
41 #include "components/signin/core/browser/account_tracker_service.h"
42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/interstitial_page.h"
44 #include "content/public/browser/navigation_details.h"
45 #include "content/public/browser/navigation_entry.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/notification_types.h"
48 #include "content/public/browser/page_navigator.h"
49 #include "content/public/browser/web_contents.h"
50 #include "content/public/browser/web_contents_delegate.h"
51 #include "content/public/common/content_switches.h"
52 #include "content/public/common/referrer.h"
53 #include "content/public/common/url_constants.h"
54 #include "content/public/test/browser_test_utils.h"
55 #include "content/public/test/test_utils.h"
56 #include "google_apis/gaia/google_service_auth_error.h"
57 #include "net/test/spawned_test_server/spawned_test_server.h"
58 #include "testing/gmock/include/gmock/gmock.h"
59 #include "testing/gtest/include/gtest/gtest.h"
60 #include "third_party/WebKit/public/web/WebInputEvent.h"
61 #include "ui/base/page_transition_types.h"
62 #include "ui/base/window_open_disposition.h"
66 #include "base/win/windows_version.h"
67 #elif defined(OS_MACOSX)
68 #include "base/mac/scoped_nsautorelease_pool.h"
69 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
72 using base::ASCIIToUTF16
;
78 using testing::Return
;
81 void MockCallback(AutofillClient::RequestAutocompleteResult
,
82 const base::string16
& message
,
83 const FormStructure
*) {
86 class TestAutofillDialogController
: public AutofillDialogControllerImpl
{
88 TestAutofillDialogController(
89 content::WebContents
* contents
,
90 const FormData
& form_data
,
91 scoped_refptr
<content::MessageLoopRunner
> runner
)
92 : AutofillDialogControllerImpl(contents
,
95 base::Bind(&MockCallback
)),
96 message_loop_runner_(runner
),
97 use_validation_(false),
98 sign_in_user_index_(0U),
99 weak_ptr_factory_(this) {
101 Profile::FromBrowserContext(contents
->GetBrowserContext());
105 AccountTrackerServiceFactory::GetForProfile(profile
),
109 ~TestAutofillDialogController() override
{}
111 GURL
FakeSignInUrl() const {
112 return GURL(chrome::kChromeUIVersionURL
);
115 void ViewClosed() override
{
116 message_loop_runner_
->Quit();
117 AutofillDialogControllerImpl::ViewClosed();
120 base::string16
InputValidityMessage(
121 DialogSection section
,
122 ServerFieldType type
,
123 const base::string16
& value
) override
{
124 if (!use_validation_
)
125 return base::string16();
126 return AutofillDialogControllerImpl::InputValidityMessage(
127 section
, type
, value
);
130 ValidityMessages
InputsAreValid(
131 DialogSection section
,
132 const FieldValueMap
& inputs
) override
{
133 if (!use_validation_
)
134 return ValidityMessages();
135 return AutofillDialogControllerImpl::InputsAreValid(section
, inputs
);
138 // Saving to Chrome is tested in AutofillDialogControllerImpl unit tests.
139 // TODO(estade): test that the view defaults to saving to Chrome.
140 bool ShouldOfferToSaveInChrome() const override
{
144 // Increase visibility for testing.
145 using AutofillDialogControllerImpl::view
;
146 using AutofillDialogControllerImpl::popup_input_type
;
148 MOCK_METHOD0(LoadRiskFingerprintData
, void());
150 std::vector
<DialogNotification
> CurrentNotifications() override
{
151 return notifications_
;
154 void set_notifications(const std::vector
<DialogNotification
>& notifications
) {
155 notifications_
= notifications
;
158 TestPersonalDataManager
* GetTestingManager() {
159 return &test_manager_
;
162 MockAddressValidator
* GetMockValidator() {
163 return &mock_validator_
;
166 using AutofillDialogControllerImpl::IsEditingExistingData
;
167 using AutofillDialogControllerImpl::IsManuallyEditingSection
;
169 void set_use_validation(bool use_validation
) {
170 use_validation_
= use_validation
;
173 base::WeakPtr
<TestAutofillDialogController
> AsWeakPtr() {
174 return weak_ptr_factory_
.GetWeakPtr();
178 PersonalDataManager
* GetManager() const override
{
179 return &const_cast<TestAutofillDialogController
*>(this)->test_manager_
;
182 AddressValidator
* GetValidator() override
{
183 return &mock_validator_
;
187 TestPersonalDataManager test_manager_
;
188 testing::NiceMock
<MockAddressValidator
> mock_validator_
;
189 scoped_refptr
<content::MessageLoopRunner
> message_loop_runner_
;
190 bool use_validation_
;
192 // A list of notifications to show in the notification area of the dialog.
193 // This is used to control what |CurrentNotifications()| returns for testing.
194 std::vector
<DialogNotification
> notifications_
;
196 // The user index that is assigned in IsSignInContinueUrl().
197 size_t sign_in_user_index_
;
199 // Allows generation of WeakPtrs, so controller liveness can be tested.
200 base::WeakPtrFactory
<TestAutofillDialogController
> weak_ptr_factory_
;
202 DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController
);
205 // This is a copy of ui_test_utils::UrlLoadObserver, except it observes
206 // NAV_ENTRY_COMMITTED instead of LOAD_STOP. This is to match the notification
207 // that AutofillDialogControllerImpl observes. Since NAV_ENTRY_COMMITTED comes
208 // before LOAD_STOP, and the controller deletes the web contents after receiving
209 // the former, we will sometimes fail to observe a LOAD_STOP.
210 // TODO(estade): Should the controller observe LOAD_STOP instead?
211 class NavEntryCommittedObserver
: public content::WindowedNotificationObserver
{
213 NavEntryCommittedObserver(const GURL
& url
,
214 const content::NotificationSource
& source
)
215 : WindowedNotificationObserver(content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
219 ~NavEntryCommittedObserver() override
{}
221 // content::NotificationObserver:
222 void Observe(int type
,
223 const content::NotificationSource
& source
,
224 const content::NotificationDetails
& details
) override
{
225 content::LoadCommittedDetails
* load_details
=
226 content::Details
<content::LoadCommittedDetails
>(details
).ptr();
227 if (load_details
->entry
->GetVirtualURL() != url_
)
230 WindowedNotificationObserver::Observe(type
, source
, details
);
236 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver
);
241 class AutofillDialogControllerTest
: public InProcessBrowserTest
{
243 AutofillDialogControllerTest() : controller_(NULL
) {}
244 ~AutofillDialogControllerTest() override
{}
246 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
247 command_line
->AppendSwitch(::switches::kReduceSecurityForTesting
);
250 void SetUpOnMainThread() override
{
251 autofill::test::DisableSystemServices(browser()->profile()->GetPrefs());
252 InitializeController();
256 bool SectionHasField(DialogSection section
, ServerFieldType type
) {
257 const DetailInputs
& fields
=
258 controller()->RequestedFieldsForSection(section
);
259 for (size_t i
= 0; i
< fields
.size(); ++i
) {
260 if (type
== fields
[i
].type
)
266 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
267 // loop. It also drains the NSAutoreleasePool.
268 void CycleRunLoops() {
269 content::RunAllPendingInMessageLoop();
270 #if defined(OS_MACOSX)
271 chrome::testing::NSRunLoopRunAllPending();
272 AutoreleasePool()->Recycle();
276 void InitializeControllerWithoutShowing() {
281 form
.name
= ASCIIToUTF16("TestForm");
284 field
.autocomplete_attribute
= "shipping tel";
285 form
.fields
.push_back(field
);
288 cc
.autocomplete_attribute
= "cc-number";
289 form
.fields
.push_back(cc
);
291 message_loop_runner_
= new content::MessageLoopRunner
;
292 controller_
= new TestAutofillDialogController(
293 GetActiveWebContents(),
295 message_loop_runner_
);
298 void InitializeController() {
299 InitializeControllerWithoutShowing();
301 CycleRunLoops(); // Ensures dialog is fully visible.
304 content::WebContents
* GetActiveWebContents() {
305 return browser()->tab_strip_model()->GetActiveWebContents();
308 content::RenderViewHost
* GetRenderViewHost() {
309 return GetActiveWebContents()->GetRenderViewHost();
312 scoped_ptr
<AutofillDialogViewTester
> GetViewTester() {
313 return AutofillDialogViewTester::For(controller()->view()).Pass();
316 TestAutofillDialogController
* controller() { return controller_
; }
318 void RunMessageLoop() {
319 message_loop_runner_
->Run();
322 // Loads an HTML page in |GetActiveWebContents()| with markup as follows:
323 // <form>|form_inner_html|</form>. After loading, emulates a click event on
324 // the page as requestAutocomplete() must be in response to a user gesture.
325 // Returns the |AutofillDialogControllerImpl| created by this invocation.
326 AutofillDialogControllerImpl
* SetUpHtmlAndInvoke(
327 const std::string
& form_inner_html
) {
328 content::WebContents
* contents
= GetActiveWebContents();
329 ChromeAutofillClient
* client
=
330 ChromeAutofillClient::FromWebContents(contents
);
331 CHECK(!client
->GetDialogControllerForTesting());
333 ui_test_utils::NavigateToURL(
334 browser(), GURL(std::string("data:text/html,") +
338 "<form>" + form_inner_html
+ "</form>"
340 "var invalidEvents = [];"
341 "function recordInvalid(e) {"
342 "if (e.type != 'invalid') throw 'only invalid events allowed';"
343 "invalidEvents.push(e);"
345 "function send(msg) {"
346 "domAutomationController.setAutomationId(0);"
347 "domAutomationController.send(msg);"
349 "document.forms[0].onautocompleteerror = function(e) {"
350 "send('error: ' + e.reason);"
352 "document.forms[0].onautocomplete = function() {"
355 "window.onclick = function() {"
356 "var inputs = document.forms[0].querySelectorAll('input');"
357 "for (var i = 0; i < inputs.length; ++i) {"
358 "inputs[i].oninvalid = recordInvalid;"
360 "document.forms[0].requestAutocomplete();"
363 "function loadIframe() {"
364 " var iframe = document.createElement('iframe');"
365 " iframe.onload = function() {"
366 " send('iframe loaded');"
368 " iframe.src = 'about:blank';"
369 " document.body.appendChild(iframe);"
371 "function getValueForFieldOfType(type) {"
372 " var fields = document.getElementsByTagName('input');"
373 " for (var i = 0; i < fields.length; i++) {"
374 " if (fields[i].autocomplete == type) {"
375 " send(fields[i].value);"
386 AutofillDialogControllerImpl
* controller
=
387 static_cast<AutofillDialogControllerImpl
*>(
388 client
->GetDialogControllerForTesting());
392 // Loads an html page on a provided server, the causes it to launch rAc.
393 // Returns whether rAc succesfully launched.
394 bool RunTestPage(const net::SpawnedTestServer
& server
) {
395 GURL url
= server
.GetURL(
396 "files/request_autocomplete/test_page.html");
397 ui_test_utils::NavigateToURL(browser(), url
);
399 // Pass through the broken SSL interstitial, if any.
400 content::WebContents
* contents
= GetActiveWebContents();
401 content::InterstitialPage
* interstitial_page
=
402 contents
->GetInterstitialPage();
403 if (interstitial_page
) {
404 ui_test_utils::UrlLoadObserver
observer(
406 content::Source
<content::NavigationController
>(
407 &contents
->GetController()));
408 interstitial_page
->Proceed();
414 ChromeAutofillClient
* client
=
415 ChromeAutofillClient::FromWebContents(contents
);
416 AutofillDialogControllerImpl
* controller
=
417 static_cast<AutofillDialogControllerImpl
*>(
418 client
->GetDialogControllerForTesting());
422 void RunTestPageInIframe(const net::SpawnedTestServer
& server
) {
423 InitializeDOMMessageQueue();
424 GURL iframe_url
= server
.GetURL(
425 "files/request_autocomplete/test_page.html");
427 ui_test_utils::NavigateToURL(
428 browser(), GURL(std::string("data:text/html,") +
432 "<iframe style='position: fixed;"
435 "id='racFrame'></iframe>"
437 "function send(msg) {"
438 "domAutomationController.setAutomationId(0);"
439 "domAutomationController.send(msg);"
441 "var racFrame = document.getElementById('racFrame');"
442 "racFrame.onload = function() {"
443 "send('iframe loaded');"
445 "racFrame.src = \"" + iframe_url
.spec() + "\";"
446 "function navigateFrame() {"
447 "racFrame.src = 'about:blank';"
453 ChromeAutofillClient
* client
=
454 ChromeAutofillClient::FromWebContents(GetActiveWebContents());
455 ExpectDomMessage("iframe loaded");
456 EXPECT_FALSE(client
->GetDialogControllerForTesting());
458 EXPECT_TRUE(client
->GetDialogControllerForTesting());
461 // Wait for a message from the DOM automation controller (from JS in the
462 // page). Requires |SetUpHtmlAndInvoke()| be called first.
463 void ExpectDomMessage(const std::string
& expected
) {
465 ASSERT_TRUE(dom_message_queue_
->WaitForMessage(&message
));
466 dom_message_queue_
->ClearQueue();
467 EXPECT_EQ("\"" + expected
+ "\"", message
);
470 void InitiateDialog() {
471 InitializeDOMMessageQueue();
472 // Triggers the onclick handler which invokes requestAutocomplete().
473 content::WebContents
* contents
= GetActiveWebContents();
474 content::SimulateMouseClick(contents
, 0, blink::WebMouseEvent::ButtonLeft
);
475 ExpectDomMessage("clicked");
478 void InitializeDOMMessageQueue() {
479 dom_message_queue_
.reset(new content::DOMMessageQueue
);
482 // Returns the value filled into the first field with autocomplete attribute
483 // equal to |autocomplete_type|, or an empty string if there is no such field.
484 std::string
GetValueForHTMLFieldOfType(const std::string
& autocomplete_type
) {
485 std::string script
= "getValueForFieldOfType('" + autocomplete_type
+ "');";
487 EXPECT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
493 void AddCreditcardToProfile(Profile
* profile
, const CreditCard
& card
) {
494 PersonalDataManagerFactory::GetForProfile(profile
)->AddCreditCard(card
);
498 void AddAutofillProfileToProfile(Profile
* profile
,
499 const AutofillProfile
& autofill_profile
) {
500 PersonalDataManagerFactory::GetForProfile(profile
)->AddProfile(
506 void WaitForWebDB() {
507 content::RunAllPendingInMessageLoop(content::BrowserThread::DB
);
510 TestAutofillDialogController
* controller_
; // Weak reference.
511 scoped_refptr
<content::MessageLoopRunner
> message_loop_runner_
;
512 scoped_ptr
<content::DOMMessageQueue
> dom_message_queue_
;
514 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerTest
);
517 // Submit the form data.
518 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, Submit
) {
519 base::HistogramTester histogram
;
520 AddCreditcardToProfile(controller()->profile(),
521 test::GetVerifiedCreditCard());
522 AddAutofillProfileToProfile(controller()->profile(),
523 test::GetVerifiedProfile());
524 scoped_ptr
<AutofillDialogViewTester
> view
= AutofillDialogViewTester::For(
525 static_cast<TestAutofillDialogController
*>(controller())->view());
526 view
->SetTextContentsOfSuggestionInput(SECTION_CC
, ASCIIToUTF16("123"));
527 GetViewTester()->SubmitForTesting();
530 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 1);
531 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 0);
534 // Cancel out of the dialog.
535 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, Cancel
) {
536 base::HistogramTester histogram
;
537 GetViewTester()->CancelForTesting();
540 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 0);
541 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 1);
542 histogram
.ExpectUniqueSample(
543 "RequestAutocomplete.DismissalState",
544 AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS
, 1);
547 // Take some other action that dismisses the dialog.
548 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, Hide
) {
549 base::HistogramTester histogram
;
550 controller()->Hide();
554 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 0);
555 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 1);
556 histogram
.ExpectUniqueSample(
557 "RequestAutocomplete.DismissalState",
558 AutofillMetrics::DIALOG_CANCELED_NO_INVALID_FIELDS
, 1);
561 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, CancelWithSuggestions
) {
562 base::HistogramTester histogram
;
564 CreditCard
card(test::GetVerifiedCreditCard());
565 controller()->GetTestingManager()->AddTestingCreditCard(&card
);
566 AutofillProfile
profile(test::GetVerifiedProfile());
567 controller()->GetTestingManager()->AddTestingProfile(&profile
);
569 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC
));
570 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING
));
571 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING
));
573 GetViewTester()->CancelForTesting();
576 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 0);
577 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 1);
578 histogram
.ExpectUniqueSample("RequestAutocomplete.DismissalState",
579 AutofillMetrics::DIALOG_CANCELED_NO_EDITS
, 1);
582 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, AcceptWithSuggestions
) {
583 base::HistogramTester histogram
;
584 CreditCard
card(test::GetVerifiedCreditCard());
585 controller()->GetTestingManager()->AddTestingCreditCard(&card
);
586 AutofillProfile
profile(test::GetVerifiedProfile());
587 controller()->GetTestingManager()->AddTestingProfile(&profile
);
589 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_CC
));
590 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_BILLING
));
591 EXPECT_FALSE(controller()->IsManuallyEditingSection(SECTION_SHIPPING
));
593 GetViewTester()->SubmitForTesting();
596 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Submit", 1);
597 histogram
.ExpectTotalCount("RequestAutocomplete.UiDuration.Cancel", 0);
598 histogram
.ExpectUniqueSample(
599 "RequestAutocomplete.DismissalState",
600 AutofillMetrics::DIALOG_ACCEPTED_EXISTING_AUTOFILL_DATA
, 1);
603 // Ensure that Hide() will only destroy the controller object after the
604 // message loop has run. Otherwise, there may be read-after-free issues
605 // during some tests.
606 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, DeferredDestruction
) {
607 base::WeakPtr
<TestAutofillDialogController
> weak_ptr
=
608 controller()->AsWeakPtr();
609 EXPECT_TRUE(weak_ptr
.get());
611 controller()->Hide();
612 EXPECT_TRUE(weak_ptr
.get());
615 EXPECT_FALSE(weak_ptr
.get());
618 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, FillInputFromAutofill
) {
619 AutofillProfile
full_profile(test::GetFullProfile());
620 const base::string16
formatted_phone(ASCIIToUTF16("+1 (310) 555 1234"));
621 full_profile
.SetRawInfo(PHONE_HOME_WHOLE_NUMBER
, formatted_phone
);
622 controller()->GetTestingManager()->AddTestingProfile(&full_profile
);
624 // Dialog is already asking for a new billing address.
625 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_BILLING
));
627 // Select "Add new shipping address...".
628 ui::MenuModel
* model
= controller()->MenuModelForSection(SECTION_SHIPPING
);
629 model
->ActivatedAt(model
->GetItemCount() - 2);
630 ASSERT_TRUE(controller()->IsManuallyEditingSection(SECTION_SHIPPING
));
632 // Enter something in a shipping input.
633 const DetailInputs
& inputs
=
634 controller()->RequestedFieldsForSection(SECTION_SHIPPING
);
635 const ServerFieldType triggering_type
= inputs
[0].type
;
636 base::string16 value
= full_profile
.GetRawInfo(triggering_type
);
637 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
638 view
->SetTextContentsOfInput(triggering_type
,
639 value
.substr(0, value
.size() / 2));
640 view
->ActivateInput(triggering_type
);
642 ASSERT_EQ(triggering_type
, controller()->popup_input_type());
643 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
645 // All inputs should be filled.
646 AutofillProfileWrapper
wrapper(&full_profile
);
647 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
648 EXPECT_EQ(wrapper
.GetInfoForDisplay(AutofillType(inputs
[i
].type
)),
649 view
->GetTextContentsOfInput(inputs
[i
].type
));
651 // Double check the correct formatting is used for the phone number.
652 if (inputs
[i
].type
== PHONE_HOME_WHOLE_NUMBER
)
653 EXPECT_EQ(formatted_phone
, view
->GetTextContentsOfInput(inputs
[i
].type
));
656 // Inputs from the other section (billing) should be left alone.
657 const DetailInputs
& other_section_inputs
=
658 controller()->RequestedFieldsForSection(SECTION_BILLING
);
659 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
660 base::string16 input_value
=
661 view
->GetTextContentsOfInput(other_section_inputs
[i
].type
);
662 // If there's a combobox, the string should be non-empty.
663 if (controller()->ComboboxModelForAutofillType(
664 other_section_inputs
[i
].type
)) {
665 EXPECT_NE(base::string16(), input_value
);
667 EXPECT_EQ(base::string16(), input_value
);
671 // Now simulate some user edits and try again.
672 std::vector
<base::string16
> expectations
;
673 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
674 if (controller()->ComboboxModelForAutofillType(inputs
[i
].type
)) {
675 expectations
.push_back(base::string16());
678 base::string16 users_input
= i
% 2 == 0 ? base::string16()
679 : ASCIIToUTF16("dummy");
680 view
->SetTextContentsOfInput(inputs
[i
].type
, users_input
);
681 // Empty inputs should be filled, others should be left alone.
682 base::string16 expectation
=
683 inputs
[i
].type
== triggering_type
|| users_input
.empty() ?
684 wrapper
.GetInfoForDisplay(AutofillType(inputs
[i
].type
)) :
686 expectations
.push_back(expectation
);
689 view
->SetTextContentsOfInput(triggering_type
,
690 value
.substr(0, value
.size() / 2));
691 view
->ActivateInput(triggering_type
);
692 ASSERT_EQ(triggering_type
, controller()->popup_input_type());
693 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
695 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
696 if (controller()->ComboboxModelForAutofillType(inputs
[i
].type
))
698 EXPECT_EQ(expectations
[i
], view
->GetTextContentsOfInput(inputs
[i
].type
));
701 base::HistogramTester histogram
;
702 view
->SubmitForTesting();
703 histogram
.ExpectUniqueSample(
704 "RequestAutocomplete.DismissalState",
705 AutofillMetrics::DIALOG_ACCEPTED_SAVE_TO_AUTOFILL
, 1);
708 // Tests that changing the value of a CC expiration date combobox works as
709 // expected when Autofill is used to fill text inputs.
711 // Flaky on Win7, WinXP, and Win Aura. http://crbug.com/270314.
713 #define MAYBE_FillComboboxFromAutofill DISABLED_FillComboboxFromAutofill
715 #define MAYBE_FillComboboxFromAutofill FillComboboxFromAutofill
717 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
718 MAYBE_FillComboboxFromAutofill
) {
720 test::SetCreditCardInfo(&card1
, "JJ Smith", "4111111111111111", "12", "2018");
721 controller()->GetTestingManager()->AddTestingCreditCard(&card1
);
723 test::SetCreditCardInfo(&card2
, "B Bird", "3111111111111111", "11", "2017");
724 controller()->GetTestingManager()->AddTestingCreditCard(&card2
);
725 AutofillProfile
full_profile(test::GetFullProfile());
726 controller()->GetTestingManager()->AddTestingProfile(&full_profile
);
728 const DetailInputs
& inputs
=
729 controller()->RequestedFieldsForSection(SECTION_CC
);
730 const ServerFieldType triggering_type
= inputs
[0].type
;
731 base::string16 value
= card1
.GetRawInfo(triggering_type
);
732 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
733 view
->SetTextContentsOfInput(triggering_type
,
734 value
.substr(0, value
.size() / 2));
735 view
->ActivateInput(triggering_type
);
737 ASSERT_EQ(triggering_type
, controller()->popup_input_type());
738 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
740 // All inputs should be filled.
741 AutofillCreditCardWrapper
wrapper1(&card1
);
742 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
743 EXPECT_EQ(wrapper1
.GetInfo(AutofillType(inputs
[i
].type
)),
744 view
->GetTextContentsOfInput(inputs
[i
].type
));
747 // Try again with different data. Only expiration date and the triggering
748 // input should be overwritten.
749 value
= card2
.GetRawInfo(triggering_type
);
750 view
->SetTextContentsOfInput(triggering_type
,
751 value
.substr(0, value
.size() / 2));
752 view
->ActivateInput(triggering_type
);
753 ASSERT_EQ(triggering_type
, controller()->popup_input_type());
754 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
756 AutofillCreditCardWrapper
wrapper2(&card2
);
757 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
758 const ServerFieldType type
= inputs
[i
].type
;
759 if (type
== triggering_type
||
760 type
== CREDIT_CARD_EXP_MONTH
||
761 type
== CREDIT_CARD_EXP_4_DIGIT_YEAR
) {
762 EXPECT_EQ(wrapper2
.GetInfo(AutofillType(type
)),
763 view
->GetTextContentsOfInput(type
));
764 } else if (type
== CREDIT_CARD_VERIFICATION_CODE
) {
765 EXPECT_TRUE(view
->GetTextContentsOfInput(type
).empty());
767 EXPECT_EQ(wrapper1
.GetInfo(AutofillType(type
)),
768 view
->GetTextContentsOfInput(type
));
772 // Now fill from a profile. It should not overwrite any CC info.
773 const DetailInputs
& billing_inputs
=
774 controller()->RequestedFieldsForSection(SECTION_BILLING
);
775 const ServerFieldType billing_triggering_type
= billing_inputs
[0].type
;
776 value
= full_profile
.GetRawInfo(triggering_type
);
777 view
->SetTextContentsOfInput(billing_triggering_type
,
778 value
.substr(0, value
.size() / 2));
779 view
->ActivateInput(billing_triggering_type
);
781 ASSERT_EQ(billing_triggering_type
, controller()->popup_input_type());
782 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
784 for (size_t i
= 0; i
< inputs
.size(); ++i
) {
785 const ServerFieldType type
= inputs
[i
].type
;
786 if (type
== triggering_type
||
787 type
== CREDIT_CARD_EXP_MONTH
||
788 type
== CREDIT_CARD_EXP_4_DIGIT_YEAR
) {
789 EXPECT_EQ(wrapper2
.GetInfo(AutofillType(type
)),
790 view
->GetTextContentsOfInput(type
));
791 } else if (type
== CREDIT_CARD_VERIFICATION_CODE
) {
792 EXPECT_TRUE(view
->GetTextContentsOfInput(type
).empty());
794 EXPECT_EQ(wrapper1
.GetInfo(AutofillType(type
)),
795 view
->GetTextContentsOfInput(type
));
800 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, ShouldShowErrorBubble
) {
801 controller()->set_use_validation(true);
802 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
804 CreditCard
card(test::GetCreditCard());
805 ASSERT_FALSE(card
.IsVerified());
806 controller()->GetTestingManager()->AddTestingCreditCard(&card
);
808 EXPECT_TRUE(controller()->IsManuallyEditingSection(SECTION_CC
));
809 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
810 view
->SetTextContentsOfInput(
812 card
.GetRawInfo(CREDIT_CARD_NUMBER
).substr(0, 1));
814 view
->ActivateInput(CREDIT_CARD_NUMBER
);
815 EXPECT_FALSE(controller()->ShouldShowErrorBubble());
817 controller()->FocusMoved();
818 EXPECT_TRUE(controller()->ShouldShowErrorBubble());
820 base::HistogramTester histogram
;
821 controller()->Hide();
822 histogram
.ExpectUniqueSample(
823 "RequestAutocomplete.DismissalState",
824 AutofillMetrics::DIALOG_CANCELED_WITH_INVALID_FIELDS
, 1);
827 // Ensure that expired cards trigger invalid suggestions.
828 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, ExpiredCard
) {
829 CreditCard
verified_card(test::GetCreditCard());
830 verified_card
.set_origin("Chrome settings");
831 ASSERT_TRUE(verified_card
.IsVerified());
832 controller()->GetTestingManager()->AddTestingCreditCard(&verified_card
);
834 CreditCard
expired_card(test::GetCreditCard());
835 expired_card
.set_origin("Chrome settings");
836 expired_card
.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, ASCIIToUTF16("2007"));
837 ASSERT_TRUE(expired_card
.IsVerified());
839 autofill::IsValidCreditCardExpirationDate(
840 expired_card
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
),
841 expired_card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
),
843 controller()->GetTestingManager()->AddTestingCreditCard(&expired_card
);
845 ui::MenuModel
* model
= controller()->MenuModelForSection(SECTION_CC
);
846 ASSERT_EQ(4, model
->GetItemCount());
848 ASSERT_TRUE(model
->IsItemCheckedAt(0));
849 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC
));
851 model
->ActivatedAt(1);
852 ASSERT_TRUE(model
->IsItemCheckedAt(1));
853 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC
));
856 // Notifications with long message text should not make the dialog bigger.
857 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, LongNotifications
) {
858 const gfx::Size no_notification_size
= GetViewTester()->GetSize();
859 ASSERT_GT(no_notification_size
.width(), 0);
861 std::vector
<DialogNotification
> notifications
;
862 notifications
.push_back(
863 DialogNotification(DialogNotification::DEVELOPER_WARNING
, ASCIIToUTF16(
864 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
865 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
866 "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
867 "aliquip ex ea commodo consequat. Duis aute irure dolor in "
868 "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
869 "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
870 "culpa qui officia deserunt mollit anim id est laborum.")));
871 controller()->set_notifications(notifications
);
872 controller()->view()->UpdateNotificationArea();
874 EXPECT_EQ(no_notification_size
.width(),
875 GetViewTester()->GetSize().width());
878 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, AutocompleteEvent
) {
879 AutofillDialogControllerImpl
* controller
=
880 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
881 ASSERT_TRUE(controller
);
883 AddCreditcardToProfile(controller
->profile(), test::GetVerifiedCreditCard());
884 AddAutofillProfileToProfile(controller
->profile(),
885 test::GetVerifiedProfile());
887 scoped_ptr
<AutofillDialogViewTester
> view
=
888 AutofillDialogViewTester::For(
889 static_cast<TestAutofillDialogController
*>(controller
)->view());
890 view
->SetTextContentsOfSuggestionInput(SECTION_CC
, ASCIIToUTF16("123"));
891 view
->SubmitForTesting();
892 ExpectDomMessage("success");
895 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
896 AutocompleteErrorEventReasonInvalid
) {
897 AutofillDialogControllerImpl
* controller
=
898 SetUpHtmlAndInvoke("<input autocomplete='cc-name' pattern='.*zebra.*'>");
899 ASSERT_TRUE(controller
);
901 const CreditCard
& credit_card
= test::GetVerifiedCreditCard();
903 credit_card
.GetRawInfo(CREDIT_CARD_NAME
).find(ASCIIToUTF16("zebra")) ==
904 base::string16::npos
);
905 AddCreditcardToProfile(controller
->profile(), credit_card
);
906 AddAutofillProfileToProfile(controller
->profile(),
907 test::GetVerifiedProfile());
909 scoped_ptr
<AutofillDialogViewTester
> view
=
910 AutofillDialogViewTester::For(
911 static_cast<TestAutofillDialogController
*>(controller
)->view());
912 view
->SetTextContentsOfSuggestionInput(SECTION_CC
, ASCIIToUTF16("123"));
913 view
->SubmitForTesting();
914 ExpectDomMessage("error: invalid");
916 int invalid_count
= -1;
917 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
918 GetRenderViewHost(), "send(invalidEvents.length);", &invalid_count
));
919 EXPECT_EQ(1, invalid_count
);
921 std::string invalid_type
;
922 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
924 "send(invalidEvents[0].target.autocomplete);",
926 EXPECT_EQ("cc-name", invalid_type
);
929 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
930 AutocompleteErrorEventReasonCancel
) {
931 AutofillDialogControllerImpl
* controller
=
932 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
933 ASSERT_TRUE(controller
);
934 AutofillDialogViewTester::For(
935 static_cast<TestAutofillDialogController
*>(controller
)->view())->
937 ExpectDomMessage("error: cancel");
940 // http://crbug.com/318526
941 #if defined(OS_MACOSX)
942 #define MAYBE_ErrorWithFrameNavigation DISABLED_ErrorWithFrameNavigation
944 #define MAYBE_ErrorWithFrameNavigation ErrorWithFrameNavigation
946 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
947 MAYBE_ErrorWithFrameNavigation
) {
948 AutofillDialogControllerImpl
* controller
=
949 SetUpHtmlAndInvoke("<input autocomplete='cc-name'>");
950 ASSERT_TRUE(controller
);
953 ASSERT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
956 ExpectDomMessage("iframe loaded");
958 AutofillDialogViewTester::For(
959 static_cast<TestAutofillDialogController
*>(controller
)->view())->
961 ExpectDomMessage("error: cancel");
964 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, NoCvcSegfault
) {
965 controller()->set_use_validation(true);
967 CreditCard
credit_card(test::GetVerifiedCreditCard());
968 controller()->GetTestingManager()->AddTestingCreditCard(&credit_card
);
969 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC
));
971 ASSERT_NO_FATAL_FAILURE(GetViewTester()->SubmitForTesting());
974 // Verify that filling a form works correctly, including filling the CVC when
975 // that is requested separately.
976 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
977 FillFormIncludesCVC
) {
978 AutofillDialogControllerImpl
* controller
=
979 SetUpHtmlAndInvoke("<input autocomplete='cc-csc'>");
980 ASSERT_TRUE(controller
);
982 AddCreditcardToProfile(controller
->profile(), test::GetVerifiedCreditCard());
983 AddAutofillProfileToProfile(controller
->profile(),
984 test::GetVerifiedProfile());
986 scoped_ptr
<AutofillDialogViewTester
> view
=
987 AutofillDialogViewTester::For(
988 static_cast<TestAutofillDialogController
*>(controller
)->view());
989 view
->SetTextContentsOfSuggestionInput(SECTION_CC
, ASCIIToUTF16("123"));
990 view
->SubmitForTesting();
991 ExpectDomMessage("success");
992 EXPECT_EQ("123", GetValueForHTMLFieldOfType("cc-csc"));
995 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, AddNewClearsComboboxes
) {
996 // Ensure the input under test is a combobox.
998 controller()->ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH
));
1000 // Set up an expired card.
1002 test::SetCreditCardInfo(&card
, "Roy Demeo", "4111111111111111", "8", "2013");
1003 card
.set_origin("Chrome settings");
1004 ASSERT_TRUE(card
.IsVerified());
1006 // Add the card and check that there's a menu for that section.
1007 controller()->GetTestingManager()->AddTestingCreditCard(&card
);
1008 ASSERT_TRUE(controller()->MenuModelForSection(SECTION_CC
));
1010 // Select the invalid, suggested card from the menu.
1011 controller()->MenuModelForSection(SECTION_CC
)->ActivatedAt(0);
1012 EXPECT_TRUE(controller()->IsEditingExistingData(SECTION_CC
));
1014 // Get the contents of the combobox of the credit card's expiration month.
1015 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
1016 base::string16 cc_exp_month_text
=
1017 view
->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH
);
1019 // Select "New X..." from the suggestion menu to clear the section's inputs.
1020 controller()->MenuModelForSection(SECTION_CC
)->ActivatedAt(1);
1021 EXPECT_FALSE(controller()->IsEditingExistingData(SECTION_CC
));
1023 // Ensure that the credit card expiration month has changed.
1024 EXPECT_NE(cc_exp_month_text
,
1025 view
->GetTextContentsOfInput(CREDIT_CARD_EXP_MONTH
));
1028 // Flaky on Win7 (http://crbug.com/446432)
1030 #define MAYBE_TabOpensToJustRight DISABLED_TabOpensToJustRight
1032 #define MAYBE_TabOpensToJustRight TabOpensToJustRight
1034 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1035 MAYBE_TabOpensToJustRight
) {
1036 ASSERT_TRUE(browser()->is_type_tabbed());
1038 // Tabs should currently be: / rAc() \.
1039 content::WebContents
* dialog_invoker
= controller()->GetWebContents();
1040 EXPECT_EQ(dialog_invoker
, GetActiveWebContents());
1042 TabStripModel
* tab_strip
= browser()->tab_strip_model();
1043 ASSERT_EQ(1, tab_strip
->count());
1044 EXPECT_EQ(0, tab_strip
->GetIndexOfWebContents(dialog_invoker
));
1046 // Open a tab to about:blank in the background at the end of the tab strip.
1047 chrome::AddTabAt(browser(), GURL(), -1, false);
1048 // Tabs should now be: / rAc() \/ blank \.
1049 EXPECT_EQ(2, tab_strip
->count());
1050 EXPECT_EQ(0, tab_strip
->active_index());
1051 EXPECT_EQ(dialog_invoker
, GetActiveWebContents());
1053 content::WebContents
* blank_tab
= tab_strip
->GetWebContentsAt(1);
1055 // Simulate clicking "Manage X...".
1056 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(2);
1057 // Tab should now be: / rAc() \/ manage 1 \/ blank \.
1058 EXPECT_EQ(3, tab_strip
->count());
1059 int dialog_index
= tab_strip
->GetIndexOfWebContents(dialog_invoker
);
1060 EXPECT_EQ(0, dialog_index
);
1061 EXPECT_EQ(1, tab_strip
->active_index());
1062 EXPECT_EQ(2, tab_strip
->GetIndexOfWebContents(blank_tab
));
1064 content::WebContents
* first_manage_tab
= tab_strip
->GetWebContentsAt(1);
1066 // Re-activate the dialog's tab (like a user would have to).
1067 tab_strip
->ActivateTabAt(dialog_index
, true);
1068 EXPECT_EQ(dialog_invoker
, GetActiveWebContents());
1070 // Simulate clicking "Manage X...".
1071 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(2);
1072 // Tabs should now be: / rAc() \/ manage 2 \/ manage 1 \/ blank \.
1073 EXPECT_EQ(4, tab_strip
->count());
1074 EXPECT_EQ(0, tab_strip
->GetIndexOfWebContents(dialog_invoker
));
1075 EXPECT_EQ(1, tab_strip
->active_index());
1076 EXPECT_EQ(2, tab_strip
->GetIndexOfWebContents(first_manage_tab
));
1077 EXPECT_EQ(3, tab_strip
->GetIndexOfWebContents(blank_tab
));
1080 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1081 DoesWorkOnHttpWithFlag
) {
1082 net::SpawnedTestServer
http_server(
1083 net::SpawnedTestServer::TYPE_HTTP
,
1084 net::SpawnedTestServer::kLocalhost
,
1085 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1086 ASSERT_TRUE(http_server
.Start());
1087 EXPECT_TRUE(RunTestPage(http_server
));
1090 // Like the parent test, but doesn't add the --reduce-security-for-testing flag.
1091 class AutofillDialogControllerSecurityTest
:
1092 public AutofillDialogControllerTest
{
1094 AutofillDialogControllerSecurityTest() {}
1095 ~AutofillDialogControllerSecurityTest() override
{}
1097 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
1098 CHECK(!command_line
->HasSwitch(::switches::kReduceSecurityForTesting
));
1101 typedef net::BaseTestServer::SSLOptions SSLOptions
;
1104 DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerSecurityTest
);
1107 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest
,
1109 net::SpawnedTestServer
http_server(
1110 net::SpawnedTestServer::TYPE_HTTP
,
1111 net::SpawnedTestServer::kLocalhost
,
1112 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1113 ASSERT_TRUE(http_server
.Start());
1114 EXPECT_FALSE(RunTestPage(http_server
));
1117 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest
,
1118 DoesWorkOnHttpWithFlags
) {
1119 net::SpawnedTestServer
https_server(
1120 net::SpawnedTestServer::TYPE_HTTPS
,
1121 SSLOptions(SSLOptions::CERT_OK
),
1122 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1123 ASSERT_TRUE(https_server
.Start());
1124 EXPECT_TRUE(RunTestPage(https_server
));
1127 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerSecurityTest
,
1128 DISABLED_DoesntWorkOnBrokenHttps
) {
1129 net::SpawnedTestServer
https_server(
1130 net::SpawnedTestServer::TYPE_HTTPS
,
1131 SSLOptions(SSLOptions::CERT_EXPIRED
),
1132 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1133 ASSERT_TRUE(https_server
.Start());
1134 EXPECT_FALSE(RunTestPage(https_server
));
1137 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1138 CountryChangeRebuildsSection
) {
1139 EXPECT_FALSE(SectionHasField(SECTION_BILLING
, ADDRESS_BILLING_SORTING_CODE
));
1140 EXPECT_FALSE(SectionHasField(SECTION_SHIPPING
, ADDRESS_HOME_SORTING_CODE
));
1142 // Select "Add new shipping address...".
1143 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(1);
1145 // Add some valid user input that should be preserved when country changes.
1146 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
1147 view
->SetTextContentsOfInput(NAME_FULL
, ASCIIToUTF16("B. Loblaw"));
1149 // Change both sections' countries.
1150 view
->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
, ASCIIToUTF16("France"));
1151 view
->ActivateInput(ADDRESS_BILLING_COUNTRY
);
1152 view
->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("Belarus"));
1153 view
->ActivateInput(ADDRESS_HOME_COUNTRY
);
1155 // Verify the name is still there.
1156 EXPECT_EQ(ASCIIToUTF16("B. Loblaw"), view
->GetTextContentsOfInput(NAME_FULL
));
1158 EXPECT_TRUE(SectionHasField(SECTION_BILLING
, ADDRESS_BILLING_SORTING_CODE
));
1159 EXPECT_TRUE(SectionHasField(SECTION_SHIPPING
, ADDRESS_HOME_SORTING_CODE
));
1162 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, AddNewResetsCountry
) {
1163 AutofillProfile
verified_profile(test::GetVerifiedProfile());
1164 controller()->GetTestingManager()->AddTestingProfile(&verified_profile
);
1166 // Select "Add new billing/shipping address...".
1167 controller()->MenuModelForSection(SECTION_BILLING
)->ActivatedAt(1);
1168 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(2);
1170 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
1171 ASSERT_EQ(ASCIIToUTF16("United States"),
1172 view
->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
));
1173 ASSERT_EQ(ASCIIToUTF16("United States"),
1174 view
->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY
));
1176 // Switch both billing and shipping countries.
1177 view
->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
, ASCIIToUTF16("Brazil"));
1178 view
->ActivateInput(ADDRESS_BILLING_COUNTRY
);
1179 view
->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("France"));
1180 view
->ActivateInput(ADDRESS_HOME_COUNTRY
);
1182 // Select "Add new billing/shipping address...".
1183 controller()->MenuModelForSection(SECTION_BILLING
)->ActivatedAt(1);
1184 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(2);
1186 EXPECT_EQ(ASCIIToUTF16("United States"),
1187 view
->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
));
1188 EXPECT_EQ(ASCIIToUTF16("United States"),
1189 view
->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY
));
1192 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1193 FillingFormRebuildsInputs
) {
1194 AutofillProfile
full_profile(test::GetFullProfile());
1195 full_profile
.SetRawInfo(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("DE"));
1196 controller()->GetTestingManager()->AddTestingProfile(&full_profile
);
1198 // Select "Add new shipping address...".
1199 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(1);
1201 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
1202 ASSERT_EQ(ASCIIToUTF16("United States"),
1203 view
->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
));
1204 ASSERT_EQ(ASCIIToUTF16("United States"),
1205 view
->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY
));
1207 const ServerFieldType input_type
= EMAIL_ADDRESS
;
1208 base::string16 name
= full_profile
.GetRawInfo(input_type
);
1209 view
->SetTextContentsOfInput(input_type
, name
.substr(0, name
.size() / 2));
1210 view
->ActivateInput(input_type
);
1211 ASSERT_EQ(input_type
, controller()->popup_input_type());
1212 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
1214 EXPECT_EQ(ASCIIToUTF16("Germany"),
1215 view
->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
));
1216 EXPECT_EQ(ASCIIToUTF16("United States"),
1217 view
->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY
));
1220 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1221 FillingFormPreservesChangedCountry
) {
1222 AutofillProfile
full_profile(test::GetFullProfile());
1223 full_profile
.SetRawInfo(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("DE"));
1224 controller()->GetTestingManager()->AddTestingProfile(&full_profile
);
1226 // Select "Add new shipping address...".
1227 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(1);
1229 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
1230 view
->SetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
, ASCIIToUTF16("France"));
1231 view
->ActivateInput(ADDRESS_BILLING_COUNTRY
);
1232 view
->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("Belarus"));
1233 view
->ActivateInput(ADDRESS_HOME_COUNTRY
);
1235 base::string16 name
= full_profile
.GetRawInfo(NAME_FULL
);
1236 view
->SetTextContentsOfInput(NAME_FULL
, name
.substr(0, name
.size() / 2));
1237 view
->ActivateInput(NAME_FULL
);
1238 ASSERT_EQ(NAME_FULL
, controller()->popup_input_type());
1239 controller()->DidAcceptSuggestion(base::string16(), 0, 1);
1241 EXPECT_EQ(ASCIIToUTF16("France"),
1242 view
->GetTextContentsOfInput(ADDRESS_BILLING_COUNTRY
));
1243 EXPECT_EQ(ASCIIToUTF16("Belarus"),
1244 view
->GetTextContentsOfInput(ADDRESS_HOME_COUNTRY
));
1247 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, RulesLoaded
) {
1248 // Select "Add new shipping address...".
1249 controller()->MenuModelForSection(SECTION_SHIPPING
)->ActivatedAt(1);
1250 controller()->set_use_validation(true);
1252 EXPECT_CALL(*controller()->GetMockValidator(),
1253 ValidateAddress(CountryCodeMatcher("DE"), _
, _
)).Times(2).
1254 WillOnce(Return(AddressValidator::RULES_NOT_READY
));
1256 // Validation should occur on country change and see the rules haven't loaded.
1257 scoped_ptr
<AutofillDialogViewTester
> view
= GetViewTester();
1258 view
->SetTextContentsOfInput(ADDRESS_HOME_ZIP
, ASCIIToUTF16("123"));
1259 view
->SetTextContentsOfInput(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("Germany"));
1260 view
->ActivateInput(ADDRESS_HOME_COUNTRY
);
1262 // Different country loaded, validation should not occur.
1263 controller()->OnAddressValidationRulesLoaded("FR", true);
1265 // Relevant country loaded, validation should occur.
1266 controller()->OnAddressValidationRulesLoaded("DE", true);
1268 // Relevant country loaded but revalidation already happened, no further
1269 // validation should occur.
1270 controller()->OnAddressValidationRulesLoaded("DE", false);
1272 // Cancelling the dialog causes additional validation to see if the user
1273 // cancelled with invalid fields, so verify and clear here.
1274 testing::Mock::VerifyAndClearExpectations(controller()->GetMockValidator());
1277 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1278 TransactionAmount
) {
1280 "<input type='number' step='0.01'"
1281 " autocomplete='transaction-amount' value='24'>"
1282 "<input autocomplete='transaction-currency' value='USD'>"
1283 "<input autocomplete='cc-csc'>");
1284 AutofillDialogControllerImpl
* controller
= SetUpHtmlAndInvoke(html
);
1285 ASSERT_TRUE(controller
);
1287 EXPECT_EQ(ASCIIToUTF16("24"), controller
->transaction_amount_
);
1288 EXPECT_EQ(ASCIIToUTF16("USD"), controller
->transaction_currency_
);
1291 // Same as above, plus readonly attribute.
1292 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
,
1293 TransactionAmountReadonly
) {
1295 "<input type='number' step='0.01'"
1296 " autocomplete='transaction-amount' value='24' readonly>"
1297 "<input autocomplete='transaction-currency' value='USD' readonly>"
1298 "<input autocomplete='cc-csc'>");
1299 AutofillDialogControllerImpl
* controller
= SetUpHtmlAndInvoke(html
);
1300 ASSERT_TRUE(controller
);
1302 EXPECT_EQ(ASCIIToUTF16("24"), controller
->transaction_amount_
);
1303 EXPECT_EQ(ASCIIToUTF16("USD"), controller
->transaction_currency_
);
1306 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, HideOnNavigate
) {
1307 base::WeakPtr
<TestAutofillDialogController
> weak_ptr
=
1308 controller()->AsWeakPtr();
1309 EXPECT_TRUE(weak_ptr
.get());
1311 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
1312 EXPECT_FALSE(weak_ptr
.get());
1315 // Tests that the rAc dialog hides when the main frame is navigated, even if
1316 // it was invoked from a child frame.
1317 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, HideOnNavigateMainFrame
) {
1318 net::SpawnedTestServer
http_server(
1319 net::SpawnedTestServer::TYPE_HTTP
,
1320 net::SpawnedTestServer::kLocalhost
,
1321 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1322 ASSERT_TRUE(http_server
.Start());
1323 RunTestPageInIframe(http_server
);
1325 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
1326 ChromeAutofillClient
* client
=
1327 ChromeAutofillClient::FromWebContents(GetActiveWebContents());
1328 EXPECT_FALSE(client
->GetDialogControllerForTesting());
1331 // Tests that the rAc dialog hides when the iframe it's in is navigated.
1332 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest
, HideOnNavigateIframe
) {
1333 net::SpawnedTestServer
http_server(
1334 net::SpawnedTestServer::TYPE_HTTP
,
1335 net::SpawnedTestServer::kLocalhost
,
1336 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1337 ASSERT_TRUE(http_server
.Start());
1338 RunTestPageInIframe(http_server
);
1341 ASSERT_TRUE(content::ExecuteScriptAndExtractString(GetRenderViewHost(),
1344 ExpectDomMessage("iframe loaded");
1345 ChromeAutofillClient
* client
=
1346 ChromeAutofillClient::FromWebContents(GetActiveWebContents());
1347 EXPECT_FALSE(client
->GetDialogControllerForTesting());
1350 } // namespace autofill