1// Copyright (c) 2013 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#include <string> 6 7#include "base/basictypes.h" 8#include "base/command_line.h" 9#include "base/file_util.h" 10#include "base/memory/ref_counted.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/rand_util.h" 13#include "base/strings/string16.h" 14#include "base/strings/string_number_conversions.h" 15#include "base/strings/string_split.h" 16#include "base/strings/utf_string_conversions.h" 17#include "base/time/time.h" 18#include "chrome/browser/autofill/personal_data_manager_factory.h" 19#include "chrome/browser/chrome_notification_types.h" 20#include "chrome/browser/infobars/confirm_infobar_delegate.h" 21#include "chrome/browser/infobars/infobar.h" 22#include "chrome/browser/infobars/infobar_service.h" 23#include "chrome/browser/profiles/profile.h" 24#include "chrome/browser/translate/translate_infobar_delegate.h" 25#include "chrome/browser/translate/translate_manager.h" 26#include "chrome/browser/ui/browser.h" 27#include "chrome/browser/ui/browser_window.h" 28#include "chrome/browser/ui/tabs/tab_strip_model.h" 29#include "chrome/common/render_messages.h" 30#include "chrome/test/base/in_process_browser_test.h" 31#include "chrome/test/base/test_switches.h" 32#include "chrome/test/base/ui_test_utils.h" 33#include "components/autofill/content/browser/autofill_driver_impl.h" 34#include "components/autofill/core/browser/autofill_manager.h" 35#include "components/autofill/core/browser/autofill_manager_test_delegate.h" 36#include "components/autofill/core/browser/autofill_profile.h" 37#include "components/autofill/core/browser/autofill_test_utils.h" 38#include "components/autofill/core/browser/personal_data_manager.h" 39#include "components/autofill/core/browser/personal_data_manager_observer.h" 40#include "components/autofill/core/browser/validation.h" 41#include "content/public/browser/navigation_controller.h" 42#include "content/public/browser/notification_observer.h" 43#include "content/public/browser/notification_registrar.h" 44#include "content/public/browser/notification_service.h" 45#include "content/public/browser/render_view_host.h" 46#include "content/public/browser/render_widget_host.h" 47#include "content/public/browser/web_contents.h" 48#include "content/public/test/browser_test_utils.h" 49#include "content/public/test/test_renderer_host.h" 50#include "content/public/test/test_utils.h" 51#include "net/url_request/test_url_fetcher_factory.h" 52#include "testing/gmock/include/gmock/gmock.h" 53#include "testing/gtest/include/gtest/gtest.h" 54#include "ui/events/keycodes/keyboard_codes.h" 55 56 57namespace autofill { 58 59static const char* kDataURIPrefix = "data:text/html;charset=utf-8,"; 60static const char* kTestFormString = 61 "<form action=\"http://www.example.com/\" method=\"POST\">" 62 "<label for=\"firstname\">First name:</label>" 63 " <input type=\"text\" id=\"firstname\"" 64 " onFocus=\"domAutomationController.send(true)\"><br>" 65 "<label for=\"lastname\">Last name:</label>" 66 " <input type=\"text\" id=\"lastname\"><br>" 67 "<label for=\"address1\">Address line 1:</label>" 68 " <input type=\"text\" id=\"address1\"><br>" 69 "<label for=\"address2\">Address line 2:</label>" 70 " <input type=\"text\" id=\"address2\"><br>" 71 "<label for=\"city\">City:</label>" 72 " <input type=\"text\" id=\"city\"><br>" 73 "<label for=\"state\">State:</label>" 74 " <select id=\"state\">" 75 " <option value=\"\" selected=\"yes\">--</option>" 76 " <option value=\"CA\">California</option>" 77 " <option value=\"TX\">Texas</option>" 78 " </select><br>" 79 "<label for=\"zip\">ZIP code:</label>" 80 " <input type=\"text\" id=\"zip\"><br>" 81 "<label for=\"country\">Country:</label>" 82 " <select id=\"country\">" 83 " <option value=\"\" selected=\"yes\">--</option>" 84 " <option value=\"CA\">Canada</option>" 85 " <option value=\"US\">United States</option>" 86 " </select><br>" 87 "<label for=\"phone\">Phone number:</label>" 88 " <input type=\"text\" id=\"phone\"><br>" 89 "</form>"; 90 91 92// AutofillManagerTestDelegateImpl -------------------------------------------- 93 94class AutofillManagerTestDelegateImpl 95 : public autofill::AutofillManagerTestDelegate { 96 public: 97 AutofillManagerTestDelegateImpl() {} 98 virtual ~AutofillManagerTestDelegateImpl() {} 99 100 // autofill::AutofillManagerTestDelegate: 101 virtual void DidPreviewFormData() OVERRIDE { 102 loop_runner_->Quit(); 103 } 104 105 virtual void DidFillFormData() OVERRIDE { 106 loop_runner_->Quit(); 107 } 108 109 virtual void DidShowSuggestions() OVERRIDE { 110 loop_runner_->Quit(); 111 } 112 113 void Reset() { 114 loop_runner_ = new content::MessageLoopRunner(); 115 } 116 117 void Wait() { 118 loop_runner_->Run(); 119 } 120 121 private: 122 scoped_refptr<content::MessageLoopRunner> loop_runner_; 123 124 DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl); 125}; 126 127 128// WindowedPersonalDataManagerObserver ---------------------------------------- 129 130class WindowedPersonalDataManagerObserver 131 : public PersonalDataManagerObserver, 132 public content::NotificationObserver { 133 public: 134 explicit WindowedPersonalDataManagerObserver(Browser* browser) 135 : alerted_(false), 136 has_run_message_loop_(false), 137 browser_(browser), 138 infobar_service_(NULL) { 139 PersonalDataManagerFactory::GetForProfile(browser_->profile())-> 140 AddObserver(this); 141 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, 142 content::NotificationService::AllSources()); 143 } 144 145 virtual ~WindowedPersonalDataManagerObserver() { 146 if (infobar_service_) { 147 while (infobar_service_->infobar_count() > 0) { 148 infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0)); 149 } 150 } 151 } 152 153 // PersonalDataManagerObserver: 154 virtual void OnPersonalDataChanged() OVERRIDE { 155 if (has_run_message_loop_) { 156 base::MessageLoopForUI::current()->Quit(); 157 has_run_message_loop_ = false; 158 } 159 alerted_ = true; 160 } 161 162 virtual void OnInsufficientFormData() OVERRIDE { 163 OnPersonalDataChanged(); 164 } 165 166 // content::NotificationObserver: 167 virtual void Observe(int type, 168 const content::NotificationSource& source, 169 const content::NotificationDetails& details) OVERRIDE { 170 infobar_service_ = InfoBarService::FromWebContents( 171 browser_->tab_strip_model()->GetActiveWebContents()); 172 infobar_service_->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate()-> 173 Accept(); 174 } 175 176 void Wait() { 177 if (!alerted_) { 178 has_run_message_loop_ = true; 179 content::RunMessageLoop(); 180 } 181 PersonalDataManagerFactory::GetForProfile(browser_->profile())-> 182 RemoveObserver(this); 183 } 184 185 private: 186 bool alerted_; 187 bool has_run_message_loop_; 188 Browser* browser_; 189 content::NotificationRegistrar registrar_; 190 InfoBarService* infobar_service_; 191 192 DISALLOW_COPY_AND_ASSIGN(WindowedPersonalDataManagerObserver); 193}; 194 195// AutofillInteractiveTest ---------------------------------------------------- 196 197class AutofillInteractiveTest : public InProcessBrowserTest { 198 protected: 199 AutofillInteractiveTest() : 200 key_press_event_sink_( 201 base::Bind(&AutofillInteractiveTest::HandleKeyPressEvent, 202 base::Unretained(this))) {} 203 virtual ~AutofillInteractiveTest() {} 204 205 // InProcessBrowserTest: 206 virtual void SetUpOnMainThread() OVERRIDE { 207 // Don't want Keychain coming up on Mac. 208 test::DisableSystemServices(browser()->profile()); 209 210 // Inject the test delegate into the AutofillManager. 211 content::WebContents* web_contents = GetWebContents(); 212 AutofillDriverImpl* autofill_driver = 213 AutofillDriverImpl::FromWebContents(web_contents); 214 AutofillManager* autofill_manager = autofill_driver->autofill_manager(); 215 autofill_manager->SetTestDelegate(&test_delegate_); 216 } 217 218 virtual void CleanUpOnMainThread() OVERRIDE { 219 // Make sure to close any showing popups prior to tearing down the UI. 220 content::WebContents* web_contents = GetWebContents(); 221 AutofillManager* autofill_manager = 222 AutofillDriverImpl::FromWebContents(web_contents)->autofill_manager(); 223 autofill_manager->delegate()->HideAutofillPopup(); 224 } 225 226 PersonalDataManager* GetPersonalDataManager() { 227 return PersonalDataManagerFactory::GetForProfile(browser()->profile()); 228 } 229 230 content::WebContents* GetWebContents() { 231 return browser()->tab_strip_model()->GetActiveWebContents(); 232 } 233 234 content::RenderViewHost* GetRenderViewHost() { 235 return GetWebContents()->GetRenderViewHost(); 236 } 237 238 void CreateTestProfile() { 239 AutofillProfile profile; 240 test::SetProfileInfo( 241 &profile, "Milton", "C.", "Waddams", 242 "red.swingline@initech.com", "Initech", "4120 Freidrich Lane", 243 "Basement", "Austin", "Texas", "78744", "US", "5125551234"); 244 245 WindowedPersonalDataManagerObserver observer(browser()); 246 GetPersonalDataManager()->AddProfile(profile); 247 248 // AddProfile is asynchronous. Wait for it to finish before continuing the 249 // tests. 250 observer.Wait(); 251 } 252 253 void SetProfiles(std::vector<AutofillProfile>* profiles) { 254 WindowedPersonalDataManagerObserver observer(browser()); 255 GetPersonalDataManager()->SetProfiles(profiles); 256 observer.Wait(); 257 } 258 259 void SetProfile(const AutofillProfile& profile) { 260 std::vector<AutofillProfile> profiles; 261 profiles.push_back(profile); 262 SetProfiles(&profiles); 263 } 264 265 // Populates a webpage form using autofill data and keypress events. 266 // This function focuses the specified input field in the form, and then 267 // sends keypress events to the tab to cause the form to be populated. 268 void PopulateForm(const std::string& field_id) { 269 std::string js("document.getElementById('" + field_id + "').focus();"); 270 ASSERT_TRUE(content::ExecuteScript(GetRenderViewHost(), js)); 271 272 SendKeyToPageAndWait(ui::VKEY_DOWN); 273 SendKeyToPopupAndWait(ui::VKEY_DOWN); 274 SendKeyToPopupAndWait(ui::VKEY_RETURN); 275 } 276 277 void ExpectFieldValue(const std::string& field_name, 278 const std::string& expected_value) { 279 std::string value; 280 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 281 GetWebContents(), 282 "window.domAutomationController.send(" 283 " document.getElementById('" + field_name + "').value);", 284 &value)); 285 EXPECT_EQ(expected_value, value); 286 } 287 288 void SimulateURLFetch(bool success) { 289 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 290 ASSERT_TRUE(fetcher); 291 net::URLRequestStatus status; 292 status.set_status(success ? net::URLRequestStatus::SUCCESS : 293 net::URLRequestStatus::FAILED); 294 295 std::string script = " var google = {};" 296 "google.translate = (function() {" 297 " return {" 298 " TranslateService: function() {" 299 " return {" 300 " isAvailable : function() {" 301 " return true;" 302 " }," 303 " restore : function() {" 304 " return;" 305 " }," 306 " getDetectedLanguage : function() {" 307 " return \"ja\";" 308 " }," 309 " translatePage : function(originalLang, targetLang," 310 " onTranslateProgress) {" 311 " document.getElementsByTagName(\"body\")[0].innerHTML = '" + 312 std::string(kTestFormString) + 313 " ';" 314 " onTranslateProgress(100, true, false);" 315 " }" 316 " };" 317 " }" 318 " };" 319 "})();" 320 "cr.googleTranslate.onTranslateElementLoad();"; 321 322 fetcher->set_url(fetcher->GetOriginalURL()); 323 fetcher->set_status(status); 324 fetcher->set_response_code(success ? 200 : 500); 325 fetcher->SetResponseString(script); 326 fetcher->delegate()->OnURLFetchComplete(fetcher); 327 } 328 329 void FocusFirstNameField() { 330 bool result = false; 331 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 332 GetRenderViewHost(), 333 "if (document.readyState === 'complete')" 334 " document.getElementById('firstname').focus();" 335 "else" 336 " domAutomationController.send(false);", 337 &result)); 338 ASSERT_TRUE(result); 339 } 340 341 void ExpectFilledTestForm() { 342 ExpectFieldValue("firstname", "Milton"); 343 ExpectFieldValue("lastname", "Waddams"); 344 ExpectFieldValue("address1", "4120 Freidrich Lane"); 345 ExpectFieldValue("address2", "Basement"); 346 ExpectFieldValue("city", "Austin"); 347 ExpectFieldValue("state", "TX"); 348 ExpectFieldValue("zip", "78744"); 349 ExpectFieldValue("country", "US"); 350 ExpectFieldValue("phone", "5125551234"); 351 } 352 353 void SendKeyToPageAndWait(ui::KeyboardCode key) { 354 test_delegate_.Reset(); 355 content::SimulateKeyPress( 356 GetWebContents(), key, false, false, false, false); 357 test_delegate_.Wait(); 358 } 359 360 bool HandleKeyPressEvent(const content::NativeWebKeyboardEvent& event) { 361 return true; 362 } 363 364 void SendKeyToPopupAndWait(ui::KeyboardCode key) { 365 // Route popup-targeted key presses via the render view host. 366 content::NativeWebKeyboardEvent event; 367 event.windowsKeyCode = key; 368 event.type = blink::WebKeyboardEvent::RawKeyDown; 369 test_delegate_.Reset(); 370 // Install the key press event sink to ensure that any events that are not 371 // handled by the installed callbacks do not end up crashing the test. 372 GetRenderViewHost()->AddKeyPressEventCallback(key_press_event_sink_); 373 GetRenderViewHost()->ForwardKeyboardEvent(event); 374 test_delegate_.Wait(); 375 GetRenderViewHost()->RemoveKeyPressEventCallback(key_press_event_sink_); 376 } 377 378 void TryBasicFormFill() { 379 FocusFirstNameField(); 380 381 // Start filling the first name field with "M" and wait for the popup to be 382 // shown. 383 SendKeyToPageAndWait(ui::VKEY_M); 384 385 // Press the down arrow to select the suggestion and preview the autofilled 386 // form. 387 SendKeyToPopupAndWait(ui::VKEY_DOWN); 388 389 // The previewed values should not be accessible to JavaScript. 390 ExpectFieldValue("firstname", "M"); 391 ExpectFieldValue("lastname", std::string()); 392 ExpectFieldValue("address1", std::string()); 393 ExpectFieldValue("address2", std::string()); 394 ExpectFieldValue("city", std::string()); 395 ExpectFieldValue("state", std::string()); 396 ExpectFieldValue("zip", std::string()); 397 ExpectFieldValue("country", std::string()); 398 ExpectFieldValue("phone", std::string()); 399 // TODO(isherman): It would be nice to test that the previewed values are 400 // displayed: http://crbug.com/57220 401 402 // Press Enter to accept the autofill suggestions. 403 SendKeyToPopupAndWait(ui::VKEY_RETURN); 404 405 // The form should be filled. 406 ExpectFilledTestForm(); 407 } 408 409 private: 410 AutofillManagerTestDelegateImpl test_delegate_; 411 412 net::TestURLFetcherFactory url_fetcher_factory_; 413 414 // KeyPressEventCallback that serves as a sink to ensure that every key press 415 // event the tests create and have the WebContents forward is handled by some 416 // key press event callback. It is necessary to have this sinkbecause if no 417 // key press event callback handles the event (at least on Mac), a DCHECK 418 // ends up going off that the |event| doesn't have an |os_event| associated 419 // with it. 420 content::RenderWidgetHost::KeyPressEventCallback key_press_event_sink_; 421 422 DISALLOW_COPY_AND_ASSIGN(AutofillInteractiveTest); 423}; 424 425// Test that basic form fill is working. 426IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, BasicFormFill) { 427 CreateTestProfile(); 428 429 // Load the test page. 430 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 431 GURL(std::string(kDataURIPrefix) + kTestFormString))); 432 433 // Invoke Autofill. 434 TryBasicFormFill(); 435} 436 437// Test that form filling can be initiated by pressing the down arrow. 438IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, AutofillViaDownArrow) { 439 CreateTestProfile(); 440 441 // Load the test page. 442 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 443 GURL(std::string(kDataURIPrefix) + kTestFormString))); 444 445 // Focus a fillable field. 446 FocusFirstNameField(); 447 448 // Press the down arrow to initiate Autofill and wait for the popup to be 449 // shown. 450 SendKeyToPageAndWait(ui::VKEY_DOWN); 451 452 // Press the down arrow to select the suggestion and preview the autofilled 453 // form. 454 SendKeyToPopupAndWait(ui::VKEY_DOWN); 455 456 // Press Enter to accept the autofill suggestions. 457 SendKeyToPopupAndWait(ui::VKEY_RETURN); 458 459 // The form should be filled. 460 ExpectFilledTestForm(); 461} 462 463IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, AutofillSelectViaTab) { 464 CreateTestProfile(); 465 466 // Load the test page. 467 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 468 GURL(std::string(kDataURIPrefix) + kTestFormString))); 469 470 // Focus a fillable field. 471 FocusFirstNameField(); 472 473 // Press the down arrow to initiate Autofill and wait for the popup to be 474 // shown. 475 SendKeyToPageAndWait(ui::VKEY_DOWN); 476 477 // Press the down arrow to select the suggestion and preview the autofilled 478 // form. 479 SendKeyToPopupAndWait(ui::VKEY_DOWN); 480 481 // Press tab to accept the autofill suggestions. 482 SendKeyToPopupAndWait(ui::VKEY_TAB); 483 484 // The form should be filled. 485 ExpectFilledTestForm(); 486} 487 488// Test that a JavaScript onchange event is fired after auto-filling a form. 489IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, OnChangeAfterAutofill) { 490 CreateTestProfile(); 491 492 const char* kOnChangeScript = 493 "<script>" 494 "focused_fired = false;" 495 "unfocused_fired = false;" 496 "changed_select_fired = false;" 497 "unchanged_select_fired = false;" 498 "document.getElementById('firstname').onchange = function() {" 499 " focused_fired = true;" 500 "};" 501 "document.getElementById('lastname').onchange = function() {" 502 " unfocused_fired = true;" 503 "};" 504 "document.getElementById('state').onchange = function() {" 505 " changed_select_fired = true;" 506 "};" 507 "document.getElementById('country').onchange = function() {" 508 " unchanged_select_fired = true;" 509 "};" 510 "document.getElementById('country').value = 'US';" 511 "</script>"; 512 513 // Load the test page. 514 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 515 GURL(std::string(kDataURIPrefix) + kTestFormString + kOnChangeScript))); 516 517 // Invoke Autofill. 518 FocusFirstNameField(); 519 520 // Start filling the first name field with "M" and wait for the popup to be 521 // shown. 522 SendKeyToPageAndWait(ui::VKEY_M); 523 524 // Press the down arrow to select the suggestion and preview the autofilled 525 // form. 526 SendKeyToPopupAndWait(ui::VKEY_DOWN); 527 528 // Press Enter to accept the autofill suggestions. 529 SendKeyToPopupAndWait(ui::VKEY_RETURN); 530 531 // The form should be filled. 532 ExpectFilledTestForm(); 533 534 // The change event should have already fired for unfocused fields, both of 535 // <input> and of <select> type. However, it should not yet have fired for the 536 // focused field. 537 bool focused_fired = false; 538 bool unfocused_fired = false; 539 bool changed_select_fired = false; 540 bool unchanged_select_fired = false; 541 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 542 GetRenderViewHost(), 543 "domAutomationController.send(focused_fired);", 544 &focused_fired)); 545 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 546 GetRenderViewHost(), 547 "domAutomationController.send(unfocused_fired);", 548 &unfocused_fired)); 549 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 550 GetRenderViewHost(), 551 "domAutomationController.send(changed_select_fired);", 552 &changed_select_fired)); 553 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 554 GetRenderViewHost(), 555 "domAutomationController.send(unchanged_select_fired);", 556 &unchanged_select_fired)); 557 EXPECT_FALSE(focused_fired); 558 EXPECT_TRUE(unfocused_fired); 559 EXPECT_TRUE(changed_select_fired); 560 EXPECT_FALSE(unchanged_select_fired); 561 562 // Unfocus the first name field. Its change event should fire. 563 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 564 GetRenderViewHost(), 565 "document.getElementById('firstname').blur();" 566 "domAutomationController.send(focused_fired);", &focused_fired)); 567 EXPECT_TRUE(focused_fired); 568} 569 570// Test that we can autofill forms distinguished only by their |id| attribute. 571IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, 572 AutofillFormsDistinguishedById) { 573 CreateTestProfile(); 574 575 // Load the test page. 576 const std::string kURL = 577 std::string(kDataURIPrefix) + kTestFormString + 578 "<script>" 579 "var mainForm = document.forms[0];" 580 "mainForm.id = 'mainForm';" 581 "var newForm = document.createElement('form');" 582 "newForm.action = mainForm.action;" 583 "newForm.method = mainForm.method;" 584 "newForm.id = 'newForm';" 585 "mainForm.parentNode.insertBefore(newForm, mainForm);" 586 "</script>"; 587 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), GURL(kURL))); 588 589 // Invoke Autofill. 590 TryBasicFormFill(); 591} 592 593// Test that we properly autofill forms with repeated fields. 594// In the wild, the repeated fields are typically either email fields 595// (duplicated for "confirmation"); or variants that are hot-swapped via 596// JavaScript, with only one actually visible at any given time. 597IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, AutofillFormWithRepeatedField) { 598 CreateTestProfile(); 599 600 // Load the test page. 601 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 602 GURL(std::string(kDataURIPrefix) + 603 "<form action=\"http://www.example.com/\" method=\"POST\">" 604 "<label for=\"firstname\">First name:</label>" 605 " <input type=\"text\" id=\"firstname\"" 606 " onFocus=\"domAutomationController.send(true)\"><br>" 607 "<label for=\"lastname\">Last name:</label>" 608 " <input type=\"text\" id=\"lastname\"><br>" 609 "<label for=\"address1\">Address line 1:</label>" 610 " <input type=\"text\" id=\"address1\"><br>" 611 "<label for=\"address2\">Address line 2:</label>" 612 " <input type=\"text\" id=\"address2\"><br>" 613 "<label for=\"city\">City:</label>" 614 " <input type=\"text\" id=\"city\"><br>" 615 "<label for=\"state\">State:</label>" 616 " <select id=\"state\">" 617 " <option value=\"\" selected=\"yes\">--</option>" 618 " <option value=\"CA\">California</option>" 619 " <option value=\"TX\">Texas</option>" 620 " </select><br>" 621 "<label for=\"state_freeform\" style=\"display:none\">State:</label>" 622 " <input type=\"text\" id=\"state_freeform\"" 623 " style=\"display:none\"><br>" 624 "<label for=\"zip\">ZIP code:</label>" 625 " <input type=\"text\" id=\"zip\"><br>" 626 "<label for=\"country\">Country:</label>" 627 " <select id=\"country\">" 628 " <option value=\"\" selected=\"yes\">--</option>" 629 " <option value=\"CA\">Canada</option>" 630 " <option value=\"US\">United States</option>" 631 " </select><br>" 632 "<label for=\"phone\">Phone number:</label>" 633 " <input type=\"text\" id=\"phone\"><br>" 634 "</form>"))); 635 636 // Invoke Autofill. 637 TryBasicFormFill(); 638 ExpectFieldValue("state_freeform", std::string()); 639} 640 641// Test that we properly autofill forms with non-autofillable fields. 642IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, 643 AutofillFormWithNonAutofillableField) { 644 CreateTestProfile(); 645 646 // Load the test page. 647 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 648 GURL(std::string(kDataURIPrefix) + 649 "<form action=\"http://www.example.com/\" method=\"POST\">" 650 "<label for=\"firstname\">First name:</label>" 651 " <input type=\"text\" id=\"firstname\"" 652 " onFocus=\"domAutomationController.send(true)\"><br>" 653 "<label for=\"middlename\">Middle name:</label>" 654 " <input type=\"text\" id=\"middlename\" autocomplete=\"off\" /><br>" 655 "<label for=\"lastname\">Last name:</label>" 656 " <input type=\"text\" id=\"lastname\"><br>" 657 "<label for=\"address1\">Address line 1:</label>" 658 " <input type=\"text\" id=\"address1\"><br>" 659 "<label for=\"address2\">Address line 2:</label>" 660 " <input type=\"text\" id=\"address2\"><br>" 661 "<label for=\"city\">City:</label>" 662 " <input type=\"text\" id=\"city\"><br>" 663 "<label for=\"state\">State:</label>" 664 " <select id=\"state\">" 665 " <option value=\"\" selected=\"yes\">--</option>" 666 " <option value=\"CA\">California</option>" 667 " <option value=\"TX\">Texas</option>" 668 " </select><br>" 669 "<label for=\"zip\">ZIP code:</label>" 670 " <input type=\"text\" id=\"zip\"><br>" 671 "<label for=\"country\">Country:</label>" 672 " <select id=\"country\">" 673 " <option value=\"\" selected=\"yes\">--</option>" 674 " <option value=\"CA\">Canada</option>" 675 " <option value=\"US\">United States</option>" 676 " </select><br>" 677 "<label for=\"phone\">Phone number:</label>" 678 " <input type=\"text\" id=\"phone\"><br>" 679 "</form>"))); 680 681 // Invoke Autofill. 682 TryBasicFormFill(); 683} 684 685// Test that we can Autofill dynamically generated forms. 686IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, DynamicFormFill) { 687 CreateTestProfile(); 688 689 // Load the test page. 690 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 691 GURL(std::string(kDataURIPrefix) + 692 "<form id=\"form\" action=\"http://www.example.com/\"" 693 " method=\"POST\"></form>" 694 "<script>" 695 "function AddElement(name, label) {" 696 " var form = document.getElementById('form');" 697 "" 698 " var label_text = document.createTextNode(label);" 699 " var label_element = document.createElement('label');" 700 " label_element.setAttribute('for', name);" 701 " label_element.appendChild(label_text);" 702 " form.appendChild(label_element);" 703 "" 704 " if (name === 'state' || name === 'country') {" 705 " var select_element = document.createElement('select');" 706 " select_element.setAttribute('id', name);" 707 " select_element.setAttribute('name', name);" 708 "" 709 " /* Add an empty selected option. */" 710 " var default_option = new Option('--', '', true);" 711 " select_element.appendChild(default_option);" 712 "" 713 " /* Add the other options. */" 714 " if (name == 'state') {" 715 " var option1 = new Option('California', 'CA');" 716 " select_element.appendChild(option1);" 717 " var option2 = new Option('Texas', 'TX');" 718 " select_element.appendChild(option2);" 719 " } else {" 720 " var option1 = new Option('Canada', 'CA');" 721 " select_element.appendChild(option1);" 722 " var option2 = new Option('United States', 'US');" 723 " select_element.appendChild(option2);" 724 " }" 725 "" 726 " form.appendChild(select_element);" 727 " } else {" 728 " var input_element = document.createElement('input');" 729 " input_element.setAttribute('id', name);" 730 " input_element.setAttribute('name', name);" 731 "" 732 " /* Add the onFocus listener to the 'firstname' field. */" 733 " if (name === 'firstname') {" 734 " input_element.setAttribute(" 735 " 'onFocus', 'domAutomationController.send(true)');" 736 " }" 737 "" 738 " form.appendChild(input_element);" 739 " }" 740 "" 741 " form.appendChild(document.createElement('br'));" 742 "};" 743 "" 744 "function BuildForm() {" 745 " var elements = [" 746 " ['firstname', 'First name:']," 747 " ['lastname', 'Last name:']," 748 " ['address1', 'Address line 1:']," 749 " ['address2', 'Address line 2:']," 750 " ['city', 'City:']," 751 " ['state', 'State:']," 752 " ['zip', 'ZIP code:']," 753 " ['country', 'Country:']," 754 " ['phone', 'Phone number:']," 755 " ];" 756 "" 757 " for (var i = 0; i < elements.length; i++) {" 758 " var name = elements[i][0];" 759 " var label = elements[i][1];" 760 " AddElement(name, label);" 761 " }" 762 "};" 763 "</script>"))); 764 765 // Dynamically construct the form. 766 ASSERT_TRUE(content::ExecuteScript(GetRenderViewHost(), "BuildForm();")); 767 768 // Invoke Autofill. 769 TryBasicFormFill(); 770} 771 772// Test that form filling works after reloading the current page. 773IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, AutofillAfterReload) { 774 CreateTestProfile(); 775 776 // Load the test page. 777 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 778 GURL(std::string(kDataURIPrefix) + kTestFormString))); 779 780 // Reload the page. 781 content::WebContents* web_contents = GetWebContents(); 782 web_contents->GetController().Reload(false); 783 content::WaitForLoadStop(web_contents); 784 785 // Invoke Autofill. 786 TryBasicFormFill(); 787} 788 789IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, AutofillAfterTranslate) { 790 CreateTestProfile(); 791 792 GURL url(std::string(kDataURIPrefix) + 793 "<form action=\"http://www.example.com/\" method=\"POST\">" 794 "<label for=\"fn\">なまえ</label>" 795 " <input type=\"text\" id=\"fn\"" 796 " onFocus=\"domAutomationController.send(true)\"" 797 "><br>" 798 "<label for=\"ln\">みょうじ</label>" 799 " <input type=\"text\" id=\"ln\"><br>" 800 "<label for=\"a1\">Address line 1:</label>" 801 " <input type=\"text\" id=\"a1\"><br>" 802 "<label for=\"a2\">Address line 2:</label>" 803 " <input type=\"text\" id=\"a2\"><br>" 804 "<label for=\"ci\">City:</label>" 805 " <input type=\"text\" id=\"ci\"><br>" 806 "<label for=\"st\">State:</label>" 807 " <select id=\"st\">" 808 " <option value=\"\" selected=\"yes\">--</option>" 809 " <option value=\"CA\">California</option>" 810 " <option value=\"TX\">Texas</option>" 811 " </select><br>" 812 "<label for=\"z\">ZIP code:</label>" 813 " <input type=\"text\" id=\"z\"><br>" 814 "<label for=\"co\">Country:</label>" 815 " <select id=\"co\">" 816 " <option value=\"\" selected=\"yes\">--</option>" 817 " <option value=\"CA\">Canada</option>" 818 " <option value=\"US\">United States</option>" 819 " </select><br>" 820 "<label for=\"ph\">Phone number:</label>" 821 " <input type=\"text\" id=\"ph\"><br>" 822 "</form>" 823 // Add additional Japanese characters to ensure the translate bar 824 // will appear. 825 "我々は重要な、興味深いものになるが、時折状況が発生するため苦労や痛みは" 826 "彼にいくつかの素晴らしいを調達することができます。それから、いくつかの利"); 827 828 content::WindowedNotificationObserver infobar_observer( 829 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, 830 content::NotificationService::AllSources()); 831 ASSERT_NO_FATAL_FAILURE( 832 ui_test_utils::NavigateToURL(browser(), url)); 833 834 // Wait for the translation bar to appear and get it. 835 infobar_observer.Wait(); 836 TranslateInfoBarDelegate* delegate = 837 InfoBarService::FromWebContents(GetWebContents())->infobar_at(0)-> 838 delegate()->AsTranslateInfoBarDelegate(); 839 ASSERT_TRUE(delegate); 840 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, 841 delegate->infobar_type()); 842 843 // Simulate translation button press. 844 delegate->Translate(); 845 846 content::WindowedNotificationObserver translation_observer( 847 chrome::NOTIFICATION_PAGE_TRANSLATED, 848 content::NotificationService::AllSources()); 849 850 // Simulate the translate script being retrieved. 851 // Pass fake google.translate lib as the translate script. 852 SimulateURLFetch(true); 853 854 // Simulate the render notifying the translation has been done. 855 translation_observer.Wait(); 856 857 TryBasicFormFill(); 858} 859 860// Test phone fields parse correctly from a given profile. 861// The high level key presses execute the following: Select the first text 862// field, invoke the autofill popup list, select the first profile within the 863// list, and commit to the profile to populate the form. 864IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, ComparePhoneNumbers) { 865 ASSERT_TRUE(test_server()->Start()); 866 867 AutofillProfile profile; 868 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bob")); 869 profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Smith")); 870 profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1234 H St.")); 871 profile.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("San Jose")); 872 profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA")); 873 profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("95110")); 874 profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("1-408-555-4567")); 875 SetProfile(profile); 876 877 GURL url = test_server()->GetURL("files/autofill/form_phones.html"); 878 ui_test_utils::NavigateToURL(browser(), url); 879 PopulateForm("NAME_FIRST"); 880 881 ExpectFieldValue("NAME_FIRST", "Bob"); 882 ExpectFieldValue("NAME_LAST", "Smith"); 883 ExpectFieldValue("ADDRESS_HOME_LINE1", "1234 H St."); 884 ExpectFieldValue("ADDRESS_HOME_CITY", "San Jose"); 885 ExpectFieldValue("ADDRESS_HOME_STATE", "CA"); 886 ExpectFieldValue("ADDRESS_HOME_ZIP", "95110"); 887 ExpectFieldValue("PHONE_HOME_WHOLE_NUMBER", "14085554567"); 888 ExpectFieldValue("PHONE_HOME_CITY_CODE-1", "408"); 889 ExpectFieldValue("PHONE_HOME_CITY_CODE-2", "408"); 890 ExpectFieldValue("PHONE_HOME_NUMBER", "5554567"); 891 ExpectFieldValue("PHONE_HOME_NUMBER_3-1", "555"); 892 ExpectFieldValue("PHONE_HOME_NUMBER_3-2", "555"); 893 ExpectFieldValue("PHONE_HOME_NUMBER_4-1", "4567"); 894 ExpectFieldValue("PHONE_HOME_NUMBER_4-2", "4567"); 895 ExpectFieldValue("PHONE_HOME_EXT-1", std::string()); 896 ExpectFieldValue("PHONE_HOME_EXT-2", std::string()); 897 ExpectFieldValue("PHONE_HOME_COUNTRY_CODE-1", "1"); 898} 899 900// Test that Autofill does not fill in read-only fields. 901IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, NoAutofillForReadOnlyFields) { 902 ASSERT_TRUE(test_server()->Start()); 903 904 std::string addr_line1("1234 H St."); 905 906 AutofillProfile profile; 907 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bob")); 908 profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Smith")); 909 profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("bsmith@gmail.com")); 910 profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16(addr_line1)); 911 profile.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("San Jose")); 912 profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA")); 913 profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("95110")); 914 profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Company X")); 915 profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("408-871-4567")); 916 SetProfile(profile); 917 918 GURL url = test_server()->GetURL("files/autofill/read_only_field_test.html"); 919 ui_test_utils::NavigateToURL(browser(), url); 920 PopulateForm("firstname"); 921 922 ExpectFieldValue("email", std::string()); 923 ExpectFieldValue("address", addr_line1); 924} 925 926// Test form is fillable from a profile after form was reset. 927// Steps: 928// 1. Fill form using a saved profile. 929// 2. Reset the form. 930// 3. Fill form using a saved profile. 931// Flakily times out: http://crbug.com/270341 932IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, DISABLED_FormFillableOnReset) { 933 ASSERT_TRUE(test_server()->Start()); 934 935 CreateTestProfile(); 936 937 GURL url = test_server()->GetURL("files/autofill/autofill_test_form.html"); 938 ui_test_utils::NavigateToURL(browser(), url); 939 PopulateForm("NAME_FIRST"); 940 941 ASSERT_TRUE(content::ExecuteScript( 942 GetWebContents(), "document.getElementById('testform').reset()")); 943 944 PopulateForm("NAME_FIRST"); 945 946 ExpectFieldValue("NAME_FIRST", "Milton"); 947 ExpectFieldValue("NAME_LAST", "Waddams"); 948 ExpectFieldValue("EMAIL_ADDRESS", "red.swingline@initech.com"); 949 ExpectFieldValue("ADDRESS_HOME_LINE1", "4120 Freidrich Lane"); 950 ExpectFieldValue("ADDRESS_HOME_CITY", "Austin"); 951 ExpectFieldValue("ADDRESS_HOME_STATE", "Texas"); 952 ExpectFieldValue("ADDRESS_HOME_ZIP", "78744"); 953 ExpectFieldValue("ADDRESS_HOME_COUNTRY", "United States"); 954 ExpectFieldValue("PHONE_HOME_WHOLE_NUMBER", "5125551234"); 955} 956 957// Test Autofill distinguishes a middle initial in a name. 958// Flakily times out: http://crbug.com/270341 959IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, 960 DISABLED_DistinguishMiddleInitialWithinName) { 961 ASSERT_TRUE(test_server()->Start()); 962 963 CreateTestProfile(); 964 965 GURL url = test_server()->GetURL( 966 "files/autofill/autofill_middleinit_form.html"); 967 ui_test_utils::NavigateToURL(browser(), url); 968 PopulateForm("NAME_FIRST"); 969 970 ExpectFieldValue("NAME_MIDDLE", "C"); 971} 972 973// Test forms with multiple email addresses are filled properly. 974// Entire form should be filled with one user gesture. 975// Flakily times out: http://crbug.com/270341 976IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, 977 DISABLED_MultipleEmailFilledByOneUserGesture) { 978 ASSERT_TRUE(test_server()->Start()); 979 980 std::string email("bsmith@gmail.com"); 981 982 AutofillProfile profile; 983 profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bob")); 984 profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Smith")); 985 profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16(email)); 986 profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("4088714567")); 987 SetProfile(profile); 988 989 GURL url = test_server()->GetURL( 990 "files/autofill/autofill_confirmemail_form.html"); 991 ui_test_utils::NavigateToURL(browser(), url); 992 PopulateForm("NAME_FIRST"); 993 994 ExpectFieldValue("EMAIL_CONFIRM", email); 995 // TODO(isherman): verify entire form. 996} 997 998// http://crbug.com/281527 999#if defined(OS_MACOSX) 1000#define MAYBE_FormFillLatencyAfterSubmit FormFillLatencyAfterSubmit 1001#else 1002#define MAYBE_FormFillLatencyAfterSubmit DISABLED_FormFillLatencyAfterSubmit 1003#endif 1004// Test latency time on form submit with lots of stored Autofill profiles. 1005// This test verifies when a profile is selected from the Autofill dictionary 1006// that consists of thousands of profiles, the form does not hang after being 1007// submitted. 1008IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, 1009 MAYBE_FormFillLatencyAfterSubmit) { 1010 ASSERT_TRUE(test_server()->Start()); 1011 1012 std::vector<std::string> cities; 1013 cities.push_back("San Jose"); 1014 cities.push_back("San Francisco"); 1015 cities.push_back("Sacramento"); 1016 cities.push_back("Los Angeles"); 1017 1018 std::vector<std::string> streets; 1019 streets.push_back("St"); 1020 streets.push_back("Ave"); 1021 streets.push_back("Ln"); 1022 streets.push_back("Ct"); 1023 1024 const int kNumProfiles = 1500; 1025 base::Time start_time = base::Time::Now(); 1026 std::vector<AutofillProfile> profiles; 1027 for (int i = 0; i < kNumProfiles; i++) { 1028 AutofillProfile profile; 1029 base::string16 name(base::IntToString16(i)); 1030 base::string16 email(name + ASCIIToUTF16("@example.com")); 1031 base::string16 street = ASCIIToUTF16( 1032 base::IntToString(base::RandInt(0, 10000)) + " " + 1033 streets[base::RandInt(0, streets.size() - 1)]); 1034 base::string16 city = ASCIIToUTF16(cities[base::RandInt(0, cities.size() - 1)]); 1035 base::string16 zip(base::IntToString16(base::RandInt(0, 10000))); 1036 profile.SetRawInfo(NAME_FIRST, name); 1037 profile.SetRawInfo(EMAIL_ADDRESS, email); 1038 profile.SetRawInfo(ADDRESS_HOME_LINE1, street); 1039 profile.SetRawInfo(ADDRESS_HOME_CITY, city); 1040 profile.SetRawInfo(ADDRESS_HOME_STATE, WideToUTF16(L"CA")); 1041 profile.SetRawInfo(ADDRESS_HOME_ZIP, zip); 1042 profile.SetRawInfo(ADDRESS_HOME_COUNTRY, WideToUTF16(L"US")); 1043 profiles.push_back(profile); 1044 } 1045 SetProfiles(&profiles); 1046 // TODO(isherman): once we're sure this test doesn't timeout on any bots, this 1047 // can be removd. 1048 LOG(INFO) << "Created " << kNumProfiles << " profiles in " << 1049 (base::Time::Now() - start_time).InSeconds() << " seconds."; 1050 1051 GURL url = test_server()->GetURL( 1052 "files/autofill/latency_after_submit_test.html"); 1053 ui_test_utils::NavigateToURL(browser(), url); 1054 PopulateForm("NAME_FIRST"); 1055 1056 content::WindowedNotificationObserver load_stop_observer( 1057 content::NOTIFICATION_LOAD_STOP, 1058 content::Source<content::NavigationController>( 1059 &GetWebContents()->GetController())); 1060 1061 ASSERT_TRUE(content::ExecuteScript( 1062 GetRenderViewHost(), 1063 "document.getElementById('testform').submit();")); 1064 // This will ensure the test didn't hang. 1065 load_stop_observer.Wait(); 1066} 1067 1068// Test that Chrome doesn't crash when autocomplete is disabled while the user 1069// is interacting with the form. This is a regression test for 1070// http://crbug.com/160476 1071IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest, 1072 DisableAutocompleteWhileFilling) { 1073 CreateTestProfile(); 1074 1075 // Load the test page. 1076 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), 1077 GURL(std::string(kDataURIPrefix) + kTestFormString))); 1078 1079 // Invoke Autofill: Start filling the first name field with "M" and wait for 1080 // the popup to be shown. 1081 FocusFirstNameField(); 1082 SendKeyToPageAndWait(ui::VKEY_M); 1083 1084 // Now that the popup with suggestions is showing, disable autocomplete for 1085 // the active field. 1086 ASSERT_TRUE(content::ExecuteScript( 1087 GetRenderViewHost(), 1088 "document.querySelector('input').autocomplete = 'off';")); 1089 1090 // Press the down arrow to select the suggestion and attempt to preview the 1091 // autofilled form. 1092 SendKeyToPopupAndWait(ui::VKEY_DOWN); 1093} 1094 1095} // namespace autofill 1096