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.
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_service.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/translate/translate_infobar_delegate.h"
24 #include "chrome/browser/translate/translate_service.h"
25 #include "chrome/browser/translate/translate_tab_helper.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/content_autofill_driver.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 "components/infobars/core/infobar.h"
42 #include "components/infobars/core/infobar_manager.h"
43 #include "content/public/browser/navigation_controller.h"
44 #include "content/public/browser/notification_observer.h"
45 #include "content/public/browser/notification_registrar.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/render_view_host.h"
48 #include "content/public/browser/render_widget_host.h"
49 #include "content/public/browser/web_contents.h"
50 #include "content/public/test/browser_test_utils.h"
51 #include "content/public/test/test_renderer_host.h"
52 #include "content/public/test/test_utils.h"
53 #include "net/url_request/test_url_fetcher_factory.h"
54 #include "testing/gmock/include/gmock/gmock.h"
55 #include "testing/gtest/include/gtest/gtest.h"
56 #include "ui/events/keycodes/keyboard_codes.h"
58 using base::ASCIIToUTF16
;
62 static const char kDataURIPrefix
[] = "data:text/html;charset=utf-8,";
63 static const char kTestFormString
[] =
64 "<form action=\"http://www.example.com/\" method=\"POST\">"
65 "<label for=\"firstname\">First name:</label>"
66 " <input type=\"text\" id=\"firstname\""
67 " onfocus=\"domAutomationController.send(true)\"><br>"
68 "<label for=\"lastname\">Last name:</label>"
69 " <input type=\"text\" id=\"lastname\"><br>"
70 "<label for=\"address1\">Address line 1:</label>"
71 " <input type=\"text\" id=\"address1\"><br>"
72 "<label for=\"address2\">Address line 2:</label>"
73 " <input type=\"text\" id=\"address2\"><br>"
74 "<label for=\"city\">City:</label>"
75 " <input type=\"text\" id=\"city\"><br>"
76 "<label for=\"state\">State:</label>"
77 " <select id=\"state\">"
78 " <option value=\"\" selected=\"yes\">--</option>"
79 " <option value=\"CA\">California</option>"
80 " <option value=\"TX\">Texas</option>"
82 "<label for=\"zip\">ZIP code:</label>"
83 " <input type=\"text\" id=\"zip\"><br>"
84 "<label for=\"country\">Country:</label>"
85 " <select id=\"country\">"
86 " <option value=\"\" selected=\"yes\">--</option>"
87 " <option value=\"CA\">Canada</option>"
88 " <option value=\"US\">United States</option>"
90 "<label for=\"phone\">Phone number:</label>"
91 " <input type=\"text\" id=\"phone\"><br>"
95 // AutofillManagerTestDelegateImpl --------------------------------------------
97 class AutofillManagerTestDelegateImpl
98 : public autofill::AutofillManagerTestDelegate
{
100 AutofillManagerTestDelegateImpl() {}
101 virtual ~AutofillManagerTestDelegateImpl() {}
103 // autofill::AutofillManagerTestDelegate:
104 virtual void DidPreviewFormData() OVERRIDE
{
105 loop_runner_
->Quit();
108 virtual void DidFillFormData() OVERRIDE
{
109 loop_runner_
->Quit();
112 virtual void DidShowSuggestions() OVERRIDE
{
113 loop_runner_
->Quit();
117 loop_runner_
= new content::MessageLoopRunner();
125 scoped_refptr
<content::MessageLoopRunner
> loop_runner_
;
127 DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl
);
131 // WindowedPersonalDataManagerObserver ----------------------------------------
133 class WindowedPersonalDataManagerObserver
134 : public PersonalDataManagerObserver
,
135 public infobars::InfoBarManager::Observer
{
137 explicit WindowedPersonalDataManagerObserver(Browser
* browser
)
139 has_run_message_loop_(false),
141 infobar_service_(InfoBarService::FromWebContents(
142 browser_
->tab_strip_model()->GetActiveWebContents())) {
143 PersonalDataManagerFactory::GetForProfile(browser_
->profile())->
145 infobar_service_
->AddObserver(this);
148 virtual ~WindowedPersonalDataManagerObserver() {
149 while (infobar_service_
->infobar_count() > 0) {
150 infobar_service_
->RemoveInfoBar(infobar_service_
->infobar_at(0));
152 infobar_service_
->RemoveObserver(this);
155 // PersonalDataManagerObserver:
156 virtual void OnPersonalDataChanged() OVERRIDE
{
157 if (has_run_message_loop_
) {
158 base::MessageLoopForUI::current()->Quit();
159 has_run_message_loop_
= false;
164 virtual void OnInsufficientFormData() OVERRIDE
{
165 OnPersonalDataChanged();
171 has_run_message_loop_
= true;
172 content::RunMessageLoop();
174 PersonalDataManagerFactory::GetForProfile(browser_
->profile())->
175 RemoveObserver(this);
179 // infobars::InfoBarManager::Observer:
180 virtual void OnInfoBarAdded(infobars::InfoBar
* infobar
) OVERRIDE
{
181 infobar_service_
->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate()->
186 bool has_run_message_loop_
;
188 InfoBarService
* infobar_service_
;
190 DISALLOW_COPY_AND_ASSIGN(WindowedPersonalDataManagerObserver
);
193 // AutofillInteractiveTest ----------------------------------------------------
195 class AutofillInteractiveTest
: public InProcessBrowserTest
{
197 AutofillInteractiveTest() :
198 key_press_event_sink_(
199 base::Bind(&AutofillInteractiveTest::HandleKeyPressEvent
,
200 base::Unretained(this))) {}
201 virtual ~AutofillInteractiveTest() {}
203 // InProcessBrowserTest:
204 virtual void SetUpOnMainThread() OVERRIDE
{
205 TranslateService::SetUseInfobar(true);
207 // Don't want Keychain coming up on Mac.
208 test::DisableSystemServices(browser()->profile()->GetPrefs());
210 // Inject the test delegate into the AutofillManager.
211 content::WebContents
* web_contents
= GetWebContents();
212 ContentAutofillDriver
* autofill_driver
=
213 ContentAutofillDriver::FromWebContents(web_contents
);
214 AutofillManager
* autofill_manager
= autofill_driver
->autofill_manager();
215 autofill_manager
->SetTestDelegate(&test_delegate_
);
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
= ContentAutofillDriver::FromWebContents(
222 web_contents
)->autofill_manager();
223 autofill_manager
->delegate()->HideAutofillPopup();
226 PersonalDataManager
* GetPersonalDataManager() {
227 return PersonalDataManagerFactory::GetForProfile(browser()->profile());
230 content::WebContents
* GetWebContents() {
231 return browser()->tab_strip_model()->GetActiveWebContents();
234 content::RenderViewHost
* GetRenderViewHost() {
235 return GetWebContents()->GetRenderViewHost();
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");
245 WindowedPersonalDataManagerObserver
observer(browser());
246 GetPersonalDataManager()->AddProfile(profile
);
248 // AddProfile is asynchronous. Wait for it to finish before continuing the
253 void SetProfiles(std::vector
<AutofillProfile
>* profiles
) {
254 WindowedPersonalDataManagerObserver
observer(browser());
255 GetPersonalDataManager()->SetProfiles(profiles
);
259 void SetProfile(const AutofillProfile
& profile
) {
260 std::vector
<AutofillProfile
> profiles
;
261 profiles
.push_back(profile
);
262 SetProfiles(&profiles
);
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
));
272 SendKeyToPageAndWait(ui::VKEY_DOWN
);
273 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
274 SendKeyToPopupAndWait(ui::VKEY_RETURN
);
277 void ExpectFieldValue(const std::string
& field_name
,
278 const std::string
& expected_value
) {
280 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
282 "window.domAutomationController.send("
283 " document.getElementById('" + field_name
+ "').value);",
285 EXPECT_EQ(expected_value
, value
);
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
);
295 std::string script
= " var google = {};"
296 "google.translate = (function() {"
298 " TranslateService: function() {"
300 " isAvailable : function() {"
303 " restore : function() {"
306 " getDetectedLanguage : function() {"
309 " translatePage : function(originalLang, targetLang,"
310 " onTranslateProgress) {"
311 " document.getElementsByTagName(\"body\")[0].innerHTML = '" +
312 std::string(kTestFormString
) +
314 " onTranslateProgress(100, true, false);"
320 "cr.googleTranslate.onTranslateElementLoad();";
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
);
329 void FocusFirstNameField() {
331 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
333 "if (document.readyState === 'complete')"
334 " document.getElementById('firstname').focus();"
336 " domAutomationController.send(false);",
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");
353 void SendKeyToPageAndWait(ui::KeyboardCode key
) {
354 test_delegate_
.Reset();
355 content::SimulateKeyPress(
356 GetWebContents(), key
, false, false, false, false);
357 test_delegate_
.Wait();
360 bool HandleKeyPressEvent(const content::NativeWebKeyboardEvent
& event
) {
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_
);
378 void TryBasicFormFill() {
379 FocusFirstNameField();
381 // Start filling the first name field with "M" and wait for the popup to be
383 SendKeyToPageAndWait(ui::VKEY_M
);
385 // Press the down arrow to select the suggestion and preview the autofilled
387 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
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
402 // Press Enter to accept the autofill suggestions.
403 SendKeyToPopupAndWait(ui::VKEY_RETURN
);
405 // The form should be filled.
406 ExpectFilledTestForm();
410 AutofillManagerTestDelegateImpl test_delegate_
;
412 net::TestURLFetcherFactory url_fetcher_factory_
;
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
420 content::RenderWidgetHost::KeyPressEventCallback key_press_event_sink_
;
422 DISALLOW_COPY_AND_ASSIGN(AutofillInteractiveTest
);
425 // Test that basic form fill is working.
426 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, BasicFormFill
) {
429 // Load the test page.
430 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
431 GURL(std::string(kDataURIPrefix
) + kTestFormString
)));
437 // Test that form filling can be initiated by pressing the down arrow.
438 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, AutofillViaDownArrow
) {
441 // Load the test page.
442 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
443 GURL(std::string(kDataURIPrefix
) + kTestFormString
)));
445 // Focus a fillable field.
446 FocusFirstNameField();
448 // Press the down arrow to initiate Autofill and wait for the popup to be
450 SendKeyToPageAndWait(ui::VKEY_DOWN
);
452 // Press the down arrow to select the suggestion and preview the autofilled
454 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
456 // Press Enter to accept the autofill suggestions.
457 SendKeyToPopupAndWait(ui::VKEY_RETURN
);
459 // The form should be filled.
460 ExpectFilledTestForm();
463 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, AutofillSelectViaTab
) {
466 // Load the test page.
467 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
468 GURL(std::string(kDataURIPrefix
) + kTestFormString
)));
470 // Focus a fillable field.
471 FocusFirstNameField();
473 // Press the down arrow to initiate Autofill and wait for the popup to be
475 SendKeyToPageAndWait(ui::VKEY_DOWN
);
477 // Press the down arrow to select the suggestion and preview the autofilled
479 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
481 // Press tab to accept the autofill suggestions.
482 SendKeyToPopupAndWait(ui::VKEY_TAB
);
484 // The form should be filled.
485 ExpectFilledTestForm();
488 // Test that a JavaScript oninput event is fired after auto-filling a form.
489 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, OnInputAfterAutofill
) {
492 const char kOnInputScript
[] =
494 "focused_fired = false;"
495 "unfocused_fired = false;"
496 "changed_select_fired = false;"
497 "unchanged_select_fired = false;"
498 "document.getElementById('firstname').oninput = function() {"
499 " focused_fired = true;"
501 "document.getElementById('lastname').oninput = function() {"
502 " unfocused_fired = true;"
504 "document.getElementById('state').oninput = function() {"
505 " changed_select_fired = true;"
507 "document.getElementById('country').oninput = function() {"
508 " unchanged_select_fired = true;"
510 "document.getElementById('country').value = 'US';"
513 // Load the test page.
514 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
515 GURL(std::string(kDataURIPrefix
) + kTestFormString
+ kOnInputScript
)));
518 FocusFirstNameField();
520 // Start filling the first name field with "M" and wait for the popup to be
522 SendKeyToPageAndWait(ui::VKEY_M
);
524 // Press the down arrow to select the suggestion and preview the autofilled
526 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
528 // Press Enter to accept the autofill suggestions.
529 SendKeyToPopupAndWait(ui::VKEY_RETURN
);
531 // The form should be filled.
532 ExpectFilledTestForm();
534 bool focused_fired
= false;
535 bool unfocused_fired
= false;
536 bool changed_select_fired
= false;
537 bool unchanged_select_fired
= false;
538 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
540 "domAutomationController.send(focused_fired);",
542 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
544 "domAutomationController.send(unfocused_fired);",
546 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
548 "domAutomationController.send(changed_select_fired);",
549 &changed_select_fired
));
550 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
552 "domAutomationController.send(unchanged_select_fired);",
553 &unchanged_select_fired
));
554 EXPECT_TRUE(focused_fired
);
555 EXPECT_TRUE(unfocused_fired
);
556 EXPECT_TRUE(changed_select_fired
);
557 EXPECT_FALSE(unchanged_select_fired
);
560 // Test that a JavaScript onchange event is fired after auto-filling a form.
561 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, OnChangeAfterAutofill
) {
564 const char kOnChangeScript
[] =
566 "focused_fired = false;"
567 "unfocused_fired = false;"
568 "changed_select_fired = false;"
569 "unchanged_select_fired = false;"
570 "document.getElementById('firstname').onchange = function() {"
571 " focused_fired = true;"
573 "document.getElementById('lastname').onchange = function() {"
574 " unfocused_fired = true;"
576 "document.getElementById('state').onchange = function() {"
577 " changed_select_fired = true;"
579 "document.getElementById('country').onchange = function() {"
580 " unchanged_select_fired = true;"
582 "document.getElementById('country').value = 'US';"
585 // Load the test page.
586 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
587 GURL(std::string(kDataURIPrefix
) + kTestFormString
+ kOnChangeScript
)));
590 FocusFirstNameField();
592 // Start filling the first name field with "M" and wait for the popup to be
594 SendKeyToPageAndWait(ui::VKEY_M
);
596 // Press the down arrow to select the suggestion and preview the autofilled
598 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
600 // Press Enter to accept the autofill suggestions.
601 SendKeyToPopupAndWait(ui::VKEY_RETURN
);
603 // The form should be filled.
604 ExpectFilledTestForm();
606 bool focused_fired
= false;
607 bool unfocused_fired
= false;
608 bool changed_select_fired
= false;
609 bool unchanged_select_fired
= false;
610 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
612 "domAutomationController.send(focused_fired);",
614 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
616 "domAutomationController.send(unfocused_fired);",
618 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
620 "domAutomationController.send(changed_select_fired);",
621 &changed_select_fired
));
622 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
624 "domAutomationController.send(unchanged_select_fired);",
625 &unchanged_select_fired
));
626 EXPECT_TRUE(focused_fired
);
627 EXPECT_TRUE(unfocused_fired
);
628 EXPECT_TRUE(changed_select_fired
);
629 EXPECT_FALSE(unchanged_select_fired
);
632 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, InputFiresBeforeChange
) {
635 const char kInputFiresBeforeChangeScript
[] =
637 "inputElementEvents = [];"
638 "function recordInputElementEvent(e) {"
639 " if (e.target.tagName != 'INPUT') throw 'only <input> tags allowed';"
640 " inputElementEvents.push(e.type);"
642 "selectElementEvents = [];"
643 "function recordSelectElementEvent(e) {"
644 " if (e.target.tagName != 'SELECT') throw 'only <select> tags allowed';"
645 " selectElementEvents.push(e.type);"
647 "document.getElementById('lastname').oninput = recordInputElementEvent;"
648 "document.getElementById('lastname').onchange = recordInputElementEvent;"
649 "document.getElementById('country').oninput = recordSelectElementEvent;"
650 "document.getElementById('country').onchange = recordSelectElementEvent;"
653 // Load the test page.
654 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
655 GURL(std::string(kDataURIPrefix
) + kTestFormString
+
656 kInputFiresBeforeChangeScript
)));
658 // Invoke and accept the Autofill popup and verify the form was filled.
659 FocusFirstNameField();
660 SendKeyToPageAndWait(ui::VKEY_M
);
661 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
662 SendKeyToPopupAndWait(ui::VKEY_RETURN
);
663 ExpectFilledTestForm();
665 int num_input_element_events
= -1;
666 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
668 "domAutomationController.send(inputElementEvents.length);",
669 &num_input_element_events
));
670 EXPECT_EQ(2, num_input_element_events
);
672 std::vector
<std::string
> input_element_events
;
673 input_element_events
.resize(2);
675 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
677 "domAutomationController.send(inputElementEvents[0]);",
678 &input_element_events
[0]));
679 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
681 "domAutomationController.send(inputElementEvents[1]);",
682 &input_element_events
[1]));
684 EXPECT_EQ("input", input_element_events
[0]);
685 EXPECT_EQ("change", input_element_events
[1]);
687 int num_select_element_events
= -1;
688 ASSERT_TRUE(content::ExecuteScriptAndExtractInt(
690 "domAutomationController.send(selectElementEvents.length);",
691 &num_select_element_events
));
692 EXPECT_EQ(2, num_select_element_events
);
694 std::vector
<std::string
> select_element_events
;
695 select_element_events
.resize(2);
697 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
699 "domAutomationController.send(selectElementEvents[0]);",
700 &select_element_events
[0]));
701 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
703 "domAutomationController.send(selectElementEvents[1]);",
704 &select_element_events
[1]));
706 EXPECT_EQ("input", select_element_events
[0]);
707 EXPECT_EQ("change", select_element_events
[1]);
710 // Test that we can autofill forms distinguished only by their |id| attribute.
711 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
,
712 AutofillFormsDistinguishedById
) {
715 // Load the test page.
716 const std::string kURL
=
717 std::string(kDataURIPrefix
) + kTestFormString
+
719 "var mainForm = document.forms[0];"
720 "mainForm.id = 'mainForm';"
721 "var newForm = document.createElement('form');"
722 "newForm.action = mainForm.action;"
723 "newForm.method = mainForm.method;"
724 "newForm.id = 'newForm';"
725 "mainForm.parentNode.insertBefore(newForm, mainForm);"
727 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), GURL(kURL
)));
733 // Test that we properly autofill forms with repeated fields.
734 // In the wild, the repeated fields are typically either email fields
735 // (duplicated for "confirmation"); or variants that are hot-swapped via
736 // JavaScript, with only one actually visible at any given time.
737 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, AutofillFormWithRepeatedField
) {
740 // Load the test page.
741 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
742 GURL(std::string(kDataURIPrefix
) +
743 "<form action=\"http://www.example.com/\" method=\"POST\">"
744 "<label for=\"firstname\">First name:</label>"
745 " <input type=\"text\" id=\"firstname\""
746 " onfocus=\"domAutomationController.send(true)\"><br>"
747 "<label for=\"lastname\">Last name:</label>"
748 " <input type=\"text\" id=\"lastname\"><br>"
749 "<label for=\"address1\">Address line 1:</label>"
750 " <input type=\"text\" id=\"address1\"><br>"
751 "<label for=\"address2\">Address line 2:</label>"
752 " <input type=\"text\" id=\"address2\"><br>"
753 "<label for=\"city\">City:</label>"
754 " <input type=\"text\" id=\"city\"><br>"
755 "<label for=\"state\">State:</label>"
756 " <select id=\"state\">"
757 " <option value=\"\" selected=\"yes\">--</option>"
758 " <option value=\"CA\">California</option>"
759 " <option value=\"TX\">Texas</option>"
761 "<label for=\"state_freeform\" style=\"display:none\">State:</label>"
762 " <input type=\"text\" id=\"state_freeform\""
763 " style=\"display:none\"><br>"
764 "<label for=\"zip\">ZIP code:</label>"
765 " <input type=\"text\" id=\"zip\"><br>"
766 "<label for=\"country\">Country:</label>"
767 " <select id=\"country\">"
768 " <option value=\"\" selected=\"yes\">--</option>"
769 " <option value=\"CA\">Canada</option>"
770 " <option value=\"US\">United States</option>"
772 "<label for=\"phone\">Phone number:</label>"
773 " <input type=\"text\" id=\"phone\"><br>"
778 ExpectFieldValue("state_freeform", std::string());
781 // Test that we properly autofill forms with non-autofillable fields.
782 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
,
783 AutofillFormWithNonAutofillableField
) {
786 // Load the test page.
787 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
788 GURL(std::string(kDataURIPrefix
) +
789 "<form action=\"http://www.example.com/\" method=\"POST\">"
790 "<label for=\"firstname\">First name:</label>"
791 " <input type=\"text\" id=\"firstname\""
792 " onfocus=\"domAutomationController.send(true)\"><br>"
793 "<label for=\"middlename\">Middle name:</label>"
794 " <input type=\"text\" id=\"middlename\" autocomplete=\"off\" /><br>"
795 "<label for=\"lastname\">Last name:</label>"
796 " <input type=\"text\" id=\"lastname\"><br>"
797 "<label for=\"address1\">Address line 1:</label>"
798 " <input type=\"text\" id=\"address1\"><br>"
799 "<label for=\"address2\">Address line 2:</label>"
800 " <input type=\"text\" id=\"address2\"><br>"
801 "<label for=\"city\">City:</label>"
802 " <input type=\"text\" id=\"city\"><br>"
803 "<label for=\"state\">State:</label>"
804 " <select id=\"state\">"
805 " <option value=\"\" selected=\"yes\">--</option>"
806 " <option value=\"CA\">California</option>"
807 " <option value=\"TX\">Texas</option>"
809 "<label for=\"zip\">ZIP code:</label>"
810 " <input type=\"text\" id=\"zip\"><br>"
811 "<label for=\"country\">Country:</label>"
812 " <select id=\"country\">"
813 " <option value=\"\" selected=\"yes\">--</option>"
814 " <option value=\"CA\">Canada</option>"
815 " <option value=\"US\">United States</option>"
817 "<label for=\"phone\">Phone number:</label>"
818 " <input type=\"text\" id=\"phone\"><br>"
825 // Test that we can Autofill dynamically generated forms.
826 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, DynamicFormFill
) {
829 // Load the test page.
830 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
831 GURL(std::string(kDataURIPrefix
) +
832 "<form id=\"form\" action=\"http://www.example.com/\""
833 " method=\"POST\"></form>"
835 "function AddElement(name, label) {"
836 " var form = document.getElementById('form');"
838 " var label_text = document.createTextNode(label);"
839 " var label_element = document.createElement('label');"
840 " label_element.setAttribute('for', name);"
841 " label_element.appendChild(label_text);"
842 " form.appendChild(label_element);"
844 " if (name === 'state' || name === 'country') {"
845 " var select_element = document.createElement('select');"
846 " select_element.setAttribute('id', name);"
847 " select_element.setAttribute('name', name);"
849 " /* Add an empty selected option. */"
850 " var default_option = new Option('--', '', true);"
851 " select_element.appendChild(default_option);"
853 " /* Add the other options. */"
854 " if (name == 'state') {"
855 " var option1 = new Option('California', 'CA');"
856 " select_element.appendChild(option1);"
857 " var option2 = new Option('Texas', 'TX');"
858 " select_element.appendChild(option2);"
860 " var option1 = new Option('Canada', 'CA');"
861 " select_element.appendChild(option1);"
862 " var option2 = new Option('United States', 'US');"
863 " select_element.appendChild(option2);"
866 " form.appendChild(select_element);"
868 " var input_element = document.createElement('input');"
869 " input_element.setAttribute('id', name);"
870 " input_element.setAttribute('name', name);"
872 " /* Add the onfocus listener to the 'firstname' field. */"
873 " if (name === 'firstname') {"
874 " input_element.onfocus = function() {"
875 " domAutomationController.send(true);"
879 " form.appendChild(input_element);"
882 " form.appendChild(document.createElement('br'));"
885 "function BuildForm() {"
887 " ['firstname', 'First name:'],"
888 " ['lastname', 'Last name:'],"
889 " ['address1', 'Address line 1:'],"
890 " ['address2', 'Address line 2:'],"
891 " ['city', 'City:'],"
892 " ['state', 'State:'],"
893 " ['zip', 'ZIP code:'],"
894 " ['country', 'Country:'],"
895 " ['phone', 'Phone number:'],"
898 " for (var i = 0; i < elements.length; i++) {"
899 " var name = elements[i][0];"
900 " var label = elements[i][1];"
901 " AddElement(name, label);"
906 // Dynamically construct the form.
907 ASSERT_TRUE(content::ExecuteScript(GetRenderViewHost(), "BuildForm();"));
913 // Test that form filling works after reloading the current page.
914 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, AutofillAfterReload
) {
917 // Load the test page.
918 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
919 GURL(std::string(kDataURIPrefix
) + kTestFormString
)));
922 content::WebContents
* web_contents
= GetWebContents();
923 web_contents
->GetController().Reload(false);
924 content::WaitForLoadStop(web_contents
);
930 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, AutofillAfterTranslate
) {
933 GURL
url(std::string(kDataURIPrefix
) +
934 "<form action=\"http://www.example.com/\" method=\"POST\">"
935 "<label for=\"fn\">なまえ</label>"
936 " <input type=\"text\" id=\"fn\""
937 " onfocus=\"domAutomationController.send(true)\""
939 "<label for=\"ln\">みょうじ</label>"
940 " <input type=\"text\" id=\"ln\"><br>"
941 "<label for=\"a1\">Address line 1:</label>"
942 " <input type=\"text\" id=\"a1\"><br>"
943 "<label for=\"a2\">Address line 2:</label>"
944 " <input type=\"text\" id=\"a2\"><br>"
945 "<label for=\"ci\">City:</label>"
946 " <input type=\"text\" id=\"ci\"><br>"
947 "<label for=\"st\">State:</label>"
948 " <select id=\"st\">"
949 " <option value=\"\" selected=\"yes\">--</option>"
950 " <option value=\"CA\">California</option>"
951 " <option value=\"TX\">Texas</option>"
953 "<label for=\"z\">ZIP code:</label>"
954 " <input type=\"text\" id=\"z\"><br>"
955 "<label for=\"co\">Country:</label>"
956 " <select id=\"co\">"
957 " <option value=\"\" selected=\"yes\">--</option>"
958 " <option value=\"CA\">Canada</option>"
959 " <option value=\"US\">United States</option>"
961 "<label for=\"ph\">Phone number:</label>"
962 " <input type=\"text\" id=\"ph\"><br>"
964 // Add additional Japanese characters to ensure the translate bar
966 "我々は重要な、興味深いものになるが、時折状況が発生するため苦労や痛みは"
967 "彼にいくつかの素晴らしいを調達することができます。それから、いくつかの利");
969 content::WindowedNotificationObserver
infobar_observer(
970 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED
,
971 content::NotificationService::AllSources());
972 ASSERT_NO_FATAL_FAILURE(
973 ui_test_utils::NavigateToURL(browser(), url
));
975 // Wait for the translation bar to appear and get it.
976 infobar_observer
.Wait();
977 InfoBarService
* infobar_service
=
978 InfoBarService::FromWebContents(GetWebContents());
979 TranslateInfoBarDelegate
* delegate
=
980 infobar_service
->infobar_at(0)->delegate()->AsTranslateInfoBarDelegate();
981 ASSERT_TRUE(delegate
);
982 EXPECT_EQ(translate::TRANSLATE_STEP_BEFORE_TRANSLATE
,
983 delegate
->translate_step());
985 // Simulate translation button press.
986 delegate
->Translate();
988 content::WindowedNotificationObserver
translation_observer(
989 chrome::NOTIFICATION_PAGE_TRANSLATED
,
990 content::NotificationService::AllSources());
992 // Simulate the translate script being retrieved.
993 // Pass fake google.translate lib as the translate script.
994 SimulateURLFetch(true);
996 // Simulate the render notifying the translation has been done.
997 translation_observer
.Wait();
1002 // Test phone fields parse correctly from a given profile.
1003 // The high level key presses execute the following: Select the first text
1004 // field, invoke the autofill popup list, select the first profile within the
1005 // list, and commit to the profile to populate the form.
1006 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, ComparePhoneNumbers
) {
1007 ASSERT_TRUE(test_server()->Start());
1009 AutofillProfile profile
;
1010 profile
.SetRawInfo(NAME_FIRST
, ASCIIToUTF16("Bob"));
1011 profile
.SetRawInfo(NAME_LAST
, ASCIIToUTF16("Smith"));
1012 profile
.SetRawInfo(ADDRESS_HOME_LINE1
, ASCIIToUTF16("1234 H St."));
1013 profile
.SetRawInfo(ADDRESS_HOME_CITY
, ASCIIToUTF16("San Jose"));
1014 profile
.SetRawInfo(ADDRESS_HOME_STATE
, ASCIIToUTF16("CA"));
1015 profile
.SetRawInfo(ADDRESS_HOME_ZIP
, ASCIIToUTF16("95110"));
1016 profile
.SetRawInfo(PHONE_HOME_WHOLE_NUMBER
, ASCIIToUTF16("1-408-555-4567"));
1017 SetProfile(profile
);
1019 GURL url
= test_server()->GetURL("files/autofill/form_phones.html");
1020 ui_test_utils::NavigateToURL(browser(), url
);
1021 PopulateForm("NAME_FIRST");
1023 ExpectFieldValue("NAME_FIRST", "Bob");
1024 ExpectFieldValue("NAME_LAST", "Smith");
1025 ExpectFieldValue("ADDRESS_HOME_LINE1", "1234 H St.");
1026 ExpectFieldValue("ADDRESS_HOME_CITY", "San Jose");
1027 ExpectFieldValue("ADDRESS_HOME_STATE", "CA");
1028 ExpectFieldValue("ADDRESS_HOME_ZIP", "95110");
1029 ExpectFieldValue("PHONE_HOME_WHOLE_NUMBER", "14085554567");
1030 ExpectFieldValue("PHONE_HOME_CITY_CODE-1", "408");
1031 ExpectFieldValue("PHONE_HOME_CITY_CODE-2", "408");
1032 ExpectFieldValue("PHONE_HOME_NUMBER", "5554567");
1033 ExpectFieldValue("PHONE_HOME_NUMBER_3-1", "555");
1034 ExpectFieldValue("PHONE_HOME_NUMBER_3-2", "555");
1035 ExpectFieldValue("PHONE_HOME_NUMBER_4-1", "4567");
1036 ExpectFieldValue("PHONE_HOME_NUMBER_4-2", "4567");
1037 ExpectFieldValue("PHONE_HOME_EXT-1", std::string());
1038 ExpectFieldValue("PHONE_HOME_EXT-2", std::string());
1039 ExpectFieldValue("PHONE_HOME_COUNTRY_CODE-1", "1");
1042 // Test that Autofill does not fill in read-only fields.
1043 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, NoAutofillForReadOnlyFields
) {
1044 ASSERT_TRUE(test_server()->Start());
1046 std::string
addr_line1("1234 H St.");
1048 AutofillProfile profile
;
1049 profile
.SetRawInfo(NAME_FIRST
, ASCIIToUTF16("Bob"));
1050 profile
.SetRawInfo(NAME_LAST
, ASCIIToUTF16("Smith"));
1051 profile
.SetRawInfo(EMAIL_ADDRESS
, ASCIIToUTF16("bsmith@gmail.com"));
1052 profile
.SetRawInfo(ADDRESS_HOME_LINE1
, ASCIIToUTF16(addr_line1
));
1053 profile
.SetRawInfo(ADDRESS_HOME_CITY
, ASCIIToUTF16("San Jose"));
1054 profile
.SetRawInfo(ADDRESS_HOME_STATE
, ASCIIToUTF16("CA"));
1055 profile
.SetRawInfo(ADDRESS_HOME_ZIP
, ASCIIToUTF16("95110"));
1056 profile
.SetRawInfo(COMPANY_NAME
, ASCIIToUTF16("Company X"));
1057 profile
.SetRawInfo(PHONE_HOME_WHOLE_NUMBER
, ASCIIToUTF16("408-871-4567"));
1058 SetProfile(profile
);
1060 GURL url
= test_server()->GetURL("files/autofill/read_only_field_test.html");
1061 ui_test_utils::NavigateToURL(browser(), url
);
1062 PopulateForm("firstname");
1064 ExpectFieldValue("email", std::string());
1065 ExpectFieldValue("address", addr_line1
);
1068 // Test form is fillable from a profile after form was reset.
1070 // 1. Fill form using a saved profile.
1071 // 2. Reset the form.
1072 // 3. Fill form using a saved profile.
1073 // Flakily times out: http://crbug.com/270341
1074 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
, DISABLED_FormFillableOnReset
) {
1075 ASSERT_TRUE(test_server()->Start());
1077 CreateTestProfile();
1079 GURL url
= test_server()->GetURL("files/autofill/autofill_test_form.html");
1080 ui_test_utils::NavigateToURL(browser(), url
);
1081 PopulateForm("NAME_FIRST");
1083 ASSERT_TRUE(content::ExecuteScript(
1084 GetWebContents(), "document.getElementById('testform').reset()"));
1086 PopulateForm("NAME_FIRST");
1088 ExpectFieldValue("NAME_FIRST", "Milton");
1089 ExpectFieldValue("NAME_LAST", "Waddams");
1090 ExpectFieldValue("EMAIL_ADDRESS", "red.swingline@initech.com");
1091 ExpectFieldValue("ADDRESS_HOME_LINE1", "4120 Freidrich Lane");
1092 ExpectFieldValue("ADDRESS_HOME_CITY", "Austin");
1093 ExpectFieldValue("ADDRESS_HOME_STATE", "Texas");
1094 ExpectFieldValue("ADDRESS_HOME_ZIP", "78744");
1095 ExpectFieldValue("ADDRESS_HOME_COUNTRY", "United States");
1096 ExpectFieldValue("PHONE_HOME_WHOLE_NUMBER", "5125551234");
1099 // Test Autofill distinguishes a middle initial in a name.
1100 // Flakily times out: http://crbug.com/270341
1101 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
,
1102 DISABLED_DistinguishMiddleInitialWithinName
) {
1103 ASSERT_TRUE(test_server()->Start());
1105 CreateTestProfile();
1107 GURL url
= test_server()->GetURL(
1108 "files/autofill/autofill_middleinit_form.html");
1109 ui_test_utils::NavigateToURL(browser(), url
);
1110 PopulateForm("NAME_FIRST");
1112 ExpectFieldValue("NAME_MIDDLE", "C");
1115 // Test forms with multiple email addresses are filled properly.
1116 // Entire form should be filled with one user gesture.
1117 // Flakily times out: http://crbug.com/270341
1118 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
,
1119 DISABLED_MultipleEmailFilledByOneUserGesture
) {
1120 ASSERT_TRUE(test_server()->Start());
1122 std::string
email("bsmith@gmail.com");
1124 AutofillProfile profile
;
1125 profile
.SetRawInfo(NAME_FIRST
, ASCIIToUTF16("Bob"));
1126 profile
.SetRawInfo(NAME_LAST
, ASCIIToUTF16("Smith"));
1127 profile
.SetRawInfo(EMAIL_ADDRESS
, ASCIIToUTF16(email
));
1128 profile
.SetRawInfo(PHONE_HOME_WHOLE_NUMBER
, ASCIIToUTF16("4088714567"));
1129 SetProfile(profile
);
1131 GURL url
= test_server()->GetURL(
1132 "files/autofill/autofill_confirmemail_form.html");
1133 ui_test_utils::NavigateToURL(browser(), url
);
1134 PopulateForm("NAME_FIRST");
1136 ExpectFieldValue("EMAIL_CONFIRM", email
);
1137 // TODO(isherman): verify entire form.
1140 // http://crbug.com/281527
1141 #if defined(OS_MACOSX)
1142 #define MAYBE_FormFillLatencyAfterSubmit FormFillLatencyAfterSubmit
1144 #define MAYBE_FormFillLatencyAfterSubmit DISABLED_FormFillLatencyAfterSubmit
1146 // Test latency time on form submit with lots of stored Autofill profiles.
1147 // This test verifies when a profile is selected from the Autofill dictionary
1148 // that consists of thousands of profiles, the form does not hang after being
1150 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
,
1151 MAYBE_FormFillLatencyAfterSubmit
) {
1152 ASSERT_TRUE(test_server()->Start());
1154 std::vector
<std::string
> cities
;
1155 cities
.push_back("San Jose");
1156 cities
.push_back("San Francisco");
1157 cities
.push_back("Sacramento");
1158 cities
.push_back("Los Angeles");
1160 std::vector
<std::string
> streets
;
1161 streets
.push_back("St");
1162 streets
.push_back("Ave");
1163 streets
.push_back("Ln");
1164 streets
.push_back("Ct");
1166 const int kNumProfiles
= 1500;
1167 base::Time start_time
= base::Time::Now();
1168 std::vector
<AutofillProfile
> profiles
;
1169 for (int i
= 0; i
< kNumProfiles
; i
++) {
1170 AutofillProfile profile
;
1171 base::string16
name(base::IntToString16(i
));
1172 base::string16
email(name
+ ASCIIToUTF16("@example.com"));
1173 base::string16 street
= ASCIIToUTF16(
1174 base::IntToString(base::RandInt(0, 10000)) + " " +
1175 streets
[base::RandInt(0, streets
.size() - 1)]);
1176 base::string16 city
=
1177 ASCIIToUTF16(cities
[base::RandInt(0, cities
.size() - 1)]);
1178 base::string16
zip(base::IntToString16(base::RandInt(0, 10000)));
1179 profile
.SetRawInfo(NAME_FIRST
, name
);
1180 profile
.SetRawInfo(EMAIL_ADDRESS
, email
);
1181 profile
.SetRawInfo(ADDRESS_HOME_LINE1
, street
);
1182 profile
.SetRawInfo(ADDRESS_HOME_CITY
, city
);
1183 profile
.SetRawInfo(ADDRESS_HOME_STATE
, ASCIIToUTF16("CA"));
1184 profile
.SetRawInfo(ADDRESS_HOME_ZIP
, zip
);
1185 profile
.SetRawInfo(ADDRESS_HOME_COUNTRY
, ASCIIToUTF16("US"));
1186 profiles
.push_back(profile
);
1188 SetProfiles(&profiles
);
1189 // TODO(isherman): once we're sure this test doesn't timeout on any bots, this
1191 LOG(INFO
) << "Created " << kNumProfiles
<< " profiles in " <<
1192 (base::Time::Now() - start_time
).InSeconds() << " seconds.";
1194 GURL url
= test_server()->GetURL(
1195 "files/autofill/latency_after_submit_test.html");
1196 ui_test_utils::NavigateToURL(browser(), url
);
1197 PopulateForm("NAME_FIRST");
1199 content::WindowedNotificationObserver
load_stop_observer(
1200 content::NOTIFICATION_LOAD_STOP
,
1201 content::Source
<content::NavigationController
>(
1202 &GetWebContents()->GetController()));
1204 ASSERT_TRUE(content::ExecuteScript(
1205 GetRenderViewHost(),
1206 "document.getElementById('testform').submit();"));
1207 // This will ensure the test didn't hang.
1208 load_stop_observer
.Wait();
1211 // Test that Chrome doesn't crash when autocomplete is disabled while the user
1212 // is interacting with the form. This is a regression test for
1213 // http://crbug.com/160476
1214 IN_PROC_BROWSER_TEST_F(AutofillInteractiveTest
,
1215 DisableAutocompleteWhileFilling
) {
1216 CreateTestProfile();
1218 // Load the test page.
1219 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
1220 GURL(std::string(kDataURIPrefix
) + kTestFormString
)));
1222 // Invoke Autofill: Start filling the first name field with "M" and wait for
1223 // the popup to be shown.
1224 FocusFirstNameField();
1225 SendKeyToPageAndWait(ui::VKEY_M
);
1227 // Now that the popup with suggestions is showing, disable autocomplete for
1228 // the active field.
1229 ASSERT_TRUE(content::ExecuteScript(
1230 GetRenderViewHost(),
1231 "document.querySelector('input').autocomplete = 'off';"));
1233 // Press the down arrow to select the suggestion and attempt to preview the
1235 SendKeyToPopupAndWait(ui::VKEY_DOWN
);
1238 } // namespace autofill