Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / renderer / autofill / password_autofill_agent_browsertest.cc
blob6a0cc2eac83a6955ad64398c8c98449702bed5e6
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 ASSERT_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 TEST_F(PasswordAutofillAgentTest, PasswordNotClearedOnEdit) {
663 // Simulate the browser sending back the login info, it triggers the
664 // autocomplete.
665 SimulateOnFillPasswordForm(fill_data_);
667 // Simulate the user changing the username to some unknown username.
668 SimulateUsernameChange("alicia");
670 // The password should not have been cleared.
671 CheckTextFieldsDOMState("alicia", false, kAlicePassword, true);
674 // Tests that we only autocomplete on focus lost and with a full username match
675 // when |wait_for_username| is true.
676 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
677 // Simulate the browser sending back the login info.
678 fill_data_.wait_for_username = true;
679 SimulateOnFillPasswordForm(fill_data_);
681 // No auto-fill should have taken place.
682 CheckTextFieldsState(std::string(), false, std::string(), false);
684 // No autocomplete should happen when text is entered in the username.
685 SimulateUsernameChange("a");
686 CheckTextFieldsState("a", false, std::string(), false);
687 SimulateUsernameChange("al");
688 CheckTextFieldsState("al", false, std::string(), false);
689 SimulateUsernameChange(kAliceUsername);
690 CheckTextFieldsState(kAliceUsername, false, std::string(), false);
692 // Autocomplete should happen only when the username textfield is blurred with
693 // a full match.
694 SimulateUsernameChange("a");
695 static_cast<blink::WebAutofillClient*>(autofill_agent_)
696 ->textFieldDidEndEditing(username_element_);
697 CheckTextFieldsState("a", false, std::string(), false);
698 SimulateUsernameChange("al");
699 static_cast<blink::WebAutofillClient*>(autofill_agent_)
700 ->textFieldDidEndEditing(username_element_);
701 CheckTextFieldsState("al", false, std::string(), false);
702 SimulateUsernameChange("alices");
703 static_cast<blink::WebAutofillClient*>(autofill_agent_)
704 ->textFieldDidEndEditing(username_element_);
705 CheckTextFieldsState("alices", false, std::string(), false);
706 SimulateUsernameChange(kAliceUsername);
707 static_cast<blink::WebAutofillClient*>(autofill_agent_)
708 ->textFieldDidEndEditing(username_element_);
709 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
712 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
713 blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
714 blink::WebFrame* frame;
716 LoadHTML(kVisibleFormWithNoUsernameHTML);
717 frame = GetMainFrame();
718 frame->document().forms(forms1);
719 ASSERT_EQ(1u, forms1.size());
720 EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
722 LoadHTML(kEmptyFormHTML);
723 frame = GetMainFrame();
724 frame->document().forms(forms2);
725 ASSERT_EQ(1u, forms2.size());
726 EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
728 LoadHTML(kNonVisibleFormHTML);
729 frame = GetMainFrame();
730 frame->document().forms(forms3);
731 ASSERT_EQ(1u, forms3.size());
732 EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
735 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
736 render_thread_->sink().ClearMessages();
737 LoadHTML(kVisibleFormWithNoUsernameHTML);
738 const IPC::Message* message = render_thread_->sink()
739 .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
740 EXPECT_TRUE(message);
741 base::Tuple<std::vector<autofill::PasswordForm>, bool> param;
742 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
743 EXPECT_TRUE(base::get<0>(param).size());
745 render_thread_->sink().ClearMessages();
746 LoadHTML(kEmptyFormHTML);
747 message = render_thread_->sink().GetFirstMessageMatching(
748 AutofillHostMsg_PasswordFormsRendered::ID);
749 EXPECT_TRUE(message);
750 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
751 EXPECT_FALSE(base::get<0>(param).size());
753 render_thread_->sink().ClearMessages();
754 LoadHTML(kNonVisibleFormHTML);
755 message = render_thread_->sink().GetFirstMessageMatching(
756 AutofillHostMsg_PasswordFormsRendered::ID);
757 EXPECT_TRUE(message);
758 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
759 EXPECT_FALSE(base::get<0>(param).size());
762 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
763 render_thread_->sink().ClearMessages();
764 LoadHTML(kEmptyWebpage);
765 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
766 AutofillHostMsg_PasswordFormsRendered::ID));
768 render_thread_->sink().ClearMessages();
769 LoadHTML(kRedirectionWebpage);
770 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
771 AutofillHostMsg_PasswordFormsRendered::ID));
773 render_thread_->sink().ClearMessages();
774 LoadHTML(kSimpleWebpage);
775 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
776 AutofillHostMsg_PasswordFormsRendered::ID));
778 render_thread_->sink().ClearMessages();
779 LoadHTML(kWebpageWithDynamicContent);
780 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
781 AutofillHostMsg_PasswordFormsRendered::ID));
784 // Tests that a password will only be filled as a suggested and will not be
785 // accessible by the DOM until a user gesture has occurred.
786 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
787 // Trigger the initial autocomplete.
788 SimulateOnFillPasswordForm(fill_data_);
790 // The username and password should have been autocompleted.
791 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
793 // However, it should only have completed with the suggested value, as tested
794 // above, and it should not have completed into the DOM accessible value for
795 // the password field.
796 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
798 // Simulate a user click so that the password field's real value is filled.
799 SimulateElementClick(kUsernameName);
800 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
803 // Verfies that a DOM-activated UI event will not cause an autofill.
804 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
805 // Trigger the initial autocomplete.
806 SimulateOnFillPasswordForm(fill_data_);
808 ExecuteJavaScriptForTests(kJavaScriptClick);
809 CheckTextFieldsDOMState(kAliceUsername, true, "", true);
812 // Verifies that password autofill triggers onChange events in JavaScript for
813 // forms that are filled on page load.
814 TEST_F(PasswordAutofillAgentTest,
815 PasswordAutofillTriggersOnChangeEventsOnLoad) {
816 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
817 LoadHTML(html.c_str());
818 UpdateOriginForHTML(html);
819 UpdateUsernameAndPasswordElements();
821 // Simulate the browser sending back the login info, it triggers the
822 // autocomplete.
823 SimulateOnFillPasswordForm(fill_data_);
825 // The username and password should have been autocompleted...
826 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
827 // ... but since there hasn't been a user gesture yet, the autocompleted
828 // password should only be visible to the user.
829 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
831 // A JavaScript onChange event should have been triggered for the username,
832 // but not yet for the password.
833 int username_onchange_called = -1;
834 int password_onchange_called = -1;
835 ASSERT_TRUE(
836 ExecuteJavaScriptAndReturnIntValue(
837 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
838 &username_onchange_called));
839 EXPECT_EQ(1, username_onchange_called);
840 ASSERT_TRUE(
841 ExecuteJavaScriptAndReturnIntValue(
842 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
843 &password_onchange_called));
844 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
845 // EXPECT_EQ(0, password_onchange_called);
847 // Simulate a user click so that the password field's real value is filled.
848 SimulateElementClick(kUsernameName);
849 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
851 // Now, a JavaScript onChange event should have been triggered for the
852 // password as well.
853 ASSERT_TRUE(
854 ExecuteJavaScriptAndReturnIntValue(
855 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
856 &password_onchange_called));
857 EXPECT_EQ(1, password_onchange_called);
860 // Verifies that password autofill triggers onChange events in JavaScript for
861 // forms that are filled after page load.
862 TEST_F(PasswordAutofillAgentTest,
863 PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
864 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
865 LoadHTML(html.c_str());
866 UpdateOriginForHTML(html);
867 UpdateUsernameAndPasswordElements();
869 // Simulate the browser sending back the login info, it triggers the
870 // autocomplete.
871 fill_data_.wait_for_username = true;
872 SimulateOnFillPasswordForm(fill_data_);
874 // The username and password should not yet have been autocompleted.
875 CheckTextFieldsState(std::string(), false, std::string(), false);
877 // Simulate a click just to force a user gesture, since the username value is
878 // set directly.
879 SimulateElementClick(kUsernameName);
881 // Simulate the user entering the first letter of her username and selecting
882 // the matching autofill from the dropdown.
883 SimulateUsernameChange("a");
884 SimulateSuggestionChoice(username_element_);
886 // The username and password should now have been autocompleted.
887 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
889 // JavaScript onChange events should have been triggered both for the username
890 // and for the password.
891 int username_onchange_called = -1;
892 int password_onchange_called = -1;
893 ASSERT_TRUE(
894 ExecuteJavaScriptAndReturnIntValue(
895 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
896 &username_onchange_called));
897 EXPECT_EQ(1, username_onchange_called);
898 ASSERT_TRUE(
899 ExecuteJavaScriptAndReturnIntValue(
900 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
901 &password_onchange_called));
902 EXPECT_EQ(1, password_onchange_called);
905 // Tests that |FillSuggestion| properly fills the username and password.
906 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
907 // Simulate the browser sending the login info, but set |wait_for_username|
908 // to prevent the form from being immediately filled.
909 fill_data_.wait_for_username = true;
910 SimulateOnFillPasswordForm(fill_data_);
912 // Neither field should have been autocompleted.
913 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
915 // If the password field is not autocompletable, it should not be affected.
916 SetElementReadOnly(password_element_, true);
917 EXPECT_FALSE(password_autofill_agent_->FillSuggestion(
918 username_element_, kAliceUsername, kAlicePassword));
919 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
920 SetElementReadOnly(password_element_, false);
922 // After filling with the suggestion, both fields should be autocompleted.
923 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
924 username_element_, kAliceUsername, kAlicePassword));
925 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
926 int username_length = strlen(kAliceUsername);
927 CheckUsernameSelection(username_length, username_length);
929 // Try Filling with a suggestion with password different from the one that was
930 // initially sent to the renderer.
931 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
932 username_element_, kBobUsername, kCarolPassword));
933 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
934 username_length = strlen(kBobUsername);
935 CheckUsernameSelection(username_length, username_length);
938 // Tests that |PreviewSuggestion| properly previews the username and password.
939 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
940 // Simulate the browser sending the login info, but set |wait_for_username|
941 // to prevent the form from being immediately filled.
942 fill_data_.wait_for_username = true;
943 SimulateOnFillPasswordForm(fill_data_);
945 // Neither field should have been autocompleted.
946 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
948 // If the password field is not autocompletable, it should not be affected.
949 SetElementReadOnly(password_element_, true);
950 EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion(
951 username_element_, kAliceUsername, kAlicePassword));
952 EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
953 EXPECT_FALSE(username_element_.isAutofilled());
954 EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
955 EXPECT_FALSE(password_element_.isAutofilled());
956 SetElementReadOnly(password_element_, false);
958 // After selecting the suggestion, both fields should be previewed
959 // with suggested values.
960 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
961 username_element_, kAliceUsername, kAlicePassword));
962 EXPECT_EQ(
963 kAliceUsername,
964 static_cast<std::string>(username_element_.suggestedValue().utf8()));
965 EXPECT_TRUE(username_element_.isAutofilled());
966 EXPECT_EQ(
967 kAlicePassword,
968 static_cast<std::string>(password_element_.suggestedValue().utf8()));
969 EXPECT_TRUE(password_element_.isAutofilled());
970 int username_length = strlen(kAliceUsername);
971 CheckUsernameSelection(0, username_length);
973 // Try previewing with a password different from the one that was initially
974 // sent to the renderer.
975 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
976 username_element_, kBobUsername, kCarolPassword));
977 EXPECT_EQ(
978 kBobUsername,
979 static_cast<std::string>(username_element_.suggestedValue().utf8()));
980 EXPECT_TRUE(username_element_.isAutofilled());
981 EXPECT_EQ(
982 kCarolPassword,
983 static_cast<std::string>(password_element_.suggestedValue().utf8()));
984 EXPECT_TRUE(password_element_.isAutofilled());
985 username_length = strlen(kBobUsername);
986 CheckUsernameSelection(0, username_length);
989 // Tests that |PreviewSuggestion| properly sets the username selection range.
990 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
991 username_element_.setValue(WebString::fromUTF8("ali"));
992 username_element_.setSelectionRange(3, 3);
993 username_element_.setAutofilled(true);
995 CheckTextFieldsDOMState("ali", true, std::string(), false);
997 // Simulate the browser sending the login info, but set |wait_for_username|
998 // to prevent the form from being immediately filled.
999 fill_data_.wait_for_username = true;
1000 SimulateOnFillPasswordForm(fill_data_);
1002 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1003 username_element_, kAliceUsername, kAlicePassword));
1004 EXPECT_EQ(
1005 kAliceUsername,
1006 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1007 EXPECT_TRUE(username_element_.isAutofilled());
1008 EXPECT_EQ(
1009 kAlicePassword,
1010 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1011 EXPECT_TRUE(password_element_.isAutofilled());
1012 int username_length = strlen(kAliceUsername);
1013 CheckUsernameSelection(3, username_length);
1016 // Tests that |ClearPreview| properly clears previewed username and password
1017 // with password being previously autofilled.
1018 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
1019 password_element_.setValue(WebString::fromUTF8("sec"));
1020 password_element_.setAutofilled(true);
1022 // Simulate the browser sending the login info, but set |wait_for_username|
1023 // to prevent the form from being immediately filled.
1024 fill_data_.wait_for_username = true;
1025 SimulateOnFillPasswordForm(fill_data_);
1027 CheckTextFieldsDOMState(std::string(), false, "sec", true);
1029 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1030 username_element_, kAliceUsername, kAlicePassword));
1032 EXPECT_TRUE(
1033 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1035 EXPECT_TRUE(username_element_.value().isEmpty());
1036 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1037 EXPECT_FALSE(username_element_.isAutofilled());
1038 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1039 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1040 EXPECT_TRUE(password_element_.isAutofilled());
1041 CheckUsernameSelection(0, 0);
1044 // Tests that |ClearPreview| properly clears previewed username and password
1045 // with username being previously autofilled.
1046 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
1047 username_element_.setValue(WebString::fromUTF8("ali"));
1048 username_element_.setSelectionRange(3, 3);
1049 username_element_.setAutofilled(true);
1051 // Simulate the browser sending the login info, but set |wait_for_username|
1052 // to prevent the form from being immediately filled.
1053 fill_data_.wait_for_username = true;
1054 SimulateOnFillPasswordForm(fill_data_);
1056 CheckTextFieldsDOMState("ali", true, std::string(), false);
1058 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1059 username_element_, kAliceUsername, kAlicePassword));
1061 EXPECT_TRUE(
1062 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1064 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1065 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1066 EXPECT_TRUE(username_element_.isAutofilled());
1067 EXPECT_TRUE(password_element_.value().isEmpty());
1068 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1069 EXPECT_FALSE(password_element_.isAutofilled());
1070 CheckUsernameSelection(3, 3);
1073 // Tests that |ClearPreview| properly clears previewed username and password
1074 // with username and password being previously autofilled.
1075 TEST_F(PasswordAutofillAgentTest,
1076 ClearPreviewWithAutofilledUsernameAndPassword) {
1077 username_element_.setValue(WebString::fromUTF8("ali"));
1078 username_element_.setSelectionRange(3, 3);
1079 username_element_.setAutofilled(true);
1080 password_element_.setValue(WebString::fromUTF8("sec"));
1081 password_element_.setAutofilled(true);
1083 // Simulate the browser sending the login info, but set |wait_for_username|
1084 // to prevent the form from being immediately filled.
1085 fill_data_.wait_for_username = true;
1086 SimulateOnFillPasswordForm(fill_data_);
1088 CheckTextFieldsDOMState("ali", true, "sec", true);
1090 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1091 username_element_, kAliceUsername, kAlicePassword));
1093 EXPECT_TRUE(
1094 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1096 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1097 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1098 EXPECT_TRUE(username_element_.isAutofilled());
1099 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1100 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1101 EXPECT_TRUE(password_element_.isAutofilled());
1102 CheckUsernameSelection(3, 3);
1105 // Tests that |ClearPreview| properly clears previewed username and password
1106 // with neither username nor password being previously autofilled.
1107 TEST_F(PasswordAutofillAgentTest,
1108 ClearPreviewWithNotAutofilledUsernameAndPassword) {
1109 // Simulate the browser sending the login info, but set |wait_for_username|
1110 // to prevent the form from being immediately filled.
1111 fill_data_.wait_for_username = true;
1112 SimulateOnFillPasswordForm(fill_data_);
1114 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1116 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1117 username_element_, kAliceUsername, kAlicePassword));
1119 EXPECT_TRUE(
1120 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1122 EXPECT_TRUE(username_element_.value().isEmpty());
1123 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1124 EXPECT_FALSE(username_element_.isAutofilled());
1125 EXPECT_TRUE(password_element_.value().isEmpty());
1126 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1127 EXPECT_FALSE(password_element_.isAutofilled());
1128 CheckUsernameSelection(0, 0);
1131 // Tests that logging is off by default.
1132 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1133 render_thread_->sink().ClearMessages();
1134 SendVisiblePasswordForms();
1135 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1136 AutofillHostMsg_RecordSavePasswordProgress::ID);
1137 EXPECT_FALSE(message);
1140 // Test that logging can be turned on by a message.
1141 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1142 // Turn the logging on.
1143 AutofillMsg_SetLoggingState msg_activate(0, true);
1144 // Up-cast to access OnMessageReceived, which is private in the agent.
1145 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1146 ->OnMessageReceived(msg_activate));
1148 render_thread_->sink().ClearMessages();
1149 SendVisiblePasswordForms();
1150 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1151 AutofillHostMsg_RecordSavePasswordProgress::ID);
1152 EXPECT_TRUE(message);
1155 // Test that logging can be turned off by a message.
1156 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1157 // Turn the logging on and then off.
1158 AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
1159 // Up-cast to access OnMessageReceived, which is private in the agent.
1160 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1161 ->OnMessageReceived(msg_activate));
1162 AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
1163 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1164 ->OnMessageReceived(msg_deactivate));
1166 render_thread_->sink().ClearMessages();
1167 SendVisiblePasswordForms();
1168 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1169 AutofillHostMsg_RecordSavePasswordProgress::ID);
1170 EXPECT_FALSE(message);
1173 // Test that the agent sends an IPC call to get the current activity state of
1174 // password saving logging soon after construction.
1175 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1176 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1177 AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1178 EXPECT_TRUE(message);
1181 // Tests that one user click on a username field is sufficient to bring up a
1182 // credential suggestion popup, and the user can autocomplete the password by
1183 // selecting the credential from the popup.
1184 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1185 // SimulateElementClick() is called so that a user gesture is actually made
1186 // and the password can be filled. However, SimulateElementClick() does not
1187 // actually lead to the AutofillAgent's InputElementClicked() method being
1188 // called, so SimulateSuggestionChoice has to manually call
1189 // InputElementClicked().
1190 ClearUsernameAndPasswordFields();
1191 SimulateOnFillPasswordForm(fill_data_);
1192 SimulateElementClick(kUsernameName);
1193 SimulateSuggestionChoice(username_element_);
1194 CheckSuggestions(kAliceUsername, true);
1196 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1199 // Tests the autosuggestions that are given when the element is clicked.
1200 // Specifically, tests when the user clicks on the username element after page
1201 // load and the element is autofilled, when the user clicks on an element that
1202 // has a non-matching username, and when the user clicks on an element that's
1203 // already been autofilled and they've already modified.
1204 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1205 // Simulate the browser sending back the login info.
1206 SimulateOnFillPasswordForm(fill_data_);
1208 // Clear the text fields to start fresh.
1209 ClearUsernameAndPasswordFields();
1211 // Call SimulateElementClick() to produce a user gesture on the page so
1212 // autofill will actually fill.
1213 SimulateElementClick(kUsernameName);
1215 // Simulate a user clicking on the username element. This should produce a
1216 // message with all the usernames.
1217 render_thread_->sink().ClearMessages();
1218 static_cast<PageClickListener*>(autofill_agent_)
1219 ->FormControlElementClicked(username_element_, false);
1220 CheckSuggestions(std::string(), false);
1222 // Now simulate a user typing in an unrecognized username and then
1223 // clicking on the username element. This should also produce a message with
1224 // all the usernames.
1225 SimulateUsernameChange("baz");
1226 render_thread_->sink().ClearMessages();
1227 static_cast<PageClickListener*>(autofill_agent_)
1228 ->FormControlElementClicked(username_element_, true);
1229 CheckSuggestions("baz", true);
1230 ClearUsernameAndPasswordFields();
1233 // Tests that there are no autosuggestions from the password manager when the
1234 // user clicks on the password field and the username field is editable when
1235 // FillOnAccountSelect is enabled.
1236 TEST_F(PasswordAutofillAgentTest,
1237 FillOnAccountSelectOnlyNoCredentialsOnPasswordClick) {
1238 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1239 autofill::switches::kEnableFillOnAccountSelect);
1241 // Simulate the browser sending back the login info.
1242 SimulateOnFillPasswordForm(fill_data_);
1244 // Clear the text fields to start fresh.
1245 ClearUsernameAndPasswordFields();
1247 // Call SimulateElementClick() to produce a user gesture on the page so
1248 // autofill will actually fill.
1249 SimulateElementClick(kUsernameName);
1251 // Simulate a user clicking on the password element. This should produce no
1252 // message.
1253 render_thread_->sink().ClearMessages();
1254 static_cast<PageClickListener*>(autofill_agent_)
1255 ->FormControlElementClicked(password_element_, false);
1256 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1257 AutofillHostMsg_ShowPasswordSuggestions::ID));
1260 // Tests the autosuggestions that are given when a password element is clicked,
1261 // the username element is not editable, and FillOnAccountSelect is enabled.
1262 // Specifically, tests when the user clicks on the password element after page
1263 // load, and the corresponding username element is readonly (and thus
1264 // uneditable), that the credentials for the already-filled username are
1265 // suggested.
1266 TEST_F(PasswordAutofillAgentTest,
1267 FillOnAccountSelectOnlyCredentialsOnPasswordClick) {
1268 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1269 autofill::switches::kEnableFillOnAccountSelect);
1271 // Simulate the browser sending back the login info.
1272 SimulateOnFillPasswordForm(fill_data_);
1274 // Clear the text fields to start fresh.
1275 ClearUsernameAndPasswordFields();
1277 // Simulate the page loading with a prefilled username element that is
1278 // uneditable.
1279 username_element_.setValue("alicia");
1280 SetElementReadOnly(username_element_, true);
1282 // Call SimulateElementClick() to produce a user gesture on the page so
1283 // autofill will actually fill.
1284 SimulateElementClick(kUsernameName);
1286 // Simulate a user clicking on the password element. This should produce a
1287 // message with "alicia" suggested as the credential.
1288 render_thread_->sink().ClearMessages();
1289 static_cast<PageClickListener*>(autofill_agent_)
1290 ->FormControlElementClicked(password_element_, false);
1291 CheckSuggestions("alicia", false);
1294 // Tests that there are no autosuggestions from the password manager when the
1295 // user clicks on the password field (not the username field).
1296 TEST_F(PasswordAutofillAgentTest, NoCredentialsOnPasswordClick) {
1297 // Simulate the browser sending back the login info.
1298 SimulateOnFillPasswordForm(fill_data_);
1300 // Clear the text fields to start fresh.
1301 ClearUsernameAndPasswordFields();
1303 // Call SimulateElementClick() to produce a user gesture on the page so
1304 // autofill will actually fill.
1305 SimulateElementClick(kUsernameName);
1307 // Simulate a user clicking on the password element. This should produce no
1308 // message.
1309 render_thread_->sink().ClearMessages();
1310 static_cast<PageClickListener*>(autofill_agent_)
1311 ->FormControlElementClicked(password_element_, false);
1312 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1313 AutofillHostMsg_ShowPasswordSuggestions::ID));
1316 // The user types in a username and a password, but then just before sending
1317 // the form off, a script clears them. This test checks that
1318 // PasswordAutofillAgent can still remember the username and the password
1319 // typed by the user.
1320 TEST_F(PasswordAutofillAgentTest,
1321 RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) {
1322 SimulateUsernameChange("temp");
1323 SimulatePasswordChange("random");
1325 // Simulate that the username and the password value was cleared by the
1326 // site's JavaScript before submit.
1327 username_element_.setValue(WebString());
1328 password_element_.setValue(WebString());
1329 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1330 ->WillSubmitForm(username_element_.form());
1332 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1333 // username and password and sent that to the browser.
1334 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1337 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time
1338 // it's the user who clears the username and the password. This test checks
1339 // that in that case, the last non-empty username and password are not
1340 // remembered.
1341 TEST_F(PasswordAutofillAgentTest,
1342 RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) {
1343 SimulateUsernameChange("temp");
1344 SimulatePasswordChange("random");
1346 // Simulate that the user actually cleared the username and password again.
1347 SimulateUsernameChange("");
1348 SimulatePasswordChange("");
1349 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1350 ->WillSubmitForm(username_element_.form());
1352 // Observe that the PasswordAutofillAgent respects the user having cleared the
1353 // password.
1354 ExpectFormSubmittedWithUsernameAndPasswords("", "", "");
1357 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the
1358 // new password instead of the current password.
1359 TEST_F(PasswordAutofillAgentTest,
1360 RememberLastNonEmptyUsernameAndPasswordOnSubmit_New) {
1361 const char kNewPasswordFormHTML[] =
1362 "<FORM name='LoginTestForm'>"
1363 " <INPUT type='text' id='username' autocomplete='username'/>"
1364 " <INPUT type='password' id='password' autocomplete='new-password'/>"
1365 " <INPUT type='submit' value='Login'/>"
1366 "</FORM>";
1367 LoadHTML(kNewPasswordFormHTML);
1368 UpdateUsernameAndPasswordElements();
1370 SimulateUsernameChange("temp");
1371 SimulatePasswordChange("random");
1373 // Simulate that the username and the password value was cleared by
1374 // the site's JavaScript before submit.
1375 username_element_.setValue(WebString());
1376 password_element_.setValue(WebString());
1377 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1378 ->WillSubmitForm(username_element_.form());
1380 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1381 // password and sent that to the browser.
1382 ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random");
1385 // The user first accepts a suggestion, but then overwrites the password. This
1386 // test checks that the overwritten password is not reverted back if the user
1387 // triggers autofill through focusing (but not changing) the username again.
1388 TEST_F(PasswordAutofillAgentTest,
1389 NoopEditingDoesNotOverwriteManuallyEditedPassword) {
1390 // Simulate having credentials which needed to wait until the user starts
1391 // typing the username to be filled (e.g., PSL-matched credentials). Those are
1392 // the ones which can be filled as a result of TextFieldDidEndEditing.
1393 fill_data_.wait_for_username = true;
1394 SimulateOnFillPasswordForm(fill_data_);
1395 // Simulate that the user typed her name to make the autofill work.
1396 SimulateUsernameChange(kAliceUsername);
1397 SimulateDidEndEditing(GetMainFrame(), username_element_);
1398 const std::string old_username(username_element_.value().utf8());
1399 const std::string old_password(password_element_.value().utf8());
1400 const std::string new_password(old_password + "modify");
1402 // The user changes the password.
1403 SimulatePasswordChange(new_password);
1405 // The user switches back into the username field, but leaves that without
1406 // changes.
1407 SimulateDidEndEditing(GetMainFrame(), username_element_);
1409 // The password should have stayed as the user changed it.
1410 CheckTextFieldsDOMState(old_username, true, new_password, false);
1411 // The password should not have a suggested value.
1412 CheckTextFieldsState(old_username, true, std::string(), false);
1415 // The user types in a username and a password, but then just before sending
1416 // the form off, a script changes them. This test checks that
1417 // PasswordAutofillAgent can still remember the username and the password
1418 // typed by the user.
1419 TEST_F(PasswordAutofillAgentTest,
1420 RememberLastTypedUsernameAndPasswordOnSubmit_ScriptChanged) {
1421 SimulateUsernameChange("temp");
1422 SimulatePasswordChange("random");
1424 // Simulate that the username and the password value was changed by the
1425 // site's JavaScript before submit.
1426 username_element_.setValue(WebString("new username"));
1427 password_element_.setValue(WebString("new password"));
1428 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1429 ->WillSendSubmitEvent(username_element_.form());
1430 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1431 ->WillSubmitForm(username_element_.form());
1433 // Observe that the PasswordAutofillAgent still remembered the last typed
1434 // username and password and sent that to the browser.
1435 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1438 // The username/password is autofilled by password manager then just before
1439 // sending the form off, a script changes them. This test checks that
1440 // PasswordAutofillAgent can still get the username and the password autofilled.
1441 TEST_F(PasswordAutofillAgentTest,
1442 RememberLastAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1443 SimulateOnFillPasswordForm(fill_data_);
1445 // Simulate that the username and the password value was changed by the
1446 // site's JavaScript before submit.
1447 username_element_.setValue(WebString("new username"));
1448 password_element_.setValue(WebString("new password"));
1449 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1450 ->WillSendSubmitEvent(username_element_.form());
1451 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1452 ->WillSubmitForm(username_element_.form());
1454 // Observe that the PasswordAutofillAgent still remembered the autofilled
1455 // username and password and sent that to the browser.
1456 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, kAlicePassword,
1457 "");
1460 // The username/password is autofilled by password manager then user types in a
1461 // username and a password. Then just before sending the form off, a script
1462 // changes them. This test checks that PasswordAutofillAgent can still remember
1463 // the username and the password typed by the user.
1464 TEST_F(
1465 PasswordAutofillAgentTest,
1466 RememberLastTypedAfterAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1467 SimulateOnFillPasswordForm(fill_data_);
1469 SimulateUsernameChange("temp");
1470 SimulatePasswordChange("random");
1472 // Simulate that the username and the password value was changed by the
1473 // site's JavaScript before submit.
1474 username_element_.setValue(WebString("new username"));
1475 password_element_.setValue(WebString("new password"));
1476 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1477 ->WillSendSubmitEvent(username_element_.form());
1478 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1479 ->WillSubmitForm(username_element_.form());
1481 // Observe that the PasswordAutofillAgent still remembered the last typed
1482 // username and password and sent that to the browser.
1483 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1486 // The user starts typing username then it is autofilled.
1487 // PasswordAutofillAgent should remember the username that was autofilled,
1488 // not last typed.
1489 TEST_F(PasswordAutofillAgentTest, RememberAutofilledUsername) {
1490 SimulateUsernameChange("Te");
1491 // Simulate that the username was changed by autofilling.
1492 username_element_.setValue(WebString("temp"));
1493 SimulatePasswordChange("random");
1495 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1496 ->WillSendSubmitEvent(username_element_.form());
1497 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1498 ->WillSubmitForm(username_element_.form());
1500 // Observe that the PasswordAutofillAgent still remembered the last typed
1501 // username and password and sent that to the browser.
1502 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1505 TEST_F(PasswordAutofillAgentTest, FormFillDataMustHaveUsername) {
1506 ClearUsernameAndPasswordFields();
1508 PasswordFormFillData no_username_fill_data = fill_data_;
1509 no_username_fill_data.username_field.name = base::string16();
1510 SimulateOnFillPasswordForm(no_username_fill_data);
1512 // The username and password should not have been autocompleted.
1513 CheckTextFieldsState("", false, "", false);
1516 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnly) {
1517 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1518 autofill::switches::kEnableFillOnAccountSelect);
1520 ClearUsernameAndPasswordFields();
1522 // Simulate the browser sending back the login info for an initial page load.
1523 SimulateOnFillPasswordForm(fill_data_);
1525 CheckTextFieldsState(std::string(), true, std::string(), false);
1528 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyReadonlyUsername) {
1529 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1530 autofill::switches::kEnableFillOnAccountSelect);
1532 ClearUsernameAndPasswordFields();
1534 username_element_.setValue("alice");
1535 SetElementReadOnly(username_element_, true);
1537 // Simulate the browser sending back the login info for an initial page load.
1538 SimulateOnFillPasswordForm(fill_data_);
1540 CheckTextFieldsState(std::string("alice"), false, std::string(), true);
1543 TEST_F(PasswordAutofillAgentTest,
1544 FillOnAccountSelectOnlyReadonlyNotPreferredUsername) {
1545 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1546 autofill::switches::kEnableFillOnAccountSelect);
1548 ClearUsernameAndPasswordFields();
1550 username_element_.setValue("Carol");
1551 SetElementReadOnly(username_element_, true);
1553 // Simulate the browser sending back the login info for an initial page load.
1554 SimulateOnFillPasswordForm(fill_data_);
1556 CheckTextFieldsState(std::string("Carol"), false, std::string(), true);
1559 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) {
1560 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1561 autofill::switches::kEnableFillOnAccountSelect);
1563 // Load a form with no username and update test data.
1564 LoadHTML(kVisibleFormWithNoUsernameHTML);
1565 username_element_.reset();
1566 WebDocument document = GetMainFrame()->document();
1567 WebElement element =
1568 document.getElementById(WebString::fromUTF8(kPasswordName));
1569 ASSERT_FALSE(element.isNull());
1570 password_element_ = element.to<blink::WebInputElement>();
1571 fill_data_.username_field = FormFieldData();
1572 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1573 fill_data_.additional_logins.clear();
1574 fill_data_.other_possible_usernames.clear();
1576 password_element_.setValue("");
1577 password_element_.setAutofilled(false);
1579 // Simulate the browser sending back the login info for an initial page load.
1580 SimulateOnFillPasswordForm(fill_data_);
1582 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1583 EXPECT_TRUE(password_element_.isAutofilled());
1586 TEST_F(PasswordAutofillAgentTest, ShowPopupNoUsername) {
1587 // Load a form with no username and update test data.
1588 LoadHTML(kVisibleFormWithNoUsernameHTML);
1589 username_element_.reset();
1590 WebDocument document = GetMainFrame()->document();
1591 WebElement element =
1592 document.getElementById(WebString::fromUTF8(kPasswordName));
1593 ASSERT_FALSE(element.isNull());
1594 password_element_ = element.to<blink::WebInputElement>();
1595 fill_data_.username_field = FormFieldData();
1596 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1597 fill_data_.additional_logins.clear();
1598 fill_data_.other_possible_usernames.clear();
1600 password_element_.setValue("");
1601 password_element_.setAutofilled(false);
1603 // Simulate the browser sending back the login info for an initial page load.
1604 SimulateOnFillPasswordForm(fill_data_);
1606 password_element_.setValue("123");
1607 password_element_.setAutofilled(false);
1609 SimulateSuggestionChoiceOfUsernameAndPassword(
1610 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword));
1611 CheckSuggestions(std::string(), false);
1612 EXPECT_EQ(ASCIIToUTF16(kAlicePassword), password_element_.value());
1613 EXPECT_TRUE(password_element_.isAutofilled());
1616 // Tests with fill-on-account-select enabled that if the username element is
1617 // read-only and filled with an unknown username, then the password field is not
1618 // highlighted as autofillable (regression test for https://crbug.com/442564).
1619 TEST_F(PasswordAutofillAgentTest,
1620 FillOnAccountSelectOnlyReadonlyUnknownUsername) {
1621 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1622 autofill::switches::kEnableFillOnAccountSelect);
1624 ClearUsernameAndPasswordFields();
1626 username_element_.setValue("foobar");
1627 SetElementReadOnly(username_element_, true);
1629 CheckTextFieldsState(std::string("foobar"), false, std::string(), false);
1632 // Test that the last plain text field before a password field is chosen as a
1633 // username, in a form with 2 plain text fields without username predictions.
1634 TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) {
1635 LoadHTML(kFormHTMLWithTwoTextFields);
1636 UpdateUsernameAndPasswordElements();
1637 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1638 SimulateUsernameChange("temp");
1639 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1640 SimulatePasswordChange("random");
1641 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1642 ->WillSendSubmitEvent(username_element_.form());
1643 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1644 ->WillSubmitForm(username_element_.form());
1646 // Observe that the PasswordAutofillAgent identifies the second field (e-mail)
1647 // as username.
1648 ExpectFormSubmittedWithUsernameAndPasswords("temp@google.com", "random", "");
1651 // Tests that field predictions are followed when identifying the username
1652 // and password in a password form with two plain text fields.
1653 TEST_F(PasswordAutofillAgentTest, FindingFieldsWithAutofillPredictions) {
1654 LoadHTML(kFormHTMLWithTwoTextFields);
1655 UpdateUsernameAndPasswordElements();
1656 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1657 SimulateUsernameChange("temp");
1658 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1659 SimulatePasswordChange("random");
1660 // Find FormData for visible password form.
1661 blink::WebFormElement form_element = username_element_.form();
1662 FormData form_data;
1663 ASSERT_TRUE(WebFormElementToFormData(form_element,
1664 blink::WebFormControlElement(),
1665 EXTRACT_NONE, &form_data, nullptr));
1666 // Simulate Autofill predictions: the first field is username, the third
1667 // one is password.
1668 std::map<autofill::FormData, PasswordFormFieldPredictionMap> predictions;
1669 predictions[form_data][PREDICTION_USERNAME] = form_data.fields[0];
1670 predictions[form_data][PREDICTION_NEW_PASSWORD] = form_data.fields[2];
1671 AutofillMsg_AutofillUsernameAndPasswordDataReceived msg(0, predictions);
1672 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1673 ->OnMessageReceived(msg);
1675 // The predictions should still match even if the form changes, as long
1676 // as the particular elements don't change.
1677 std::string add_field_to_form =
1678 "var form = document.getElementById('LoginTestForm');"
1679 "var new_input = document.createElement('input');"
1680 "new_input.setAttribute('type', 'text');"
1681 "new_input.setAttribute('id', 'other_field');"
1682 "form.appendChild(new_input);";
1683 ExecuteJavaScriptForTests(add_field_to_form.c_str());
1685 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1686 ->WillSendSubmitEvent(username_element_.form());
1687 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1688 ->WillSubmitForm(username_element_.form());
1690 // Observe that the PasswordAutofillAgent identifies the first field as
1691 // username.
1692 // TODO(msramek): We should also test that adding another password field
1693 // won't override the password field prediction either. However, the password
1694 // field predictions are not taken into account yet.
1695 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1698 // The user types in a username and a password. Then JavaScript changes password
1699 // field to readonly state before submit. PasswordAutofillAgent can correctly
1700 // process readonly password field. This test models behaviour of gmail.com.
1701 TEST_F(PasswordAutofillAgentTest, ReadonlyPasswordFieldOnSubmit) {
1702 SimulateUsernameChange("temp");
1703 SimulatePasswordChange("random");
1705 // Simulate that JavaScript makes password field readonly.
1706 SetElementReadOnly(password_element_, true);
1707 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1708 ->WillSubmitForm(username_element_.form());
1710 // Observe that the PasswordAutofillAgent can correctly process submitted
1711 // form.
1712 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1715 // Verify that typed passwords are saved correctly when autofill and generation
1716 // both trigger. Regression test for https://crbug.com/493455
1717 TEST_F(PasswordAutofillAgentTest, PasswordGenerationTriggered_TypedPassword) {
1718 SimulateOnFillPasswordForm(fill_data_);
1720 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1721 SetAccountCreationFormsDetectedMessage(password_generation_,
1722 GetMainFrame()->document(),
1725 SimulateUsernameChange("NewGuy");
1726 SimulatePasswordChange("NewPassword");
1727 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1728 ->WillSendSubmitEvent(username_element_.form());
1729 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1730 ->WillSubmitForm(username_element_.form());
1732 ExpectFormSubmittedWithUsernameAndPasswords("NewGuy", "NewPassword", "");
1735 // Verify that generated passwords are saved correctly when autofill and
1736 // generation both trigger. Regression test for https://crbug.com/493455.
1737 TEST_F(PasswordAutofillAgentTest,
1738 PasswordGenerationTriggered_GeneratedPassword) {
1739 SimulateOnFillPasswordForm(fill_data_);
1741 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1742 SetAccountCreationFormsDetectedMessage(password_generation_,
1743 GetMainFrame()->document(),
1746 base::string16 password = base::ASCIIToUTF16("NewPass22");
1747 AutofillMsg_GeneratedPasswordAccepted msg(0, password);
1748 password_generation_->OnMessageReceived(msg);
1750 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1751 ->WillSendSubmitEvent(username_element_.form());
1752 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1753 ->WillSubmitForm(username_element_.form());
1755 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, "NewPass22", "");
1758 // If password generation is enabled for a field, password autofill should not
1759 // show UI.
1760 TEST_F(PasswordAutofillAgentTest, PasswordGenerationSupersedesAutofill) {
1761 LoadHTML(kSignupFormHTML);
1763 // Update password_element_;
1764 WebDocument document = GetMainFrame()->document();
1765 WebElement element =
1766 document.getElementById(WebString::fromUTF8("new_password"));
1767 ASSERT_FALSE(element.isNull());
1768 password_element_ = element.to<blink::WebInputElement>();
1770 // Update fill_data_ for the new form and simulate filling. Pretend as if
1771 // the password manager didn't detect a username field so it will try to
1772 // show UI when the password field is focused.
1773 fill_data_.wait_for_username = true;
1774 fill_data_.username_field = FormFieldData();
1775 fill_data_.password_field.name = base::ASCIIToUTF16("new_password");
1776 UpdateOriginForHTML(kSignupFormHTML);
1777 SimulateOnFillPasswordForm(fill_data_);
1779 // Simulate generation triggering.
1780 SetNotBlacklistedMessage(password_generation_,
1781 kSignupFormHTML);
1782 SetAccountCreationFormsDetectedMessage(password_generation_,
1783 GetMainFrame()->document(),
1786 // Simulate the field being clicked to start typing. This should trigger
1787 // generation but not password autofill.
1788 SetFocused(password_element_);
1789 SimulateElementClick("new_password");
1790 EXPECT_EQ(nullptr,
1791 render_thread_->sink().GetFirstMessageMatching(
1792 AutofillHostMsg_ShowPasswordSuggestions::ID));
1793 ExpectPasswordGenerationAvailable(password_generation_, true);
1796 // Tests that a password change form is properly filled with the username and
1797 // password.
1798 TEST_F(PasswordAutofillAgentTest, FillSuggestionPasswordChangeForms) {
1799 LoadHTML(kPasswordChangeFormHTML);
1800 UpdateOriginForHTML(kPasswordChangeFormHTML);
1801 UpdateUsernameAndPasswordElements();
1802 // Simulate the browser sending the login info, but set |wait_for_username|
1803 // to prevent the form from being immediately filled.
1804 fill_data_.wait_for_username = true;
1805 fill_data_.is_possible_change_password_form = true;
1806 SimulateOnFillPasswordForm(fill_data_);
1808 // Neither field should have been autocompleted.
1809 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1811 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1812 username_element_, kAliceUsername, kAlicePassword));
1813 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1816 // Tests that a password change form is properly filled with the password when
1817 // the user click on the password field.
1818 TEST_F(PasswordAutofillAgentTest,
1819 FillSuggestionPasswordChangeFormsOnlyPassword) {
1820 LoadHTML(kPasswordChangeFormHTML);
1821 UpdateOriginForHTML(kPasswordChangeFormHTML);
1822 UpdateUsernameAndPasswordElements();
1823 // Simulate the browser sending the login info, but set |wait_for_username|
1824 // to prevent the form from being immediately filled.
1825 fill_data_.wait_for_username = true;
1826 fill_data_.is_possible_change_password_form = true;
1827 SimulateOnFillPasswordForm(fill_data_);
1829 // Neither field should have been autocompleted.
1830 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1832 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1833 password_element_, kAliceUsername, kAlicePassword));
1834 CheckTextFieldsDOMState("", false, kAlicePassword, true);
1837 // Tests that one user click on a username field is sufficient to bring up a
1838 // credential suggestion popup on a change password form.
1839 TEST_F(PasswordAutofillAgentTest,
1840 SuggestionsOnUsernameFieldOfChangePasswordForm) {
1841 LoadHTML(kPasswordChangeFormHTML);
1842 UpdateOriginForHTML(kPasswordChangeFormHTML);
1843 UpdateUsernameAndPasswordElements();
1845 ClearUsernameAndPasswordFields();
1846 fill_data_.wait_for_username = true;
1847 fill_data_.is_possible_change_password_form = true;
1848 SimulateOnFillPasswordForm(fill_data_);
1849 // Simulate a user clicking on the username element. This should produce a
1850 // message.
1851 render_thread_->sink().ClearMessages();
1852 static_cast<PageClickListener*>(autofill_agent_)
1853 ->FormControlElementClicked(username_element_, true);
1854 CheckSuggestions("", true);
1857 // Tests that one user click on a password field is sufficient to bring up a
1858 // credential suggestion popup on a change password form.
1859 TEST_F(PasswordAutofillAgentTest,
1860 SuggestionsOnPasswordFieldOfChangePasswordForm) {
1861 LoadHTML(kPasswordChangeFormHTML);
1862 UpdateOriginForHTML(kPasswordChangeFormHTML);
1863 UpdateUsernameAndPasswordElements();
1865 ClearUsernameAndPasswordFields();
1866 fill_data_.wait_for_username = true;
1867 fill_data_.is_possible_change_password_form = true;
1868 SimulateOnFillPasswordForm(fill_data_);
1869 // Simulate a user clicking on the password element. This should produce a
1870 // message.
1871 render_thread_->sink().ClearMessages();
1872 static_cast<PageClickListener*>(autofill_agent_)
1873 ->FormControlElementClicked(password_element_, true);
1874 CheckSuggestions("", false);
1877 // Tests that there are no autosuggestions from the password manager when the
1878 // user clicks on the password field of change password form after the user
1879 // typed in the username field.
1880 TEST_F(PasswordAutofillAgentTest,
1881 NoSuggestionsOnPasswordFieldOfChangePasswordFormAfterUsernameTyping) {
1882 LoadHTML(kPasswordChangeFormHTML);
1883 UpdateOriginForHTML(kPasswordChangeFormHTML);
1884 UpdateUsernameAndPasswordElements();
1886 ClearUsernameAndPasswordFields();
1887 fill_data_.wait_for_username = true;
1888 fill_data_.is_possible_change_password_form = true;
1889 SimulateOnFillPasswordForm(fill_data_);
1891 // Clear the text fields to start fresh.
1892 SimulateUsernameChange("temp");
1894 // Simulate a user clicking on the password element. This should produce no
1895 // message.
1896 render_thread_->sink().ClearMessages();
1897 static_cast<PageClickListener*>(autofill_agent_)
1898 ->FormControlElementClicked(password_element_, false);
1899 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1900 AutofillHostMsg_ShowPasswordSuggestions::ID));
1903 } // namespace autofill