Reland "Non-SFI mode: Switch to newlib. (patchset #4 id:60001 of https://codereview...
[chromium-blink-merge.git] / chrome / renderer / autofill / password_autofill_agent_browsertest.cc
blobe0168719de66f2f64ddae2e2f636d6e894ecfc27
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.
5 #include "base/strings/string_util.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/renderer/autofill/password_generation_test_utils.h"
8 #include "chrome/test/base/chrome_render_view_test.h"
9 #include "components/autofill/content/common/autofill_messages.h"
10 #include "components/autofill/content/renderer/autofill_agent.h"
11 #include "components/autofill/content/renderer/form_autofill_util.h"
12 #include "components/autofill/content/renderer/password_autofill_agent.h"
13 #include "components/autofill/content/renderer/test_password_autofill_agent.h"
14 #include "components/autofill/content/renderer/test_password_generation_agent.h"
15 #include "components/autofill/core/common/autofill_constants.h"
16 #include "components/autofill/core/common/autofill_switches.h"
17 #include "components/autofill/core/common/form_data.h"
18 #include "components/autofill/core/common/form_field_data.h"
19 #include "components/autofill/core/common/password_form_field_prediction_map.h"
20 #include "content/public/renderer/render_frame.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/WebKit/public/platform/WebString.h"
23 #include "third_party/WebKit/public/platform/WebVector.h"
24 #include "third_party/WebKit/public/web/WebDocument.h"
25 #include "third_party/WebKit/public/web/WebElement.h"
26 #include "third_party/WebKit/public/web/WebFormControlElement.h"
27 #include "third_party/WebKit/public/web/WebFormElement.h"
28 #include "third_party/WebKit/public/web/WebInputElement.h"
29 #include "third_party/WebKit/public/web/WebLocalFrame.h"
30 #include "third_party/WebKit/public/web/WebNode.h"
31 #include "third_party/WebKit/public/web/WebView.h"
32 #include "ui/events/keycodes/keyboard_codes.h"
34 using autofill::PasswordForm;
35 using base::ASCIIToUTF16;
36 using base::UTF16ToUTF8;
37 using blink::WebDocument;
38 using blink::WebElement;
39 using blink::WebFrame;
40 using blink::WebInputElement;
41 using blink::WebString;
42 using blink::WebView;
44 namespace {
46 const int kPasswordFillFormDataId = 1234;
48 // The name of the username/password element in the form.
49 const char kUsernameName[] = "username";
50 const char kPasswordName[] = "password";
51 const char kEmailName[] = "email";
53 const char kAliceUsername[] = "alice";
54 const char kAlicePassword[] = "password";
55 const char kBobUsername[] = "bob";
56 const char kBobPassword[] = "secret";
57 const char kCarolUsername[] = "Carol";
58 const char kCarolPassword[] = "test";
59 const char kCarolAlternateUsername[] = "RealCarolUsername";
61 const char kFormHTML[] =
62 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
63 " <INPUT type='text' id='random_field'/>"
64 " <INPUT type='text' id='username'/>"
65 " <INPUT type='password' id='password'/>"
66 " <INPUT type='submit' value='Login'/>"
67 "</FORM>";
69 const char kVisibleFormWithNoUsernameHTML[] =
70 "<head> <style> form {display: inline;} </style> </head>"
71 "<body>"
72 " <form name='LoginTestForm' action='http://www.bidule.com'>"
73 " <div>"
74 " <input type='password' id='password'/>"
75 " </div>"
76 " </form>"
77 "</body>";
79 const char kEmptyFormHTML[] =
80 "<head> <style> form {display: inline;} </style> </head>"
81 "<body> <form> </form> </body>";
83 const char kNonVisibleFormHTML[] =
84 "<head> <style> form {display: none;} </style> </head>"
85 "<body>"
86 " <form>"
87 " <div>"
88 " <input type='password' id='password'/>"
89 " </div>"
90 " </form>"
91 "</body>";
93 const char kSignupFormHTML[] =
94 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
95 " <INPUT type='text' id='random_info'/>"
96 " <INPUT type='password' id='new_password'/>"
97 " <INPUT type='password' id='confirm_password'/>"
98 " <INPUT type='submit' value='Login'/>"
99 "</FORM>";
101 const char kEmptyWebpage[] =
102 "<html>"
103 " <head>"
104 " </head>"
105 " <body>"
106 " </body>"
107 "</html>";
109 const char kRedirectionWebpage[] =
110 "<html>"
111 " <head>"
112 " <meta http-equiv='Content-Type' content='text/html'>"
113 " <title>Redirection page</title>"
114 " <script></script>"
115 " </head>"
116 " <body>"
117 " <script type='text/javascript'>"
118 " function test(){}"
119 " </script>"
120 " </body>"
121 "</html>";
123 const char kSimpleWebpage[] =
124 "<html>"
125 " <head>"
126 " <meta charset='utf-8' />"
127 " <title>Title</title>"
128 " </head>"
129 " <body>"
130 " <form name='LoginTestForm'>"
131 " <input type='text' id='username'/>"
132 " <input type='password' id='password'/>"
133 " <input type='submit' value='Login'/>"
134 " </form>"
135 " </body>"
136 "</html>";
138 const char kWebpageWithDynamicContent[] =
139 "<html>"
140 " <head>"
141 " <meta charset='utf-8' />"
142 " <title>Title</title>"
143 " </head>"
144 " <body>"
145 " <script type='text/javascript'>"
146 " function addParagraph() {"
147 " var p = document.createElement('p');"
148 " document.body.appendChild(p);"
149 " }"
150 " window.onload = addParagraph;"
151 " </script>"
152 " </body>"
153 "</html>";
155 const char kJavaScriptClick[] =
156 "var event = new MouseEvent('click', {"
157 " 'view': window,"
158 " 'bubbles': true,"
159 " 'cancelable': true"
160 "});"
161 "var form = document.getElementById('myform1');"
162 "form.dispatchEvent(event);"
163 "console.log('clicked!');";
165 const char kOnChangeDetectionScript[] =
166 "<script>"
167 " usernameOnchangeCalled = false;"
168 " passwordOnchangeCalled = false;"
169 " document.getElementById('username').onchange = function() {"
170 " usernameOnchangeCalled = true;"
171 " };"
172 " document.getElementById('password').onchange = function() {"
173 " passwordOnchangeCalled = true;"
174 " };"
175 "</script>";
177 const char kFormHTMLWithTwoTextFields[] =
178 "<FORM name='LoginTestForm' id='LoginTestForm' "
179 "action='http://www.bidule.com'>"
180 " <INPUT type='text' id='username'/>"
181 " <INPUT type='text' id='email'/>"
182 " <INPUT type='password' id='password'/>"
183 " <INPUT type='submit' value='Login'/>"
184 "</FORM>";
186 const char kPasswordChangeFormHTML[] =
187 "<FORM name='ChangeWithUsernameForm' action='http://www.bidule.com'>"
188 " <INPUT type='text' id='username'/>"
189 " <INPUT type='password' id='password'/>"
190 " <INPUT type='password' id='newpassword'/>"
191 " <INPUT type='password' id='confirmpassword'/>"
192 " <INPUT type='submit' value='Login'/>"
193 "</FORM>";
195 // Sets the "readonly" attribute of |element| to the value given by |read_only|.
196 void SetElementReadOnly(WebInputElement& element, bool read_only) {
197 element.setAttribute(WebString::fromUTF8("readonly"),
198 read_only ? WebString::fromUTF8("true") : WebString());
201 } // namespace
203 namespace autofill {
205 class PasswordAutofillAgentTest : public ChromeRenderViewTest {
206 public:
207 PasswordAutofillAgentTest() {
210 // Simulates the fill password form message being sent to the renderer.
211 // We use that so we don't have to make RenderView::OnFillPasswordForm()
212 // protected.
213 void SimulateOnFillPasswordForm(
214 const PasswordFormFillData& fill_data) {
215 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data);
216 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
217 ->OnMessageReceived(msg);
220 // As above, but fills for an iframe.
221 void SimulateOnFillPasswordFormForFrame(
222 WebFrame* frame,
223 const PasswordFormFillData& fill_data) {
224 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data);
225 content::RenderFrame::FromWebFrame(frame)->OnMessageReceived(msg);
228 void SendVisiblePasswordForms() {
229 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
230 ->DidFinishLoad();
233 void SetUp() override {
234 ChromeRenderViewTest::SetUp();
236 // Add a preferred login and an additional login to the FillData.
237 username1_ = ASCIIToUTF16(kAliceUsername);
238 password1_ = ASCIIToUTF16(kAlicePassword);
239 username2_ = ASCIIToUTF16(kBobUsername);
240 password2_ = ASCIIToUTF16(kBobPassword);
241 username3_ = ASCIIToUTF16(kCarolUsername);
242 password3_ = ASCIIToUTF16(kCarolPassword);
243 alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
245 FormFieldData username_field;
246 username_field.name = ASCIIToUTF16(kUsernameName);
247 username_field.value = username1_;
248 fill_data_.username_field = username_field;
250 FormFieldData password_field;
251 password_field.name = ASCIIToUTF16(kPasswordName);
252 password_field.value = password1_;
253 password_field.form_control_type = "password";
254 fill_data_.password_field = password_field;
256 PasswordAndRealm password2;
257 password2.password = password2_;
258 fill_data_.additional_logins[username2_] = password2;
259 PasswordAndRealm password3;
260 password3.password = password3_;
261 fill_data_.additional_logins[username3_] = password3;
263 UsernamesCollectionKey key;
264 key.username = username3_;
265 key.password = password3_;
266 key.realm = "google.com";
267 fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
269 // We need to set the origin so it matches the frame URL and the action so
270 // it matches the form action, otherwise we won't autocomplete.
271 UpdateOriginForHTML(kFormHTML);
272 fill_data_.action = GURL("http://www.bidule.com");
274 LoadHTML(kFormHTML);
276 // Necessary for SimulateElementClick() to work correctly.
277 GetWebWidget()->resize(blink::WebSize(500, 500));
278 GetWebWidget()->setFocus(true);
280 // Now retrieve the input elements so the test can access them.
281 UpdateUsernameAndPasswordElements();
284 void TearDown() override {
285 username_element_.reset();
286 password_element_.reset();
287 ChromeRenderViewTest::TearDown();
290 void UpdateOriginForHTML(const std::string& html) {
291 std::string origin = "data:text/html;charset=utf-8," + html;
292 fill_data_.origin = GURL(origin);
295 void UpdateUsernameAndPasswordElements() {
296 WebDocument document = GetMainFrame()->document();
297 WebElement element =
298 document.getElementById(WebString::fromUTF8(kUsernameName));
299 ASSERT_FALSE(element.isNull());
300 username_element_ = element.to<blink::WebInputElement>();
301 element = document.getElementById(WebString::fromUTF8(kPasswordName));
302 ASSERT_FALSE(element.isNull());
303 password_element_ = element.to<blink::WebInputElement>();
306 blink::WebInputElement GetInputElementByID(const std::string& id) {
307 WebDocument document = GetMainFrame()->document();
308 WebElement element =
309 document.getElementById(WebString::fromUTF8(id.c_str()));
310 return element.to<blink::WebInputElement>();
313 void ClearUsernameAndPasswordFields() {
314 username_element_.setValue("");
315 username_element_.setAutofilled(false);
316 password_element_.setValue("");
317 password_element_.setAutofilled(false);
320 void SimulateDidEndEditing(WebFrame* input_frame, WebInputElement& input) {
321 static_cast<blink::WebAutofillClient*>(autofill_agent_)
322 ->textFieldDidEndEditing(input);
325 void SimulateSuggestionChoice(WebInputElement& username_input) {
326 base::string16 username(base::ASCIIToUTF16(kAliceUsername));
327 base::string16 password(base::ASCIIToUTF16(kAlicePassword));
328 SimulateSuggestionChoiceOfUsernameAndPassword(username_input, username,
329 password);
332 void SimulateSuggestionChoiceOfUsernameAndPassword(
333 WebInputElement& input,
334 const base::string16& username,
335 const base::string16& password) {
336 // This call is necessary to setup the autofill agent appropriate for the
337 // user selection; simulates the menu actually popping up.
338 render_thread_->sink().ClearMessages();
339 static_cast<autofill::PageClickListener*>(autofill_agent_)
340 ->FormControlElementClicked(input, false);
342 AutofillMsg_FillPasswordSuggestion msg(0, username, password);
343 static_cast<content::RenderFrameObserver*>(autofill_agent_)
344 ->OnMessageReceived(msg);
347 void SimulateUsernameChange(const std::string& username) {
348 SimulateUserInputChangeForElement(&username_element_, username);
351 void SimulatePasswordChange(const std::string& password) {
352 SimulateUserInputChangeForElement(&password_element_, password);
355 void CheckTextFieldsStateForElements(const WebInputElement& username_element,
356 const std::string& username,
357 bool username_autofilled,
358 const WebInputElement& password_element,
359 const std::string& password,
360 bool password_autofilled,
361 bool checkSuggestedValue) {
362 EXPECT_EQ(username,
363 static_cast<std::string>(username_element.value().utf8()));
364 EXPECT_EQ(username_autofilled, username_element.isAutofilled());
365 EXPECT_EQ(password,
366 static_cast<std::string>(
367 checkSuggestedValue ? password_element.suggestedValue().utf8()
368 : password_element.value().utf8()))
369 << "checkSuggestedValue == " << checkSuggestedValue;
370 EXPECT_EQ(password_autofilled, password_element.isAutofilled());
373 // Checks the DOM-accessible value of the username element and the
374 // *suggested* value of the password element.
375 void CheckTextFieldsState(const std::string& username,
376 bool username_autofilled,
377 const std::string& password,
378 bool password_autofilled) {
379 CheckTextFieldsStateForElements(username_element_,
380 username,
381 username_autofilled,
382 password_element_,
383 password,
384 password_autofilled,
385 true);
388 // Checks the DOM-accessible value of the username element and the
389 // DOM-accessible value of the password element.
390 void CheckTextFieldsDOMState(const std::string& username,
391 bool username_autofilled,
392 const std::string& password,
393 bool password_autofilled) {
394 CheckTextFieldsStateForElements(username_element_,
395 username,
396 username_autofilled,
397 password_element_,
398 password,
399 password_autofilled,
400 false);
403 void CheckUsernameSelection(int start, int end) {
404 EXPECT_EQ(start, username_element_.selectionStart());
405 EXPECT_EQ(end, username_element_.selectionEnd());
408 // Checks the message sent to PasswordAutofillManager to build the suggestion
409 // list. |username| is the expected username field value, and |show_all| is
410 // the expected flag for the PasswordAutofillManager, whether to show all
411 // suggestions, or only those starting with |username|.
412 void CheckSuggestions(const std::string& username, bool show_all) {
413 const IPC::Message* message =
414 render_thread_->sink().GetFirstMessageMatching(
415 AutofillHostMsg_ShowPasswordSuggestions::ID);
416 EXPECT_TRUE(message);
417 base::Tuple<int, base::i18n::TextDirection, base::string16, int, gfx::RectF>
418 args;
419 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
420 EXPECT_EQ(kPasswordFillFormDataId, base::get<0>(args));
421 EXPECT_EQ(ASCIIToUTF16(username), base::get<2>(args));
422 EXPECT_EQ(show_all,
423 static_cast<bool>(base::get<3>(args) & autofill::SHOW_ALL));
425 render_thread_->sink().ClearMessages();
428 void ExpectFormSubmittedWithUsernameAndPasswords(
429 const std::string& username_value,
430 const std::string& password_value,
431 const std::string& new_password_value) {
432 const IPC::Message* message =
433 render_thread_->sink().GetFirstMessageMatching(
434 AutofillHostMsg_PasswordFormSubmitted::ID);
435 ASSERT_TRUE(message);
436 base::Tuple<autofill::PasswordForm> args;
437 AutofillHostMsg_PasswordFormSubmitted::Read(message, &args);
438 EXPECT_EQ(ASCIIToUTF16(username_value), base::get<0>(args).username_value);
439 EXPECT_EQ(ASCIIToUTF16(password_value), base::get<0>(args).password_value);
440 EXPECT_EQ(ASCIIToUTF16(new_password_value),
441 base::get<0>(args).new_password_value);
444 base::string16 username1_;
445 base::string16 username2_;
446 base::string16 username3_;
447 base::string16 password1_;
448 base::string16 password2_;
449 base::string16 password3_;
450 base::string16 alternate_username3_;
451 PasswordFormFillData fill_data_;
453 WebInputElement username_element_;
454 WebInputElement password_element_;
456 private:
457 DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
460 // Tests that the password login is autocompleted as expected when the browser
461 // sends back the password info.
462 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
464 * Right now we are not sending the message to the browser because we are
465 * loading a data URL and the security origin canAccessPasswordManager()
466 * returns false. May be we should mock URL loading to cirmcuvent this?
467 TODO(jcivelli): find a way to make the security origin not deny access to the
468 password manager and then reenable this code.
470 // The form has been loaded, we should have sent the browser a message about
471 // the form.
472 const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
473 AutofillHostMsg_PasswordFormsParsed::ID);
474 ASSERT_TRUE(msg != NULL);
476 base::Tuple1<std::vector<PasswordForm> > forms;
477 AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
478 ASSERT_EQ(1U, forms.a.size());
479 PasswordForm password_form = forms.a[0];
480 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
481 EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
482 EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
485 // Simulate the browser sending back the login info, it triggers the
486 // autocomplete.
487 SimulateOnFillPasswordForm(fill_data_);
489 // The username and password should have been autocompleted.
490 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
493 // Tests that we correctly fill forms having an empty 'action' attribute.
494 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
495 const char kEmptyActionFormHTML[] =
496 "<FORM name='LoginTestForm'>"
497 " <INPUT type='text' id='username'/>"
498 " <INPUT type='password' id='password'/>"
499 " <INPUT type='submit' value='Login'/>"
500 "</FORM>";
501 LoadHTML(kEmptyActionFormHTML);
503 // Retrieve the input elements so the test can access them.
504 WebDocument document = GetMainFrame()->document();
505 WebElement element =
506 document.getElementById(WebString::fromUTF8(kUsernameName));
507 ASSERT_FALSE(element.isNull());
508 username_element_ = element.to<blink::WebInputElement>();
509 element = document.getElementById(WebString::fromUTF8(kPasswordName));
510 ASSERT_FALSE(element.isNull());
511 password_element_ = element.to<blink::WebInputElement>();
513 // Set the expected form origin and action URLs.
514 UpdateOriginForHTML(kEmptyActionFormHTML);
515 fill_data_.action = fill_data_.origin;
517 // Simulate the browser sending back the login info, it triggers the
518 // autocomplete.
519 SimulateOnFillPasswordForm(fill_data_);
521 // The username and password should have been autocompleted.
522 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
525 // Tests that if a password is marked as readonly, neither field is autofilled
526 // on page load.
527 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
528 SetElementReadOnly(password_element_, true);
530 // Simulate the browser sending back the login info, it triggers the
531 // autocomplete.
532 SimulateOnFillPasswordForm(fill_data_);
534 CheckTextFieldsState(std::string(), false, std::string(), false);
537 // Can still fill a password field if the username is set to a value that
538 // matches.
539 TEST_F(PasswordAutofillAgentTest,
540 AutocompletePasswordForReadonlyUsernameMatched) {
541 username_element_.setValue(username3_);
542 SetElementReadOnly(username_element_, true);
544 // Filled even though username is not the preferred match.
545 SimulateOnFillPasswordForm(fill_data_);
546 CheckTextFieldsState(UTF16ToUTF8(username3_), false,
547 UTF16ToUTF8(password3_), true);
550 // If a username field is empty and readonly, don't autofill.
551 TEST_F(PasswordAutofillAgentTest,
552 NoAutocompletePasswordForReadonlyUsernameUnmatched) {
553 username_element_.setValue(WebString::fromUTF8(""));
554 SetElementReadOnly(username_element_, true);
556 SimulateOnFillPasswordForm(fill_data_);
557 CheckTextFieldsState(std::string(), false, std::string(), false);
560 // Tests that having a non-matching username precludes the autocomplete.
561 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
562 username_element_.setValue(WebString::fromUTF8("bogus"));
564 // Simulate the browser sending back the login info, it triggers the
565 // autocomplete.
566 SimulateOnFillPasswordForm(fill_data_);
568 // Neither field should be autocompleted.
569 CheckTextFieldsState("bogus", false, std::string(), false);
572 // Don't try to complete a prefilled value even if it's a partial match
573 // to a username.
574 TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
575 username_element_.setValue(WebString::fromUTF8("ali"));
577 SimulateOnFillPasswordForm(fill_data_);
579 CheckTextFieldsState("ali", false, std::string(), false);
582 TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
583 const char kNoFormInputs[] =
584 "<input type='text' id='username'/>"
585 "<input type='password' id='password'/>";
586 LoadHTML(kNoFormInputs);
588 SimulateOnFillPasswordForm(fill_data_);
590 // Input elements that aren't in a <form> won't autofill.
591 CheckTextFieldsState(std::string(), false, std::string(), false);
594 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
595 const char kTextFieldPasswordFormHTML[] =
596 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
597 " <INPUT type='text' id='username'/>"
598 " <INPUT type='text' id='password'/>"
599 " <INPUT type='submit' value='Login'/>"
600 "</FORM>";
601 LoadHTML(kTextFieldPasswordFormHTML);
603 // Retrieve the input elements so the test can access them.
604 WebDocument document = GetMainFrame()->document();
605 WebElement element =
606 document.getElementById(WebString::fromUTF8(kUsernameName));
607 ASSERT_FALSE(element.isNull());
608 username_element_ = element.to<blink::WebInputElement>();
609 element = document.getElementById(WebString::fromUTF8(kPasswordName));
610 ASSERT_FALSE(element.isNull());
611 password_element_ = element.to<blink::WebInputElement>();
613 // Set the expected form origin URL.
614 UpdateOriginForHTML(kTextFieldPasswordFormHTML);
616 SimulateOnFillPasswordForm(fill_data_);
618 // Fields should still be empty.
619 CheckTextFieldsState(std::string(), false, std::string(), false);
622 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
623 const char kPasswordFieldUsernameFormHTML[] =
624 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
625 " <INPUT type='password' id='username'/>"
626 " <INPUT type='password' id='password'/>"
627 " <INPUT type='submit' value='Login'/>"
628 "</FORM>";
629 LoadHTML(kPasswordFieldUsernameFormHTML);
631 // Retrieve the input elements so the test can access them.
632 WebDocument document = GetMainFrame()->document();
633 WebElement element =
634 document.getElementById(WebString::fromUTF8(kUsernameName));
635 ASSERT_FALSE(element.isNull());
636 username_element_ = element.to<blink::WebInputElement>();
637 element = document.getElementById(WebString::fromUTF8(kPasswordName));
638 ASSERT_FALSE(element.isNull());
639 password_element_ = element.to<blink::WebInputElement>();
641 // Set the expected form origin URL.
642 UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
644 SimulateOnFillPasswordForm(fill_data_);
646 // Fields should still be empty.
647 CheckTextFieldsState(std::string(), false, std::string(), false);
650 // Tests that having a matching username does not preclude the autocomplete.
651 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
652 username_element_.setValue(WebString::fromUTF8(kAliceUsername));
654 // Simulate the browser sending back the login info, it triggers the
655 // autocomplete.
656 SimulateOnFillPasswordForm(fill_data_);
658 // The username and password should have been autocompleted.
659 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
662 // Tests that editing the password clears the autocompleted password field.
663 TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
664 // Simulate the browser sending back the login info, it triggers the
665 // autocomplete.
666 SimulateOnFillPasswordForm(fill_data_);
668 // Simulate the user changing the username to some unknown username.
669 SimulateUsernameChange("alicia");
671 // The password should have been cleared.
672 CheckTextFieldsState("alicia", false, std::string(), false);
675 // Tests that we only autocomplete on focus lost and with a full username match
676 // when |wait_for_username| is true.
677 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
678 // Simulate the browser sending back the login info.
679 fill_data_.wait_for_username = true;
680 SimulateOnFillPasswordForm(fill_data_);
682 // No auto-fill should have taken place.
683 CheckTextFieldsState(std::string(), false, std::string(), false);
685 // No autocomplete should happen when text is entered in the username.
686 SimulateUsernameChange("a");
687 CheckTextFieldsState("a", false, std::string(), false);
688 SimulateUsernameChange("al");
689 CheckTextFieldsState("al", false, std::string(), false);
690 SimulateUsernameChange(kAliceUsername);
691 CheckTextFieldsState(kAliceUsername, false, std::string(), false);
693 // Autocomplete should happen only when the username textfield is blurred with
694 // a full match.
695 SimulateUsernameChange("a");
696 static_cast<blink::WebAutofillClient*>(autofill_agent_)
697 ->textFieldDidEndEditing(username_element_);
698 CheckTextFieldsState("a", false, std::string(), false);
699 SimulateUsernameChange("al");
700 static_cast<blink::WebAutofillClient*>(autofill_agent_)
701 ->textFieldDidEndEditing(username_element_);
702 CheckTextFieldsState("al", false, std::string(), false);
703 SimulateUsernameChange("alices");
704 static_cast<blink::WebAutofillClient*>(autofill_agent_)
705 ->textFieldDidEndEditing(username_element_);
706 CheckTextFieldsState("alices", false, std::string(), false);
707 SimulateUsernameChange(kAliceUsername);
708 static_cast<blink::WebAutofillClient*>(autofill_agent_)
709 ->textFieldDidEndEditing(username_element_);
710 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
713 // Tests that inline autocompletion works properly.
714 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
715 // Simulate the browser sending back the login info.
716 SimulateOnFillPasswordForm(fill_data_);
718 ClearUsernameAndPasswordFields();
720 // Simulate the user typing in the first letter of 'alice', a stored
721 // username.
722 SimulateUsernameChange("a");
723 // Both the username and password text fields should reflect selection of the
724 // stored login.
725 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
726 // And the selection should have been set to 'lice', the last 4 letters.
727 CheckUsernameSelection(1, 5);
729 // Now the user types the next letter of the same username, 'l'.
730 SimulateUserTypingASCIICharacter('l', true);
731 // Now the fields should have the same value, but the selection should have a
732 // different start value.
733 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
734 CheckUsernameSelection(2, 5);
736 // Test that backspace will erase the selection and will stop autocompletion.
737 SimulateUserTypingASCIICharacter(ui::VKEY_BACK, true);
738 CheckTextFieldsState("al", false, std::string(), false);
739 CheckUsernameSelection(2, 2); // No selection.
741 // Now lets say the user goes astray from the stored username and types the
742 // letter 'f', spelling 'alf'. We don't know alf (that's just sad), so in
743 // practice the username should no longer be 'alice' and the selected range
744 // should be empty.
745 SimulateUserTypingASCIICharacter('f', true);
746 CheckTextFieldsState("alf", false, std::string(), false);
747 CheckUsernameSelection(3, 3); // No selection.
749 // Ok, so now the user removes all the text and enters the letter 'b'.
750 SimulateUsernameChange("b");
751 // The username and password fields should match the 'bob' entry.
752 CheckTextFieldsDOMState(kBobUsername, true, kBobPassword, true);
753 CheckUsernameSelection(1, 3);
755 // Then, the user again removes all the text and types an uppercase 'C'.
756 SimulateUsernameChange("C");
757 // The username and password fields should match the 'Carol' entry.
758 CheckTextFieldsDOMState(kCarolUsername, true, kCarolPassword, true);
759 CheckUsernameSelection(1, 5);
761 // The user removes all the text and types a lowercase 'c'. We only
762 // want case-sensitive autocompletion, so the username and the selected range
763 // should be empty.
764 SimulateUsernameChange("c");
765 CheckTextFieldsState("c", false, std::string(), false);
766 CheckUsernameSelection(1, 1);
768 // Check that we complete other_possible_usernames as well.
769 SimulateUsernameChange("R");
770 CheckTextFieldsDOMState(kCarolAlternateUsername, true, kCarolPassword, true);
771 CheckUsernameSelection(1, 17);
774 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
775 blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
776 blink::WebFrame* frame;
778 LoadHTML(kVisibleFormWithNoUsernameHTML);
779 frame = GetMainFrame();
780 frame->document().forms(forms1);
781 ASSERT_EQ(1u, forms1.size());
782 EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
784 LoadHTML(kEmptyFormHTML);
785 frame = GetMainFrame();
786 frame->document().forms(forms2);
787 ASSERT_EQ(1u, forms2.size());
788 EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
790 LoadHTML(kNonVisibleFormHTML);
791 frame = GetMainFrame();
792 frame->document().forms(forms3);
793 ASSERT_EQ(1u, forms3.size());
794 EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
797 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
798 render_thread_->sink().ClearMessages();
799 LoadHTML(kVisibleFormWithNoUsernameHTML);
800 const IPC::Message* message = render_thread_->sink()
801 .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
802 EXPECT_TRUE(message);
803 base::Tuple<std::vector<autofill::PasswordForm>, bool> param;
804 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
805 EXPECT_TRUE(base::get<0>(param).size());
807 render_thread_->sink().ClearMessages();
808 LoadHTML(kEmptyFormHTML);
809 message = render_thread_->sink().GetFirstMessageMatching(
810 AutofillHostMsg_PasswordFormsRendered::ID);
811 EXPECT_TRUE(message);
812 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
813 EXPECT_FALSE(base::get<0>(param).size());
815 render_thread_->sink().ClearMessages();
816 LoadHTML(kNonVisibleFormHTML);
817 message = render_thread_->sink().GetFirstMessageMatching(
818 AutofillHostMsg_PasswordFormsRendered::ID);
819 EXPECT_TRUE(message);
820 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
821 EXPECT_FALSE(base::get<0>(param).size());
824 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
825 render_thread_->sink().ClearMessages();
826 LoadHTML(kEmptyWebpage);
827 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
828 AutofillHostMsg_PasswordFormsRendered::ID));
830 render_thread_->sink().ClearMessages();
831 LoadHTML(kRedirectionWebpage);
832 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
833 AutofillHostMsg_PasswordFormsRendered::ID));
835 render_thread_->sink().ClearMessages();
836 LoadHTML(kSimpleWebpage);
837 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
838 AutofillHostMsg_PasswordFormsRendered::ID));
840 render_thread_->sink().ClearMessages();
841 LoadHTML(kWebpageWithDynamicContent);
842 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
843 AutofillHostMsg_PasswordFormsRendered::ID));
846 // Tests that a password will only be filled as a suggested and will not be
847 // accessible by the DOM until a user gesture has occurred.
848 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
849 // Trigger the initial autocomplete.
850 SimulateOnFillPasswordForm(fill_data_);
852 // The username and password should have been autocompleted.
853 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
855 // However, it should only have completed with the suggested value, as tested
856 // above, and it should not have completed into the DOM accessible value for
857 // the password field.
858 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
860 // Simulate a user click so that the password field's real value is filled.
861 SimulateElementClick(kUsernameName);
862 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
865 // Verfies that a DOM-activated UI event will not cause an autofill.
866 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
867 // Trigger the initial autocomplete.
868 SimulateOnFillPasswordForm(fill_data_);
870 ExecuteJavaScript(kJavaScriptClick);
871 CheckTextFieldsDOMState(kAliceUsername, true, "", true);
874 // Verifies that password autofill triggers onChange events in JavaScript for
875 // forms that are filled on page load.
876 TEST_F(PasswordAutofillAgentTest,
877 PasswordAutofillTriggersOnChangeEventsOnLoad) {
878 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
879 LoadHTML(html.c_str());
880 UpdateOriginForHTML(html);
881 UpdateUsernameAndPasswordElements();
883 // Simulate the browser sending back the login info, it triggers the
884 // autocomplete.
885 SimulateOnFillPasswordForm(fill_data_);
887 // The username and password should have been autocompleted...
888 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
889 // ... but since there hasn't been a user gesture yet, the autocompleted
890 // password should only be visible to the user.
891 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
893 // A JavaScript onChange event should have been triggered for the username,
894 // but not yet for the password.
895 int username_onchange_called = -1;
896 int password_onchange_called = -1;
897 ASSERT_TRUE(
898 ExecuteJavaScriptAndReturnIntValue(
899 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
900 &username_onchange_called));
901 EXPECT_EQ(1, username_onchange_called);
902 ASSERT_TRUE(
903 ExecuteJavaScriptAndReturnIntValue(
904 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
905 &password_onchange_called));
906 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
907 // EXPECT_EQ(0, password_onchange_called);
909 // Simulate a user click so that the password field's real value is filled.
910 SimulateElementClick(kUsernameName);
911 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
913 // Now, a JavaScript onChange event should have been triggered for the
914 // password as well.
915 ASSERT_TRUE(
916 ExecuteJavaScriptAndReturnIntValue(
917 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
918 &password_onchange_called));
919 EXPECT_EQ(1, password_onchange_called);
922 // Verifies that password autofill triggers onChange events in JavaScript for
923 // forms that are filled after page load.
924 TEST_F(PasswordAutofillAgentTest,
925 PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
926 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
927 LoadHTML(html.c_str());
928 UpdateOriginForHTML(html);
929 UpdateUsernameAndPasswordElements();
931 // Simulate the browser sending back the login info, it triggers the
932 // autocomplete.
933 fill_data_.wait_for_username = true;
934 SimulateOnFillPasswordForm(fill_data_);
936 // The username and password should not yet have been autocompleted.
937 CheckTextFieldsState(std::string(), false, std::string(), false);
939 // Simulate a click just to force a user gesture, since the username value is
940 // set directly.
941 SimulateElementClick(kUsernameName);
943 // Simulate the user entering the first letter of her username and selecting
944 // the matching autofill from the dropdown.
945 SimulateUsernameChange("a");
946 SimulateSuggestionChoice(username_element_);
948 // The username and password should now have been autocompleted.
949 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
951 // JavaScript onChange events should have been triggered both for the username
952 // and for the password.
953 int username_onchange_called = -1;
954 int password_onchange_called = -1;
955 ASSERT_TRUE(
956 ExecuteJavaScriptAndReturnIntValue(
957 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
958 &username_onchange_called));
959 EXPECT_EQ(1, username_onchange_called);
960 ASSERT_TRUE(
961 ExecuteJavaScriptAndReturnIntValue(
962 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
963 &password_onchange_called));
964 EXPECT_EQ(1, password_onchange_called);
967 // Tests that |FillSuggestion| properly fills the username and password.
968 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
969 // Simulate the browser sending the login info, but set |wait_for_username|
970 // to prevent the form from being immediately filled.
971 fill_data_.wait_for_username = true;
972 SimulateOnFillPasswordForm(fill_data_);
974 // Neither field should have been autocompleted.
975 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
977 // If the password field is not autocompletable, it should not be affected.
978 SetElementReadOnly(password_element_, true);
979 EXPECT_FALSE(password_autofill_agent_->FillSuggestion(
980 username_element_, kAliceUsername, kAlicePassword));
981 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
982 SetElementReadOnly(password_element_, false);
984 // After filling with the suggestion, both fields should be autocompleted.
985 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
986 username_element_, kAliceUsername, kAlicePassword));
987 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
988 int username_length = strlen(kAliceUsername);
989 CheckUsernameSelection(username_length, username_length);
991 // Try Filling with a suggestion with password different from the one that was
992 // initially sent to the renderer.
993 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
994 username_element_, kBobUsername, kCarolPassword));
995 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
996 username_length = strlen(kBobUsername);
997 CheckUsernameSelection(username_length, username_length);
1000 // Tests that |PreviewSuggestion| properly previews the username and password.
1001 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
1002 // Simulate the browser sending the login info, but set |wait_for_username|
1003 // to prevent the form from being immediately filled.
1004 fill_data_.wait_for_username = true;
1005 SimulateOnFillPasswordForm(fill_data_);
1007 // Neither field should have been autocompleted.
1008 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1010 // If the password field is not autocompletable, it should not be affected.
1011 SetElementReadOnly(password_element_, true);
1012 EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion(
1013 username_element_, kAliceUsername, kAlicePassword));
1014 EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
1015 EXPECT_FALSE(username_element_.isAutofilled());
1016 EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
1017 EXPECT_FALSE(password_element_.isAutofilled());
1018 SetElementReadOnly(password_element_, false);
1020 // After selecting the suggestion, both fields should be previewed
1021 // with suggested values.
1022 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1023 username_element_, kAliceUsername, kAlicePassword));
1024 EXPECT_EQ(
1025 kAliceUsername,
1026 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1027 EXPECT_TRUE(username_element_.isAutofilled());
1028 EXPECT_EQ(
1029 kAlicePassword,
1030 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1031 EXPECT_TRUE(password_element_.isAutofilled());
1032 int username_length = strlen(kAliceUsername);
1033 CheckUsernameSelection(0, username_length);
1035 // Try previewing with a password different from the one that was initially
1036 // sent to the renderer.
1037 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1038 username_element_, kBobUsername, kCarolPassword));
1039 EXPECT_EQ(
1040 kBobUsername,
1041 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1042 EXPECT_TRUE(username_element_.isAutofilled());
1043 EXPECT_EQ(
1044 kCarolPassword,
1045 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1046 EXPECT_TRUE(password_element_.isAutofilled());
1047 username_length = strlen(kBobUsername);
1048 CheckUsernameSelection(0, username_length);
1051 // Tests that |PreviewSuggestion| properly sets the username selection range.
1052 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
1053 username_element_.setValue(WebString::fromUTF8("ali"));
1054 username_element_.setSelectionRange(3, 3);
1055 username_element_.setAutofilled(true);
1057 CheckTextFieldsDOMState("ali", true, std::string(), false);
1059 // Simulate the browser sending the login info, but set |wait_for_username|
1060 // to prevent the form from being immediately filled.
1061 fill_data_.wait_for_username = true;
1062 SimulateOnFillPasswordForm(fill_data_);
1064 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1065 username_element_, kAliceUsername, kAlicePassword));
1066 EXPECT_EQ(
1067 kAliceUsername,
1068 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1069 EXPECT_TRUE(username_element_.isAutofilled());
1070 EXPECT_EQ(
1071 kAlicePassword,
1072 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1073 EXPECT_TRUE(password_element_.isAutofilled());
1074 int username_length = strlen(kAliceUsername);
1075 CheckUsernameSelection(3, username_length);
1078 // Tests that |ClearPreview| properly clears previewed username and password
1079 // with password being previously autofilled.
1080 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
1081 password_element_.setValue(WebString::fromUTF8("sec"));
1082 password_element_.setAutofilled(true);
1084 // Simulate the browser sending the login info, but set |wait_for_username|
1085 // to prevent the form from being immediately filled.
1086 fill_data_.wait_for_username = true;
1087 SimulateOnFillPasswordForm(fill_data_);
1089 CheckTextFieldsDOMState(std::string(), false, "sec", true);
1091 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1092 username_element_, kAliceUsername, kAlicePassword));
1094 EXPECT_TRUE(
1095 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1097 EXPECT_TRUE(username_element_.value().isEmpty());
1098 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1099 EXPECT_FALSE(username_element_.isAutofilled());
1100 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1101 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1102 EXPECT_TRUE(password_element_.isAutofilled());
1103 CheckUsernameSelection(0, 0);
1106 // Tests that |ClearPreview| properly clears previewed username and password
1107 // with username being previously autofilled.
1108 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
1109 username_element_.setValue(WebString::fromUTF8("ali"));
1110 username_element_.setSelectionRange(3, 3);
1111 username_element_.setAutofilled(true);
1113 // Simulate the browser sending the login info, but set |wait_for_username|
1114 // to prevent the form from being immediately filled.
1115 fill_data_.wait_for_username = true;
1116 SimulateOnFillPasswordForm(fill_data_);
1118 CheckTextFieldsDOMState("ali", true, std::string(), false);
1120 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1121 username_element_, kAliceUsername, kAlicePassword));
1123 EXPECT_TRUE(
1124 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1126 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1127 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1128 EXPECT_TRUE(username_element_.isAutofilled());
1129 EXPECT_TRUE(password_element_.value().isEmpty());
1130 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1131 EXPECT_FALSE(password_element_.isAutofilled());
1132 CheckUsernameSelection(3, 3);
1135 // Tests that |ClearPreview| properly clears previewed username and password
1136 // with username and password being previously autofilled.
1137 TEST_F(PasswordAutofillAgentTest,
1138 ClearPreviewWithAutofilledUsernameAndPassword) {
1139 username_element_.setValue(WebString::fromUTF8("ali"));
1140 username_element_.setSelectionRange(3, 3);
1141 username_element_.setAutofilled(true);
1142 password_element_.setValue(WebString::fromUTF8("sec"));
1143 password_element_.setAutofilled(true);
1145 // Simulate the browser sending the login info, but set |wait_for_username|
1146 // to prevent the form from being immediately filled.
1147 fill_data_.wait_for_username = true;
1148 SimulateOnFillPasswordForm(fill_data_);
1150 CheckTextFieldsDOMState("ali", true, "sec", true);
1152 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1153 username_element_, kAliceUsername, kAlicePassword));
1155 EXPECT_TRUE(
1156 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1158 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1159 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1160 EXPECT_TRUE(username_element_.isAutofilled());
1161 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1162 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1163 EXPECT_TRUE(password_element_.isAutofilled());
1164 CheckUsernameSelection(3, 3);
1167 // Tests that |ClearPreview| properly clears previewed username and password
1168 // with neither username nor password being previously autofilled.
1169 TEST_F(PasswordAutofillAgentTest,
1170 ClearPreviewWithNotAutofilledUsernameAndPassword) {
1171 // Simulate the browser sending the login info, but set |wait_for_username|
1172 // to prevent the form from being immediately filled.
1173 fill_data_.wait_for_username = true;
1174 SimulateOnFillPasswordForm(fill_data_);
1176 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1178 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1179 username_element_, kAliceUsername, kAlicePassword));
1181 EXPECT_TRUE(
1182 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1184 EXPECT_TRUE(username_element_.value().isEmpty());
1185 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1186 EXPECT_FALSE(username_element_.isAutofilled());
1187 EXPECT_TRUE(password_element_.value().isEmpty());
1188 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1189 EXPECT_FALSE(password_element_.isAutofilled());
1190 CheckUsernameSelection(0, 0);
1193 // Tests that |ClearPreview| properly restores the original selection range of
1194 // username field that has initially been filled by inline autocomplete.
1195 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) {
1196 // Simulate the browser sending back the login info.
1197 SimulateOnFillPasswordForm(fill_data_);
1199 // Clear the text fields to start fresh.
1200 ClearUsernameAndPasswordFields();
1202 // Simulate the user typing in the first letter of 'alice', a stored username.
1203 SimulateUsernameChange("a");
1204 // Both the username and password text fields should reflect selection of the
1205 // stored login.
1206 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1207 // The selection should have been set to 'lice', the last 4 letters.
1208 CheckUsernameSelection(1, 5);
1210 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1211 username_element_, "alicia", "secret"));
1212 EXPECT_EQ(
1213 "alicia",
1214 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1215 EXPECT_TRUE(username_element_.isAutofilled());
1216 EXPECT_EQ(
1217 "secret",
1218 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1219 EXPECT_TRUE(password_element_.isAutofilled());
1220 CheckUsernameSelection(1, 6);
1222 EXPECT_TRUE(
1223 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1225 EXPECT_EQ(kAliceUsername, username_element_.value().utf8());
1226 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1227 EXPECT_TRUE(username_element_.isAutofilled());
1228 EXPECT_EQ(kAlicePassword, password_element_.value().utf8());
1229 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1230 EXPECT_TRUE(password_element_.isAutofilled());
1231 CheckUsernameSelection(1, 5);
1234 // Tests that logging is off by default.
1235 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1236 render_thread_->sink().ClearMessages();
1237 SendVisiblePasswordForms();
1238 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1239 AutofillHostMsg_RecordSavePasswordProgress::ID);
1240 EXPECT_FALSE(message);
1243 // Test that logging can be turned on by a message.
1244 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1245 // Turn the logging on.
1246 AutofillMsg_SetLoggingState msg_activate(0, true);
1247 // Up-cast to access OnMessageReceived, which is private in the agent.
1248 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1249 ->OnMessageReceived(msg_activate));
1251 render_thread_->sink().ClearMessages();
1252 SendVisiblePasswordForms();
1253 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1254 AutofillHostMsg_RecordSavePasswordProgress::ID);
1255 EXPECT_TRUE(message);
1258 // Test that logging can be turned off by a message.
1259 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1260 // Turn the logging on and then off.
1261 AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
1262 // Up-cast to access OnMessageReceived, which is private in the agent.
1263 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1264 ->OnMessageReceived(msg_activate));
1265 AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
1266 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1267 ->OnMessageReceived(msg_deactivate));
1269 render_thread_->sink().ClearMessages();
1270 SendVisiblePasswordForms();
1271 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1272 AutofillHostMsg_RecordSavePasswordProgress::ID);
1273 EXPECT_FALSE(message);
1276 // Test that the agent sends an IPC call to get the current activity state of
1277 // password saving logging soon after construction.
1278 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1279 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1280 AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1281 EXPECT_TRUE(message);
1284 // Tests that one user click on a username field is sufficient to bring up a
1285 // credential suggestion popup, and the user can autocomplete the password by
1286 // selecting the credential from the popup.
1287 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1288 // SimulateElementClick() is called so that a user gesture is actually made
1289 // and the password can be filled. However, SimulateElementClick() does not
1290 // actually lead to the AutofillAgent's InputElementClicked() method being
1291 // called, so SimulateSuggestionChoice has to manually call
1292 // InputElementClicked().
1293 ClearUsernameAndPasswordFields();
1294 SimulateOnFillPasswordForm(fill_data_);
1295 SimulateElementClick(kUsernameName);
1296 SimulateSuggestionChoice(username_element_);
1297 CheckSuggestions(kAliceUsername, true);
1299 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1302 // Tests the autosuggestions that are given when the element is clicked.
1303 // Specifically, tests when the user clicks on the username element after page
1304 // load and the element is autofilled, when the user clicks on an element that
1305 // has a non-matching username, and when the user clicks on an element that's
1306 // already been autofilled and they've already modified.
1307 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1308 // Simulate the browser sending back the login info.
1309 SimulateOnFillPasswordForm(fill_data_);
1311 // Clear the text fields to start fresh.
1312 ClearUsernameAndPasswordFields();
1314 // Call SimulateElementClick() to produce a user gesture on the page so
1315 // autofill will actually fill.
1316 SimulateElementClick(kUsernameName);
1318 // Simulate a user clicking on the username element. This should produce a
1319 // message with all the usernames.
1320 render_thread_->sink().ClearMessages();
1321 static_cast<PageClickListener*>(autofill_agent_)
1322 ->FormControlElementClicked(username_element_, false);
1323 CheckSuggestions(std::string(), false);
1325 // Now simulate a user typing in an unrecognized username and then
1326 // clicking on the username element. This should also produce a message with
1327 // all the usernames.
1328 SimulateUsernameChange("baz");
1329 render_thread_->sink().ClearMessages();
1330 static_cast<PageClickListener*>(autofill_agent_)
1331 ->FormControlElementClicked(username_element_, true);
1332 CheckSuggestions("baz", true);
1333 ClearUsernameAndPasswordFields();
1335 // Now simulate a user typing in the first letter of the username and then
1336 // clicking on the username element. While the typing of the first letter will
1337 // inline autocomplete, clicking on the element should still produce a full
1338 // suggestion list.
1339 SimulateUsernameChange("a");
1340 render_thread_->sink().ClearMessages();
1341 static_cast<PageClickListener*>(autofill_agent_)
1342 ->FormControlElementClicked(username_element_, true);
1343 CheckSuggestions(kAliceUsername, true);
1346 // Tests that there are no autosuggestions from the password manager when the
1347 // user clicks on the password field and the username field is editable when
1348 // FillOnAccountSelect is enabled.
1349 TEST_F(PasswordAutofillAgentTest,
1350 FillOnAccountSelectOnlyNoCredentialsOnPasswordClick) {
1351 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1352 autofill::switches::kEnableFillOnAccountSelect);
1354 // Simulate the browser sending back the login info.
1355 SimulateOnFillPasswordForm(fill_data_);
1357 // Clear the text fields to start fresh.
1358 ClearUsernameAndPasswordFields();
1360 // Call SimulateElementClick() to produce a user gesture on the page so
1361 // autofill will actually fill.
1362 SimulateElementClick(kUsernameName);
1364 // Simulate a user clicking on the password element. This should produce no
1365 // message.
1366 render_thread_->sink().ClearMessages();
1367 static_cast<PageClickListener*>(autofill_agent_)
1368 ->FormControlElementClicked(password_element_, false);
1369 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1370 AutofillHostMsg_ShowPasswordSuggestions::ID));
1373 // Tests the autosuggestions that are given when a password element is clicked,
1374 // the username element is not editable, and FillOnAccountSelect is enabled.
1375 // Specifically, tests when the user clicks on the password element after page
1376 // load, and the corresponding username element is readonly (and thus
1377 // uneditable), that the credentials for the already-filled username are
1378 // suggested.
1379 TEST_F(PasswordAutofillAgentTest,
1380 FillOnAccountSelectOnlyCredentialsOnPasswordClick) {
1381 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1382 autofill::switches::kEnableFillOnAccountSelect);
1384 // Simulate the browser sending back the login info.
1385 SimulateOnFillPasswordForm(fill_data_);
1387 // Clear the text fields to start fresh.
1388 ClearUsernameAndPasswordFields();
1390 // Simulate the page loading with a prefilled username element that is
1391 // uneditable.
1392 username_element_.setValue("alicia");
1393 SetElementReadOnly(username_element_, true);
1395 // Call SimulateElementClick() to produce a user gesture on the page so
1396 // autofill will actually fill.
1397 SimulateElementClick(kUsernameName);
1399 // Simulate a user clicking on the password element. This should produce a
1400 // message with "alicia" suggested as the credential.
1401 render_thread_->sink().ClearMessages();
1402 static_cast<PageClickListener*>(autofill_agent_)
1403 ->FormControlElementClicked(password_element_, false);
1404 CheckSuggestions("alicia", false);
1407 // Tests that there are no autosuggestions from the password manager when the
1408 // user clicks on the password field (not the username field).
1409 TEST_F(PasswordAutofillAgentTest, NoCredentialsOnPasswordClick) {
1410 // Simulate the browser sending back the login info.
1411 SimulateOnFillPasswordForm(fill_data_);
1413 // Clear the text fields to start fresh.
1414 ClearUsernameAndPasswordFields();
1416 // Call SimulateElementClick() to produce a user gesture on the page so
1417 // autofill will actually fill.
1418 SimulateElementClick(kUsernameName);
1420 // Simulate a user clicking on the password element. This should produce no
1421 // message.
1422 render_thread_->sink().ClearMessages();
1423 static_cast<PageClickListener*>(autofill_agent_)
1424 ->FormControlElementClicked(password_element_, false);
1425 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1426 AutofillHostMsg_ShowPasswordSuggestions::ID));
1429 // The user types in a username and a password, but then just before sending
1430 // the form off, a script clears them. This test checks that
1431 // PasswordAutofillAgent can still remember the username and the password
1432 // typed by the user.
1433 TEST_F(PasswordAutofillAgentTest,
1434 RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) {
1435 SimulateUsernameChange("temp");
1436 SimulatePasswordChange("random");
1438 // Simulate that the username and the password value was cleared by the
1439 // site's JavaScript before submit.
1440 username_element_.setValue(WebString());
1441 password_element_.setValue(WebString());
1442 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1443 ->WillSubmitForm(username_element_.form());
1445 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1446 // username and password and sent that to the browser.
1447 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1450 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time
1451 // it's the user who clears the username and the password. This test checks
1452 // that in that case, the last non-empty username and password are not
1453 // remembered.
1454 TEST_F(PasswordAutofillAgentTest,
1455 RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) {
1456 SimulateUsernameChange("temp");
1457 SimulatePasswordChange("random");
1459 // Simulate that the user actually cleared the username and password again.
1460 SimulateUsernameChange("");
1461 SimulatePasswordChange("");
1462 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1463 ->WillSubmitForm(username_element_.form());
1465 // Observe that the PasswordAutofillAgent respects the user having cleared the
1466 // password.
1467 ExpectFormSubmittedWithUsernameAndPasswords("", "", "");
1470 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the
1471 // new password instead of the current password.
1472 TEST_F(PasswordAutofillAgentTest,
1473 RememberLastNonEmptyUsernameAndPasswordOnSubmit_New) {
1474 const char kNewPasswordFormHTML[] =
1475 "<FORM name='LoginTestForm'>"
1476 " <INPUT type='text' id='username' autocomplete='username'/>"
1477 " <INPUT type='password' id='password' autocomplete='new-password'/>"
1478 " <INPUT type='submit' value='Login'/>"
1479 "</FORM>";
1480 LoadHTML(kNewPasswordFormHTML);
1481 UpdateUsernameAndPasswordElements();
1483 SimulateUsernameChange("temp");
1484 SimulatePasswordChange("random");
1486 // Simulate that the username and the password value was cleared by
1487 // the site's JavaScript before submit.
1488 username_element_.setValue(WebString());
1489 password_element_.setValue(WebString());
1490 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1491 ->WillSubmitForm(username_element_.form());
1493 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1494 // password and sent that to the browser.
1495 ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random");
1498 // The user first accepts a suggestion, but then overwrites the password. This
1499 // test checks that the overwritten password is not reverted back if the user
1500 // triggers autofill through focusing (but not changing) the username again.
1501 TEST_F(PasswordAutofillAgentTest,
1502 NoopEditingDoesNotOverwriteManuallyEditedPassword) {
1503 // Simulate having credentials which needed to wait until the user starts
1504 // typing the username to be filled (e.g., PSL-matched credentials). Those are
1505 // the ones which can be filled as a result of TextFieldDidEndEditing.
1506 fill_data_.wait_for_username = true;
1507 SimulateOnFillPasswordForm(fill_data_);
1508 // Simulate that the user typed her name to make the autofill work.
1509 SimulateUsernameChange(kAliceUsername);
1510 SimulateDidEndEditing(GetMainFrame(), username_element_);
1511 const std::string old_username(username_element_.value().utf8());
1512 const std::string old_password(password_element_.value().utf8());
1513 const std::string new_password(old_password + "modify");
1515 // The user changes the password.
1516 SimulatePasswordChange(new_password);
1518 // The user switches back into the username field, but leaves that without
1519 // changes.
1520 SimulateDidEndEditing(GetMainFrame(), username_element_);
1522 // The password should have stayed as the user changed it.
1523 CheckTextFieldsDOMState(old_username, true, new_password, false);
1524 // The password should not have a suggested value.
1525 CheckTextFieldsState(old_username, true, std::string(), false);
1528 TEST_F(PasswordAutofillAgentTest,
1529 InlineAutocompleteOverwritesManuallyEditedPassword) {
1530 // Simulate the browser sending back the login info.
1531 SimulateOnFillPasswordForm(fill_data_);
1533 ClearUsernameAndPasswordFields();
1535 // The user enters a password
1536 SimulatePasswordChange("someOtherPassword");
1538 // Simulate the user typing a stored username.
1539 SimulateUsernameChange(kAliceUsername);
1540 // The autofileld password should replace the typed one.
1541 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1544 // The user types in a username and a password, but then just before sending
1545 // the form off, a script changes them. This test checks that
1546 // PasswordAutofillAgent can still remember the username and the password
1547 // typed by the user.
1548 TEST_F(PasswordAutofillAgentTest,
1549 RememberLastTypedUsernameAndPasswordOnSubmit_ScriptChanged) {
1550 SimulateUsernameChange("temp");
1551 SimulatePasswordChange("random");
1553 // Simulate that the username and the password value was changed by the
1554 // site's JavaScript before submit.
1555 username_element_.setValue(WebString("new username"));
1556 password_element_.setValue(WebString("new password"));
1557 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1558 ->WillSendSubmitEvent(username_element_.form());
1559 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1560 ->WillSubmitForm(username_element_.form());
1562 // Observe that the PasswordAutofillAgent still remembered the last typed
1563 // username and password and sent that to the browser.
1564 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1567 // The username/password is autofilled by password manager then just before
1568 // sending the form off, a script changes them. This test checks that
1569 // PasswordAutofillAgent can still get the username and the password autofilled.
1570 TEST_F(PasswordAutofillAgentTest,
1571 RememberLastAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1572 SimulateOnFillPasswordForm(fill_data_);
1574 // Simulate that the username and the password value was changed by the
1575 // site's JavaScript before submit.
1576 username_element_.setValue(WebString("new username"));
1577 password_element_.setValue(WebString("new password"));
1578 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1579 ->WillSendSubmitEvent(username_element_.form());
1580 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1581 ->WillSubmitForm(username_element_.form());
1583 // Observe that the PasswordAutofillAgent still remembered the autofilled
1584 // username and password and sent that to the browser.
1585 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, kAlicePassword,
1586 "");
1589 // The username/password is autofilled by password manager then user types in a
1590 // username and a password. Then just before sending the form off, a script
1591 // changes them. This test checks that PasswordAutofillAgent can still remember
1592 // the username and the password typed by the user.
1593 TEST_F(
1594 PasswordAutofillAgentTest,
1595 RememberLastTypedAfterAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1596 SimulateOnFillPasswordForm(fill_data_);
1598 SimulateUsernameChange("temp");
1599 SimulatePasswordChange("random");
1601 // Simulate that the username and the password value was changed by the
1602 // site's JavaScript before submit.
1603 username_element_.setValue(WebString("new username"));
1604 password_element_.setValue(WebString("new password"));
1605 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1606 ->WillSendSubmitEvent(username_element_.form());
1607 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1608 ->WillSubmitForm(username_element_.form());
1610 // Observe that the PasswordAutofillAgent still remembered the last typed
1611 // username and password and sent that to the browser.
1612 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1615 // The user starts typing username then it is autofilled.
1616 // PasswordAutofillAgent should remember the username that was autofilled,
1617 // not last typed.
1618 TEST_F(PasswordAutofillAgentTest, RememberAutofilledUsername) {
1619 SimulateUsernameChange("Te");
1620 // Simulate that the username was changed by autofilling.
1621 username_element_.setValue(WebString("temp"));
1622 SimulatePasswordChange("random");
1624 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1625 ->WillSendSubmitEvent(username_element_.form());
1626 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1627 ->WillSubmitForm(username_element_.form());
1629 // Observe that the PasswordAutofillAgent still remembered the last typed
1630 // username and password and sent that to the browser.
1631 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1634 TEST_F(PasswordAutofillAgentTest, FormFillDataMustHaveUsername) {
1635 ClearUsernameAndPasswordFields();
1637 PasswordFormFillData no_username_fill_data = fill_data_;
1638 no_username_fill_data.username_field.name = base::string16();
1639 SimulateOnFillPasswordForm(no_username_fill_data);
1641 // The username and password should not have been autocompleted.
1642 CheckTextFieldsState("", false, "", false);
1645 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnly) {
1646 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1647 autofill::switches::kEnableFillOnAccountSelect);
1649 ClearUsernameAndPasswordFields();
1651 // Simulate the browser sending back the login info for an initial page load.
1652 SimulateOnFillPasswordForm(fill_data_);
1654 CheckTextFieldsState(std::string(), true, std::string(), false);
1657 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyReadonlyUsername) {
1658 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1659 autofill::switches::kEnableFillOnAccountSelect);
1661 ClearUsernameAndPasswordFields();
1663 username_element_.setValue("alice");
1664 SetElementReadOnly(username_element_, true);
1666 // Simulate the browser sending back the login info for an initial page load.
1667 SimulateOnFillPasswordForm(fill_data_);
1669 CheckTextFieldsState(std::string("alice"), false, std::string(), true);
1672 TEST_F(PasswordAutofillAgentTest,
1673 FillOnAccountSelectOnlyReadonlyNotPreferredUsername) {
1674 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1675 autofill::switches::kEnableFillOnAccountSelect);
1677 ClearUsernameAndPasswordFields();
1679 username_element_.setValue("Carol");
1680 SetElementReadOnly(username_element_, true);
1682 // Simulate the browser sending back the login info for an initial page load.
1683 SimulateOnFillPasswordForm(fill_data_);
1685 CheckTextFieldsState(std::string("Carol"), false, std::string(), true);
1688 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) {
1689 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1690 autofill::switches::kEnableFillOnAccountSelect);
1692 // Load a form with no username and update test data.
1693 LoadHTML(kVisibleFormWithNoUsernameHTML);
1694 username_element_.reset();
1695 WebDocument document = GetMainFrame()->document();
1696 WebElement element =
1697 document.getElementById(WebString::fromUTF8(kPasswordName));
1698 ASSERT_FALSE(element.isNull());
1699 password_element_ = element.to<blink::WebInputElement>();
1700 fill_data_.username_field = FormFieldData();
1701 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1702 fill_data_.additional_logins.clear();
1703 fill_data_.other_possible_usernames.clear();
1705 password_element_.setValue("");
1706 password_element_.setAutofilled(false);
1708 // Simulate the browser sending back the login info for an initial page load.
1709 SimulateOnFillPasswordForm(fill_data_);
1711 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1712 EXPECT_TRUE(password_element_.isAutofilled());
1715 TEST_F(PasswordAutofillAgentTest, ShowPopupNoUsername) {
1716 // Load a form with no username and update test data.
1717 LoadHTML(kVisibleFormWithNoUsernameHTML);
1718 username_element_.reset();
1719 WebDocument document = GetMainFrame()->document();
1720 WebElement element =
1721 document.getElementById(WebString::fromUTF8(kPasswordName));
1722 ASSERT_FALSE(element.isNull());
1723 password_element_ = element.to<blink::WebInputElement>();
1724 fill_data_.username_field = FormFieldData();
1725 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1726 fill_data_.additional_logins.clear();
1727 fill_data_.other_possible_usernames.clear();
1729 password_element_.setValue("");
1730 password_element_.setAutofilled(false);
1732 // Simulate the browser sending back the login info for an initial page load.
1733 SimulateOnFillPasswordForm(fill_data_);
1735 password_element_.setValue("");
1736 password_element_.setAutofilled(false);
1738 SimulateSuggestionChoiceOfUsernameAndPassword(
1739 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword));
1740 CheckSuggestions(std::string(), false);
1741 EXPECT_EQ(ASCIIToUTF16(kAlicePassword), password_element_.value());
1742 EXPECT_TRUE(password_element_.isAutofilled());
1745 // Tests with fill-on-account-select enabled that if the username element is
1746 // read-only and filled with an unknown username, then the password field is not
1747 // highlighted as autofillable (regression test for https://crbug.com/442564).
1748 TEST_F(PasswordAutofillAgentTest,
1749 FillOnAccountSelectOnlyReadonlyUnknownUsername) {
1750 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1751 autofill::switches::kEnableFillOnAccountSelect);
1753 ClearUsernameAndPasswordFields();
1755 username_element_.setValue("foobar");
1756 SetElementReadOnly(username_element_, true);
1758 CheckTextFieldsState(std::string("foobar"), false, std::string(), false);
1761 // Test that the last plain text field before a password field is chosen as a
1762 // username, in a form with 2 plain text fields without username predictions.
1763 TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) {
1764 LoadHTML(kFormHTMLWithTwoTextFields);
1765 UpdateUsernameAndPasswordElements();
1766 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1767 SimulateUsernameChange("temp");
1768 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1769 SimulatePasswordChange("random");
1770 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1771 ->WillSendSubmitEvent(username_element_.form());
1772 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1773 ->WillSubmitForm(username_element_.form());
1775 // Observe that the PasswordAutofillAgent identifies the second field (e-mail)
1776 // as username.
1777 ExpectFormSubmittedWithUsernameAndPasswords("temp@google.com", "random", "");
1780 // Tests that field predictions are followed when identifying the username
1781 // and password in a password form with two plain text fields.
1782 TEST_F(PasswordAutofillAgentTest, FindingFieldsWithAutofillPredictions) {
1783 LoadHTML(kFormHTMLWithTwoTextFields);
1784 UpdateUsernameAndPasswordElements();
1785 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1786 SimulateUsernameChange("temp");
1787 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1788 SimulatePasswordChange("random");
1789 // Find FormData for visible password form.
1790 blink::WebFormElement form_element = username_element_.form();
1791 FormData form_data;
1792 ASSERT_TRUE(WebFormElementToFormData(form_element,
1793 blink::WebFormControlElement(),
1794 EXTRACT_NONE, &form_data, nullptr));
1795 // Simulate Autofill predictions: the first field is username, the third
1796 // one is password.
1797 std::map<autofill::FormData, PasswordFormFieldPredictionMap> predictions;
1798 predictions[form_data][PREDICTION_USERNAME] = form_data.fields[0];
1799 predictions[form_data][PREDICTION_NEW_PASSWORD] = form_data.fields[2];
1800 AutofillMsg_AutofillUsernameAndPasswordDataReceived msg(0, predictions);
1801 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1802 ->OnMessageReceived(msg);
1804 // The predictions should still match even if the form changes, as long
1805 // as the particular elements don't change.
1806 std::string add_field_to_form =
1807 "var form = document.getElementById('LoginTestForm');"
1808 "var new_input = document.createElement('input');"
1809 "new_input.setAttribute('type', 'text');"
1810 "new_input.setAttribute('id', 'other_field');"
1811 "form.appendChild(new_input);";
1812 ExecuteJavaScript(add_field_to_form.c_str());
1814 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1815 ->WillSendSubmitEvent(username_element_.form());
1816 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1817 ->WillSubmitForm(username_element_.form());
1819 // Observe that the PasswordAutofillAgent identifies the first field as
1820 // username.
1821 // TODO(msramek): We should also test that adding another password field
1822 // won't override the password field prediction either. However, the password
1823 // field predictions are not taken into account yet.
1824 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1827 // The user types in a username and a password. Then JavaScript changes password
1828 // field to readonly state before submit. PasswordAutofillAgent can correctly
1829 // process readonly password field. This test models behaviour of gmail.com.
1830 TEST_F(PasswordAutofillAgentTest, ReadonlyPasswordFieldOnSubmit) {
1831 SimulateUsernameChange("temp");
1832 SimulatePasswordChange("random");
1834 // Simulate that JavaScript makes password field readonly.
1835 SetElementReadOnly(password_element_, true);
1836 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1837 ->WillSubmitForm(username_element_.form());
1839 // Observe that the PasswordAutofillAgent can correctly process submitted
1840 // form.
1841 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1844 // Verify that typed passwords are saved correctly when autofill and generation
1845 // both trigger. Regression test for https://crbug.com/493455
1846 TEST_F(PasswordAutofillAgentTest, PasswordGenerationTriggered_TypedPassword) {
1847 SimulateOnFillPasswordForm(fill_data_);
1849 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1850 SetAccountCreationFormsDetectedMessage(password_generation_,
1851 GetMainFrame()->document(),
1854 SimulateUsernameChange("NewGuy");
1855 SimulatePasswordChange("NewPassword");
1856 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1857 ->WillSendSubmitEvent(username_element_.form());
1858 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1859 ->WillSubmitForm(username_element_.form());
1861 ExpectFormSubmittedWithUsernameAndPasswords("NewGuy", "NewPassword", "");
1864 // Verify that generated passwords are saved correctly when autofill and
1865 // generation both trigger. Regression test for https://crbug.com/493455.
1866 TEST_F(PasswordAutofillAgentTest,
1867 PasswordGenerationTriggered_GeneratedPassword) {
1868 SimulateOnFillPasswordForm(fill_data_);
1870 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1871 SetAccountCreationFormsDetectedMessage(password_generation_,
1872 GetMainFrame()->document(),
1875 base::string16 password = base::ASCIIToUTF16("NewPass22");
1876 AutofillMsg_GeneratedPasswordAccepted msg(0, password);
1877 password_generation_->OnMessageReceived(msg);
1879 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1880 ->WillSendSubmitEvent(username_element_.form());
1881 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1882 ->WillSubmitForm(username_element_.form());
1884 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, "NewPass22", "");
1887 // If password generation is enabled for a field, password autofill should not
1888 // show UI.
1889 TEST_F(PasswordAutofillAgentTest, PasswordGenerationSupersedesAutofill) {
1890 LoadHTML(kSignupFormHTML);
1892 // Update password_element_;
1893 WebDocument document = GetMainFrame()->document();
1894 WebElement element =
1895 document.getElementById(WebString::fromUTF8("new_password"));
1896 ASSERT_FALSE(element.isNull());
1897 password_element_ = element.to<blink::WebInputElement>();
1899 // Update fill_data_ for the new form and simulate filling. Pretend as if
1900 // the password manager didn't detect a username field so it will try to
1901 // show UI when the password field is focused.
1902 fill_data_.wait_for_username = true;
1903 fill_data_.username_field = FormFieldData();
1904 fill_data_.password_field.name = base::ASCIIToUTF16("new_password");
1905 UpdateOriginForHTML(kSignupFormHTML);
1906 SimulateOnFillPasswordForm(fill_data_);
1908 // Simulate generation triggering.
1909 SetNotBlacklistedMessage(password_generation_,
1910 kSignupFormHTML);
1911 SetAccountCreationFormsDetectedMessage(password_generation_,
1912 GetMainFrame()->document(),
1915 // Simulate the field being clicked to start typing. This should trigger
1916 // generation but not password autofill.
1917 SetFocused(password_element_);
1918 SimulateElementClick("new_password");
1919 EXPECT_EQ(nullptr,
1920 render_thread_->sink().GetFirstMessageMatching(
1921 AutofillHostMsg_ShowPasswordSuggestions::ID));
1922 ExpectPasswordGenerationAvailable(password_generation_, true);
1925 // Tests that a password change form is properly filled with the username and
1926 // password.
1927 TEST_F(PasswordAutofillAgentTest, FillSuggestionPasswordChangeForms) {
1928 LoadHTML(kPasswordChangeFormHTML);
1929 UpdateOriginForHTML(kPasswordChangeFormHTML);
1930 UpdateUsernameAndPasswordElements();
1931 // Simulate the browser sending the login info, but set |wait_for_username|
1932 // to prevent the form from being immediately filled.
1933 fill_data_.wait_for_username = true;
1934 fill_data_.is_possible_change_password_form = true;
1935 SimulateOnFillPasswordForm(fill_data_);
1937 // Neither field should have been autocompleted.
1938 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1940 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1941 username_element_, kAliceUsername, kAlicePassword));
1942 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1945 // Tests that a password change form is properly filled with the password when
1946 // the user click on the password field.
1947 TEST_F(PasswordAutofillAgentTest,
1948 FillSuggestionPasswordChangeFormsOnlyPassword) {
1949 LoadHTML(kPasswordChangeFormHTML);
1950 UpdateOriginForHTML(kPasswordChangeFormHTML);
1951 UpdateUsernameAndPasswordElements();
1952 // Simulate the browser sending the login info, but set |wait_for_username|
1953 // to prevent the form from being immediately filled.
1954 fill_data_.wait_for_username = true;
1955 fill_data_.is_possible_change_password_form = true;
1956 SimulateOnFillPasswordForm(fill_data_);
1958 // Neither field should have been autocompleted.
1959 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1961 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1962 password_element_, kAliceUsername, kAlicePassword));
1963 CheckTextFieldsDOMState("", false, kAlicePassword, true);
1966 // Tests that one user click on a username field is sufficient to bring up a
1967 // credential suggestion popup on a change password form.
1968 TEST_F(PasswordAutofillAgentTest,
1969 SuggestionsOnUsernameFieldOfChangePasswordForm) {
1970 LoadHTML(kPasswordChangeFormHTML);
1971 UpdateOriginForHTML(kPasswordChangeFormHTML);
1972 UpdateUsernameAndPasswordElements();
1974 ClearUsernameAndPasswordFields();
1975 fill_data_.wait_for_username = true;
1976 fill_data_.is_possible_change_password_form = true;
1977 SimulateOnFillPasswordForm(fill_data_);
1978 // Simulate a user clicking on the username element. This should produce a
1979 // message.
1980 render_thread_->sink().ClearMessages();
1981 static_cast<PageClickListener*>(autofill_agent_)
1982 ->FormControlElementClicked(username_element_, true);
1983 CheckSuggestions("", true);
1986 // Tests that one user click on a password field is sufficient to bring up a
1987 // credential suggestion popup on a change password form.
1988 TEST_F(PasswordAutofillAgentTest,
1989 SuggestionsOnPasswordFieldOfChangePasswordForm) {
1990 LoadHTML(kPasswordChangeFormHTML);
1991 UpdateOriginForHTML(kPasswordChangeFormHTML);
1992 UpdateUsernameAndPasswordElements();
1994 ClearUsernameAndPasswordFields();
1995 fill_data_.wait_for_username = true;
1996 fill_data_.is_possible_change_password_form = true;
1997 SimulateOnFillPasswordForm(fill_data_);
1998 // Simulate a user clicking on the password element. This should produce a
1999 // message.
2000 render_thread_->sink().ClearMessages();
2001 static_cast<PageClickListener*>(autofill_agent_)
2002 ->FormControlElementClicked(password_element_, true);
2003 CheckSuggestions("", false);
2006 // Tests that there are no autosuggestions from the password manager when the
2007 // user clicks on the password field of change password form after the user
2008 // typed in the username field.
2009 TEST_F(PasswordAutofillAgentTest,
2010 NoSuggestionsOnPasswordFieldOfChangePasswordFormAfterUsernameTyping) {
2011 LoadHTML(kPasswordChangeFormHTML);
2012 UpdateOriginForHTML(kPasswordChangeFormHTML);
2013 UpdateUsernameAndPasswordElements();
2015 ClearUsernameAndPasswordFields();
2016 fill_data_.wait_for_username = true;
2017 fill_data_.is_possible_change_password_form = true;
2018 SimulateOnFillPasswordForm(fill_data_);
2020 // Clear the text fields to start fresh.
2021 SimulateUsernameChange("temp");
2023 // Simulate a user clicking on the password element. This should produce no
2024 // message.
2025 render_thread_->sink().ClearMessages();
2026 static_cast<PageClickListener*>(autofill_agent_)
2027 ->FormControlElementClicked(password_element_, false);
2028 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
2029 AutofillHostMsg_ShowPasswordSuggestions::ID));
2032 } // namespace autofill