Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / chrome / renderer / autofill / password_autofill_agent_browsertest.cc
blob01562c4c97913e6b23967874cb226a119dfc9f68
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";
52 const char kCreditCardOwnerName[] = "creditcardowner";
53 const char kCreditCardNumberName[] = "creditcardnumber";
54 const char kCreditCardVerificationName[] = "cvc";
56 const char kAliceUsername[] = "alice";
57 const char kAlicePassword[] = "password";
58 const char kBobUsername[] = "bob";
59 const char kBobPassword[] = "secret";
60 const char kCarolUsername[] = "Carol";
61 const char kCarolPassword[] = "test";
62 const char kCarolAlternateUsername[] = "RealCarolUsername";
64 const char kFormHTML[] =
65 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
66 " <INPUT type='text' id='random_field'/>"
67 " <INPUT type='text' id='username'/>"
68 " <INPUT type='password' id='password'/>"
69 " <INPUT type='submit' value='Login'/>"
70 "</FORM>";
72 const char kVisibleFormWithNoUsernameHTML[] =
73 "<head> <style> form {display: inline;} </style> </head>"
74 "<body>"
75 " <form name='LoginTestForm' action='http://www.bidule.com'>"
76 " <div>"
77 " <input type='password' id='password'/>"
78 " </div>"
79 " </form>"
80 "</body>";
82 const char kEmptyFormHTML[] =
83 "<head> <style> form {display: inline;} </style> </head>"
84 "<body> <form> </form> </body>";
86 const char kNonVisibleFormHTML[] =
87 "<head> <style> form {display: none;} </style> </head>"
88 "<body>"
89 " <form>"
90 " <div>"
91 " <input type='password' id='password'/>"
92 " </div>"
93 " </form>"
94 "</body>";
96 const char kSignupFormHTML[] =
97 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
98 " <INPUT type='text' id='random_info'/>"
99 " <INPUT type='password' id='new_password'/>"
100 " <INPUT type='password' id='confirm_password'/>"
101 " <INPUT type='submit' value='Login'/>"
102 "</FORM>";
104 const char kEmptyWebpage[] =
105 "<html>"
106 " <head>"
107 " </head>"
108 " <body>"
109 " </body>"
110 "</html>";
112 const char kRedirectionWebpage[] =
113 "<html>"
114 " <head>"
115 " <meta http-equiv='Content-Type' content='text/html'>"
116 " <title>Redirection page</title>"
117 " <script></script>"
118 " </head>"
119 " <body>"
120 " <script type='text/javascript'>"
121 " function test(){}"
122 " </script>"
123 " </body>"
124 "</html>";
126 const char kSimpleWebpage[] =
127 "<html>"
128 " <head>"
129 " <meta charset='utf-8' />"
130 " <title>Title</title>"
131 " </head>"
132 " <body>"
133 " <form name='LoginTestForm'>"
134 " <input type='text' id='username'/>"
135 " <input type='password' id='password'/>"
136 " <input type='submit' value='Login'/>"
137 " </form>"
138 " </body>"
139 "</html>";
141 const char kWebpageWithDynamicContent[] =
142 "<html>"
143 " <head>"
144 " <meta charset='utf-8' />"
145 " <title>Title</title>"
146 " </head>"
147 " <body>"
148 " <script type='text/javascript'>"
149 " function addParagraph() {"
150 " var p = document.createElement('p');"
151 " document.body.appendChild(p);"
152 " }"
153 " window.onload = addParagraph;"
154 " </script>"
155 " </body>"
156 "</html>";
158 const char kJavaScriptClick[] =
159 "var event = new MouseEvent('click', {"
160 " 'view': window,"
161 " 'bubbles': true,"
162 " 'cancelable': true"
163 "});"
164 "var form = document.getElementById('myform1');"
165 "form.dispatchEvent(event);"
166 "console.log('clicked!');";
168 const char kOnChangeDetectionScript[] =
169 "<script>"
170 " usernameOnchangeCalled = false;"
171 " passwordOnchangeCalled = false;"
172 " document.getElementById('username').onchange = function() {"
173 " usernameOnchangeCalled = true;"
174 " };"
175 " document.getElementById('password').onchange = function() {"
176 " passwordOnchangeCalled = true;"
177 " };"
178 "</script>";
180 const char kFormHTMLWithTwoTextFields[] =
181 "<FORM name='LoginTestForm' id='LoginTestForm' "
182 "action='http://www.bidule.com'>"
183 " <INPUT type='text' id='username'/>"
184 " <INPUT type='text' id='email'/>"
185 " <INPUT type='password' id='password'/>"
186 " <INPUT type='submit' value='Login'/>"
187 "</FORM>";
189 const char kPasswordChangeFormHTML[] =
190 "<FORM name='ChangeWithUsernameForm' action='http://www.bidule.com'>"
191 " <INPUT type='text' id='username'/>"
192 " <INPUT type='password' id='password'/>"
193 " <INPUT type='password' id='newpassword'/>"
194 " <INPUT type='password' id='confirmpassword'/>"
195 " <INPUT type='submit' value='Login'/>"
196 "</FORM>";
198 const char kCreditCardFormHTML[] =
199 "<FORM name='ChangeWithUsernameForm' action='http://www.bidule.com'>"
200 " <INPUT type='text' id='creditcardowner'/>"
201 " <INPUT type='text' id='creditcardnumber'/>"
202 " <INPUT type='password' id='cvc'/>"
203 " <INPUT type='submit' value='Submit'/>"
204 "</FORM>";
206 const char kNoFormHTML[] =
207 " <INPUT type='text' id='username'/>"
208 " <INPUT type='password' id='password'/>";
210 // Sets the "readonly" attribute of |element| to the value given by |read_only|.
211 void SetElementReadOnly(WebInputElement& element, bool read_only) {
212 element.setAttribute(WebString::fromUTF8("readonly"),
213 read_only ? WebString::fromUTF8("true") : WebString());
216 } // namespace
218 namespace autofill {
220 class PasswordAutofillAgentTest : public ChromeRenderViewTest {
221 public:
222 PasswordAutofillAgentTest() {
225 // Simulates the fill password form message being sent to the renderer.
226 // We use that so we don't have to make RenderView::OnFillPasswordForm()
227 // protected.
228 void SimulateOnFillPasswordForm(
229 const PasswordFormFillData& fill_data) {
230 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data);
231 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
232 ->OnMessageReceived(msg);
235 // As above, but fills for an iframe.
236 void SimulateOnFillPasswordFormForFrame(
237 WebFrame* frame,
238 const PasswordFormFillData& fill_data) {
239 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data);
240 content::RenderFrame::FromWebFrame(frame)->OnMessageReceived(msg);
243 void SendVisiblePasswordForms() {
244 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
245 ->DidFinishLoad();
248 void SetUp() override {
249 ChromeRenderViewTest::SetUp();
251 // Add a preferred login and an additional login to the FillData.
252 username1_ = ASCIIToUTF16(kAliceUsername);
253 password1_ = ASCIIToUTF16(kAlicePassword);
254 username2_ = ASCIIToUTF16(kBobUsername);
255 password2_ = ASCIIToUTF16(kBobPassword);
256 username3_ = ASCIIToUTF16(kCarolUsername);
257 password3_ = ASCIIToUTF16(kCarolPassword);
258 alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
260 FormFieldData username_field;
261 username_field.name = ASCIIToUTF16(kUsernameName);
262 username_field.value = username1_;
263 fill_data_.username_field = username_field;
265 FormFieldData password_field;
266 password_field.name = ASCIIToUTF16(kPasswordName);
267 password_field.value = password1_;
268 password_field.form_control_type = "password";
269 fill_data_.password_field = password_field;
271 PasswordAndRealm password2;
272 password2.password = password2_;
273 fill_data_.additional_logins[username2_] = password2;
274 PasswordAndRealm password3;
275 password3.password = password3_;
276 fill_data_.additional_logins[username3_] = password3;
278 UsernamesCollectionKey key;
279 key.username = username3_;
280 key.password = password3_;
281 key.realm = "google.com";
282 fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
284 // We need to set the origin so it matches the frame URL and the action so
285 // it matches the form action, otherwise we won't autocomplete.
286 UpdateOriginForHTML(kFormHTML);
287 fill_data_.action = GURL("http://www.bidule.com");
289 LoadHTML(kFormHTML);
291 // Necessary for SimulateElementClick() to work correctly.
292 GetWebWidget()->resize(blink::WebSize(500, 500));
293 GetWebWidget()->setFocus(true);
295 // Now retrieve the input elements so the test can access them.
296 UpdateUsernameAndPasswordElements();
299 void TearDown() override {
300 username_element_.reset();
301 password_element_.reset();
302 ChromeRenderViewTest::TearDown();
305 void UpdateOriginForHTML(const std::string& html) {
306 std::string origin = "data:text/html;charset=utf-8," + html;
307 fill_data_.origin = GURL(origin);
310 void UpdateUsernameAndPasswordElements() {
311 WebDocument document = GetMainFrame()->document();
312 WebElement element =
313 document.getElementById(WebString::fromUTF8(kUsernameName));
314 ASSERT_FALSE(element.isNull());
315 username_element_ = element.to<blink::WebInputElement>();
316 element = document.getElementById(WebString::fromUTF8(kPasswordName));
317 ASSERT_FALSE(element.isNull());
318 password_element_ = element.to<blink::WebInputElement>();
321 blink::WebInputElement GetInputElementByID(const std::string& id) {
322 WebDocument document = GetMainFrame()->document();
323 WebElement element =
324 document.getElementById(WebString::fromUTF8(id.c_str()));
325 return element.to<blink::WebInputElement>();
328 void ClearUsernameAndPasswordFields() {
329 username_element_.setValue("");
330 username_element_.setAutofilled(false);
331 password_element_.setValue("");
332 password_element_.setAutofilled(false);
335 void SimulateDidEndEditing(WebFrame* input_frame, WebInputElement& input) {
336 static_cast<blink::WebAutofillClient*>(autofill_agent_)
337 ->textFieldDidEndEditing(input);
340 void SimulateSuggestionChoice(WebInputElement& username_input) {
341 base::string16 username(base::ASCIIToUTF16(kAliceUsername));
342 base::string16 password(base::ASCIIToUTF16(kAlicePassword));
343 SimulateSuggestionChoiceOfUsernameAndPassword(username_input, username,
344 password);
347 void SimulateSuggestionChoiceOfUsernameAndPassword(
348 WebInputElement& input,
349 const base::string16& username,
350 const base::string16& password) {
351 // This call is necessary to setup the autofill agent appropriate for the
352 // user selection; simulates the menu actually popping up.
353 render_thread_->sink().ClearMessages();
354 static_cast<autofill::PageClickListener*>(autofill_agent_)
355 ->FormControlElementClicked(input, false);
357 AutofillMsg_FillPasswordSuggestion msg(0, username, password);
358 static_cast<content::RenderFrameObserver*>(autofill_agent_)
359 ->OnMessageReceived(msg);
362 void SimulateUsernameChange(const std::string& username) {
363 SimulateUserInputChangeForElement(&username_element_, username);
366 void SimulatePasswordChange(const std::string& password) {
367 SimulateUserInputChangeForElement(&password_element_, password);
370 void CheckTextFieldsStateForElements(const WebInputElement& username_element,
371 const std::string& username,
372 bool username_autofilled,
373 const WebInputElement& password_element,
374 const std::string& password,
375 bool password_autofilled,
376 bool checkSuggestedValue) {
377 EXPECT_EQ(username,
378 static_cast<std::string>(username_element.value().utf8()));
379 EXPECT_EQ(username_autofilled, username_element.isAutofilled());
380 EXPECT_EQ(password,
381 static_cast<std::string>(
382 checkSuggestedValue ? password_element.suggestedValue().utf8()
383 : password_element.value().utf8()))
384 << "checkSuggestedValue == " << checkSuggestedValue;
385 EXPECT_EQ(password_autofilled, password_element.isAutofilled());
388 // Checks the DOM-accessible value of the username element and the
389 // *suggested* value of the password element.
390 void CheckTextFieldsState(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 true);
403 // Checks the DOM-accessible value of the username element and the
404 // DOM-accessible value of the password element.
405 void CheckTextFieldsDOMState(const std::string& username,
406 bool username_autofilled,
407 const std::string& password,
408 bool password_autofilled) {
409 CheckTextFieldsStateForElements(username_element_,
410 username,
411 username_autofilled,
412 password_element_,
413 password,
414 password_autofilled,
415 false);
418 void CheckUsernameSelection(int start, int end) {
419 EXPECT_EQ(start, username_element_.selectionStart());
420 EXPECT_EQ(end, username_element_.selectionEnd());
423 // Checks the message sent to PasswordAutofillManager to build the suggestion
424 // list. |username| is the expected username field value, and |show_all| is
425 // the expected flag for the PasswordAutofillManager, whether to show all
426 // suggestions, or only those starting with |username|.
427 void CheckSuggestions(const std::string& username, bool show_all) {
428 const IPC::Message* message =
429 render_thread_->sink().GetFirstMessageMatching(
430 AutofillHostMsg_ShowPasswordSuggestions::ID);
431 ASSERT_TRUE(message);
432 base::Tuple<int, base::i18n::TextDirection, base::string16, int, gfx::RectF>
433 args;
434 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
435 EXPECT_EQ(kPasswordFillFormDataId, base::get<0>(args));
436 EXPECT_EQ(ASCIIToUTF16(username), base::get<2>(args));
437 EXPECT_EQ(show_all,
438 static_cast<bool>(base::get<3>(args) & autofill::SHOW_ALL));
440 render_thread_->sink().ClearMessages();
443 void ExpectFormSubmittedWithUsernameAndPasswords(
444 const std::string& username_value,
445 const std::string& password_value,
446 const std::string& new_password_value) {
447 const IPC::Message* message =
448 render_thread_->sink().GetFirstMessageMatching(
449 AutofillHostMsg_PasswordFormSubmitted::ID);
450 ASSERT_TRUE(message);
451 base::Tuple<autofill::PasswordForm> args;
452 AutofillHostMsg_PasswordFormSubmitted::Read(message, &args);
453 EXPECT_EQ(ASCIIToUTF16(username_value), base::get<0>(args).username_value);
454 EXPECT_EQ(ASCIIToUTF16(password_value), base::get<0>(args).password_value);
455 EXPECT_EQ(ASCIIToUTF16(new_password_value),
456 base::get<0>(args).new_password_value);
459 void ExpectInPageNavigationWithUsernameAndPasswords(
460 const std::string& username_value,
461 const std::string& password_value,
462 const std::string& new_password_value) {
463 const IPC::Message* message =
464 render_thread_->sink().GetFirstMessageMatching(
465 AutofillHostMsg_InPageNavigation::ID);
466 ASSERT_TRUE(message);
467 base::Tuple<autofill::PasswordForm> args;
468 AutofillHostMsg_InPageNavigation::Read(message, &args);
469 EXPECT_EQ(ASCIIToUTF16(username_value), base::get<0>(args).username_value);
470 EXPECT_EQ(ASCIIToUTF16(password_value), base::get<0>(args).password_value);
471 EXPECT_EQ(ASCIIToUTF16(new_password_value),
472 base::get<0>(args).new_password_value);
475 base::string16 username1_;
476 base::string16 username2_;
477 base::string16 username3_;
478 base::string16 password1_;
479 base::string16 password2_;
480 base::string16 password3_;
481 base::string16 alternate_username3_;
482 PasswordFormFillData fill_data_;
484 WebInputElement username_element_;
485 WebInputElement password_element_;
487 private:
488 DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
491 // Tests that the password login is autocompleted as expected when the browser
492 // sends back the password info.
493 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
495 * Right now we are not sending the message to the browser because we are
496 * loading a data URL and the security origin canAccessPasswordManager()
497 * returns false. May be we should mock URL loading to cirmcuvent this?
498 TODO(jcivelli): find a way to make the security origin not deny access to the
499 password manager and then reenable this code.
501 // The form has been loaded, we should have sent the browser a message about
502 // the form.
503 const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
504 AutofillHostMsg_PasswordFormsParsed::ID);
505 ASSERT_TRUE(msg != NULL);
507 base::Tuple1<std::vector<PasswordForm> > forms;
508 AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
509 ASSERT_EQ(1U, forms.a.size());
510 PasswordForm password_form = forms.a[0];
511 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
512 EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
513 EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
516 // Simulate the browser sending back the login info, it triggers the
517 // autocomplete.
518 SimulateOnFillPasswordForm(fill_data_);
520 // The username and password should have been autocompleted.
521 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
524 // Tests that we correctly fill forms having an empty 'action' attribute.
525 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
526 const char kEmptyActionFormHTML[] =
527 "<FORM name='LoginTestForm'>"
528 " <INPUT type='text' id='username'/>"
529 " <INPUT type='password' id='password'/>"
530 " <INPUT type='submit' value='Login'/>"
531 "</FORM>";
532 LoadHTML(kEmptyActionFormHTML);
534 // Retrieve the input elements so the test can access them.
535 WebDocument document = GetMainFrame()->document();
536 WebElement element =
537 document.getElementById(WebString::fromUTF8(kUsernameName));
538 ASSERT_FALSE(element.isNull());
539 username_element_ = element.to<blink::WebInputElement>();
540 element = document.getElementById(WebString::fromUTF8(kPasswordName));
541 ASSERT_FALSE(element.isNull());
542 password_element_ = element.to<blink::WebInputElement>();
544 // Set the expected form origin and action URLs.
545 UpdateOriginForHTML(kEmptyActionFormHTML);
546 fill_data_.action = fill_data_.origin;
548 // Simulate the browser sending back the login info, it triggers the
549 // autocomplete.
550 SimulateOnFillPasswordForm(fill_data_);
552 // The username and password should have been autocompleted.
553 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
556 // Tests that if a password is marked as readonly, neither field is autofilled
557 // on page load.
558 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
559 SetElementReadOnly(password_element_, true);
561 // Simulate the browser sending back the login info, it triggers the
562 // autocomplete.
563 SimulateOnFillPasswordForm(fill_data_);
565 CheckTextFieldsState(std::string(), false, std::string(), false);
568 // Can still fill a password field if the username is set to a value that
569 // matches.
570 TEST_F(PasswordAutofillAgentTest,
571 AutocompletePasswordForReadonlyUsernameMatched) {
572 username_element_.setValue(username3_);
573 SetElementReadOnly(username_element_, true);
575 // Filled even though username is not the preferred match.
576 SimulateOnFillPasswordForm(fill_data_);
577 CheckTextFieldsState(UTF16ToUTF8(username3_), false,
578 UTF16ToUTF8(password3_), true);
581 // If a username field is empty and readonly, don't autofill.
582 TEST_F(PasswordAutofillAgentTest,
583 NoAutocompletePasswordForReadonlyUsernameUnmatched) {
584 username_element_.setValue(WebString::fromUTF8(""));
585 SetElementReadOnly(username_element_, true);
587 SimulateOnFillPasswordForm(fill_data_);
588 CheckTextFieldsState(std::string(), false, std::string(), false);
591 // Tests that having a non-matching username precludes the autocomplete.
592 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
593 username_element_.setValue(WebString::fromUTF8("bogus"));
595 // Simulate the browser sending back the login info, it triggers the
596 // autocomplete.
597 SimulateOnFillPasswordForm(fill_data_);
599 // Neither field should be autocompleted.
600 CheckTextFieldsState("bogus", false, std::string(), false);
603 // Don't try to complete a prefilled value even if it's a partial match
604 // to a username.
605 TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
606 username_element_.setValue(WebString::fromUTF8("ali"));
608 SimulateOnFillPasswordForm(fill_data_);
610 CheckTextFieldsState("ali", false, std::string(), false);
613 TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
614 const char kNoFormInputs[] =
615 "<input type='text' id='username'/>"
616 "<input type='password' id='password'/>";
617 LoadHTML(kNoFormInputs);
619 SimulateOnFillPasswordForm(fill_data_);
621 // Input elements that aren't in a <form> won't autofill.
622 CheckTextFieldsState(std::string(), false, std::string(), false);
625 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
626 const char kTextFieldPasswordFormHTML[] =
627 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
628 " <INPUT type='text' id='username'/>"
629 " <INPUT type='text' id='password'/>"
630 " <INPUT type='submit' value='Login'/>"
631 "</FORM>";
632 LoadHTML(kTextFieldPasswordFormHTML);
634 // Retrieve the input elements so the test can access them.
635 WebDocument document = GetMainFrame()->document();
636 WebElement element =
637 document.getElementById(WebString::fromUTF8(kUsernameName));
638 ASSERT_FALSE(element.isNull());
639 username_element_ = element.to<blink::WebInputElement>();
640 element = document.getElementById(WebString::fromUTF8(kPasswordName));
641 ASSERT_FALSE(element.isNull());
642 password_element_ = element.to<blink::WebInputElement>();
644 // Set the expected form origin URL.
645 UpdateOriginForHTML(kTextFieldPasswordFormHTML);
647 SimulateOnFillPasswordForm(fill_data_);
649 // Fields should still be empty.
650 CheckTextFieldsState(std::string(), false, std::string(), false);
653 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
654 const char kPasswordFieldUsernameFormHTML[] =
655 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
656 " <INPUT type='password' id='username'/>"
657 " <INPUT type='password' id='password'/>"
658 " <INPUT type='submit' value='Login'/>"
659 "</FORM>";
660 LoadHTML(kPasswordFieldUsernameFormHTML);
662 // Retrieve the input elements so the test can access them.
663 WebDocument document = GetMainFrame()->document();
664 WebElement element =
665 document.getElementById(WebString::fromUTF8(kUsernameName));
666 ASSERT_FALSE(element.isNull());
667 username_element_ = element.to<blink::WebInputElement>();
668 element = document.getElementById(WebString::fromUTF8(kPasswordName));
669 ASSERT_FALSE(element.isNull());
670 password_element_ = element.to<blink::WebInputElement>();
672 // Set the expected form origin URL.
673 UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
675 SimulateOnFillPasswordForm(fill_data_);
677 // Fields should still be empty.
678 CheckTextFieldsState(std::string(), false, std::string(), false);
681 // Tests that having a matching username does not preclude the autocomplete.
682 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
683 username_element_.setValue(WebString::fromUTF8(kAliceUsername));
685 // Simulate the browser sending back the login info, it triggers the
686 // autocomplete.
687 SimulateOnFillPasswordForm(fill_data_);
689 // The username and password should have been autocompleted.
690 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
693 TEST_F(PasswordAutofillAgentTest, PasswordNotClearedOnEdit) {
694 // Simulate the browser sending back the login info, it triggers the
695 // autocomplete.
696 SimulateOnFillPasswordForm(fill_data_);
698 // Simulate the user changing the username to some unknown username.
699 SimulateUsernameChange("alicia");
701 // The password should not have been cleared.
702 CheckTextFieldsDOMState("alicia", false, kAlicePassword, true);
705 // Tests that we only autocomplete on focus lost and with a full username match
706 // when |wait_for_username| is true.
707 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
708 // Simulate the browser sending back the login info.
709 fill_data_.wait_for_username = true;
710 SimulateOnFillPasswordForm(fill_data_);
712 // No auto-fill should have taken place.
713 CheckTextFieldsState(std::string(), false, std::string(), false);
715 // No autocomplete should happen when text is entered in the username.
716 SimulateUsernameChange("a");
717 CheckTextFieldsState("a", false, std::string(), false);
718 SimulateUsernameChange("al");
719 CheckTextFieldsState("al", false, std::string(), false);
720 SimulateUsernameChange(kAliceUsername);
721 CheckTextFieldsState(kAliceUsername, false, std::string(), false);
723 // Autocomplete should happen only when the username textfield is blurred with
724 // a full match.
725 SimulateUsernameChange("a");
726 static_cast<blink::WebAutofillClient*>(autofill_agent_)
727 ->textFieldDidEndEditing(username_element_);
728 CheckTextFieldsState("a", false, std::string(), false);
729 SimulateUsernameChange("al");
730 static_cast<blink::WebAutofillClient*>(autofill_agent_)
731 ->textFieldDidEndEditing(username_element_);
732 CheckTextFieldsState("al", false, std::string(), false);
733 SimulateUsernameChange("alices");
734 static_cast<blink::WebAutofillClient*>(autofill_agent_)
735 ->textFieldDidEndEditing(username_element_);
736 CheckTextFieldsState("alices", false, std::string(), false);
737 SimulateUsernameChange(kAliceUsername);
738 static_cast<blink::WebAutofillClient*>(autofill_agent_)
739 ->textFieldDidEndEditing(username_element_);
740 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
743 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
744 blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
745 blink::WebFrame* frame;
747 LoadHTML(kVisibleFormWithNoUsernameHTML);
748 frame = GetMainFrame();
749 frame->document().forms(forms1);
750 ASSERT_EQ(1u, forms1.size());
751 EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
753 LoadHTML(kEmptyFormHTML);
754 frame = GetMainFrame();
755 frame->document().forms(forms2);
756 ASSERT_EQ(1u, forms2.size());
757 EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
759 LoadHTML(kNonVisibleFormHTML);
760 frame = GetMainFrame();
761 frame->document().forms(forms3);
762 ASSERT_EQ(1u, forms3.size());
763 EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
766 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
767 render_thread_->sink().ClearMessages();
768 LoadHTML(kVisibleFormWithNoUsernameHTML);
769 const IPC::Message* message = render_thread_->sink()
770 .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
771 EXPECT_TRUE(message);
772 base::Tuple<std::vector<autofill::PasswordForm>, bool> param;
773 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
774 EXPECT_TRUE(base::get<0>(param).size());
776 render_thread_->sink().ClearMessages();
777 LoadHTML(kEmptyFormHTML);
778 message = render_thread_->sink().GetFirstMessageMatching(
779 AutofillHostMsg_PasswordFormsRendered::ID);
780 EXPECT_TRUE(message);
781 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
782 EXPECT_FALSE(base::get<0>(param).size());
784 render_thread_->sink().ClearMessages();
785 LoadHTML(kNonVisibleFormHTML);
786 message = render_thread_->sink().GetFirstMessageMatching(
787 AutofillHostMsg_PasswordFormsRendered::ID);
788 EXPECT_TRUE(message);
789 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
790 EXPECT_FALSE(base::get<0>(param).size());
793 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
794 render_thread_->sink().ClearMessages();
795 LoadHTML(kEmptyWebpage);
796 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
797 AutofillHostMsg_PasswordFormsRendered::ID));
799 render_thread_->sink().ClearMessages();
800 LoadHTML(kRedirectionWebpage);
801 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
802 AutofillHostMsg_PasswordFormsRendered::ID));
804 render_thread_->sink().ClearMessages();
805 LoadHTML(kSimpleWebpage);
806 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
807 AutofillHostMsg_PasswordFormsRendered::ID));
809 render_thread_->sink().ClearMessages();
810 LoadHTML(kWebpageWithDynamicContent);
811 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
812 AutofillHostMsg_PasswordFormsRendered::ID));
815 // Tests that a password will only be filled as a suggested and will not be
816 // accessible by the DOM until a user gesture has occurred.
817 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
818 // Trigger the initial autocomplete.
819 SimulateOnFillPasswordForm(fill_data_);
821 // The username and password should have been autocompleted.
822 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
824 // However, it should only have completed with the suggested value, as tested
825 // above, and it should not have completed into the DOM accessible value for
826 // the password field.
827 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
829 // Simulate a user click so that the password field's real value is filled.
830 SimulateElementClick(kUsernameName);
831 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
834 // Verfies that a DOM-activated UI event will not cause an autofill.
835 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
836 // Trigger the initial autocomplete.
837 SimulateOnFillPasswordForm(fill_data_);
839 ExecuteJavaScriptForTests(kJavaScriptClick);
840 CheckTextFieldsDOMState(kAliceUsername, true, "", true);
843 // Verifies that password autofill triggers onChange events in JavaScript for
844 // forms that are filled on page load.
845 TEST_F(PasswordAutofillAgentTest,
846 PasswordAutofillTriggersOnChangeEventsOnLoad) {
847 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
848 LoadHTML(html.c_str());
849 UpdateOriginForHTML(html);
850 UpdateUsernameAndPasswordElements();
852 // Simulate the browser sending back the login info, it triggers the
853 // autocomplete.
854 SimulateOnFillPasswordForm(fill_data_);
856 // The username and password should have been autocompleted...
857 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
858 // ... but since there hasn't been a user gesture yet, the autocompleted
859 // password should only be visible to the user.
860 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
862 // A JavaScript onChange event should have been triggered for the username,
863 // but not yet for the password.
864 int username_onchange_called = -1;
865 int password_onchange_called = -1;
866 ASSERT_TRUE(
867 ExecuteJavaScriptAndReturnIntValue(
868 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
869 &username_onchange_called));
870 EXPECT_EQ(1, username_onchange_called);
871 ASSERT_TRUE(
872 ExecuteJavaScriptAndReturnIntValue(
873 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
874 &password_onchange_called));
875 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
876 // EXPECT_EQ(0, password_onchange_called);
878 // Simulate a user click so that the password field's real value is filled.
879 SimulateElementClick(kUsernameName);
880 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
882 // Now, a JavaScript onChange event should have been triggered for the
883 // password as well.
884 ASSERT_TRUE(
885 ExecuteJavaScriptAndReturnIntValue(
886 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
887 &password_onchange_called));
888 EXPECT_EQ(1, password_onchange_called);
891 // Verifies that password autofill triggers onChange events in JavaScript for
892 // forms that are filled after page load.
893 TEST_F(PasswordAutofillAgentTest,
894 PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
895 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
896 LoadHTML(html.c_str());
897 UpdateOriginForHTML(html);
898 UpdateUsernameAndPasswordElements();
900 // Simulate the browser sending back the login info, it triggers the
901 // autocomplete.
902 fill_data_.wait_for_username = true;
903 SimulateOnFillPasswordForm(fill_data_);
905 // The username and password should not yet have been autocompleted.
906 CheckTextFieldsState(std::string(), false, std::string(), false);
908 // Simulate a click just to force a user gesture, since the username value is
909 // set directly.
910 SimulateElementClick(kUsernameName);
912 // Simulate the user entering the first letter of her username and selecting
913 // the matching autofill from the dropdown.
914 SimulateUsernameChange("a");
915 SimulateSuggestionChoice(username_element_);
917 // The username and password should now have been autocompleted.
918 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
920 // JavaScript onChange events should have been triggered both for the username
921 // and for the password.
922 int username_onchange_called = -1;
923 int password_onchange_called = -1;
924 ASSERT_TRUE(
925 ExecuteJavaScriptAndReturnIntValue(
926 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
927 &username_onchange_called));
928 EXPECT_EQ(1, username_onchange_called);
929 ASSERT_TRUE(
930 ExecuteJavaScriptAndReturnIntValue(
931 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
932 &password_onchange_called));
933 EXPECT_EQ(1, password_onchange_called);
936 // Tests that |FillSuggestion| properly fills the username and password.
937 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
938 // Simulate the browser sending the login info, but set |wait_for_username|
939 // to prevent the form from being immediately filled.
940 fill_data_.wait_for_username = true;
941 SimulateOnFillPasswordForm(fill_data_);
943 // Neither field should have been autocompleted.
944 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
946 // If the password field is not autocompletable, it should not be affected.
947 SetElementReadOnly(password_element_, true);
948 EXPECT_FALSE(password_autofill_agent_->FillSuggestion(
949 username_element_, kAliceUsername, kAlicePassword));
950 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
951 SetElementReadOnly(password_element_, false);
953 // After filling with the suggestion, both fields should be autocompleted.
954 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
955 username_element_, kAliceUsername, kAlicePassword));
956 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
957 int username_length = strlen(kAliceUsername);
958 CheckUsernameSelection(username_length, username_length);
960 // Try Filling with a suggestion with password different from the one that was
961 // initially sent to the renderer.
962 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
963 username_element_, kBobUsername, kCarolPassword));
964 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
965 username_length = strlen(kBobUsername);
966 CheckUsernameSelection(username_length, username_length);
969 // Tests that |PreviewSuggestion| properly previews the username and password.
970 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
971 // Simulate the browser sending the login info, but set |wait_for_username|
972 // to prevent the form from being immediately filled.
973 fill_data_.wait_for_username = true;
974 SimulateOnFillPasswordForm(fill_data_);
976 // Neither field should have been autocompleted.
977 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
979 // If the password field is not autocompletable, it should not be affected.
980 SetElementReadOnly(password_element_, true);
981 EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion(
982 username_element_, kAliceUsername, kAlicePassword));
983 EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
984 EXPECT_FALSE(username_element_.isAutofilled());
985 EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
986 EXPECT_FALSE(password_element_.isAutofilled());
987 SetElementReadOnly(password_element_, false);
989 // After selecting the suggestion, both fields should be previewed
990 // with suggested values.
991 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
992 username_element_, kAliceUsername, kAlicePassword));
993 EXPECT_EQ(
994 kAliceUsername,
995 static_cast<std::string>(username_element_.suggestedValue().utf8()));
996 EXPECT_TRUE(username_element_.isAutofilled());
997 EXPECT_EQ(
998 kAlicePassword,
999 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1000 EXPECT_TRUE(password_element_.isAutofilled());
1001 int username_length = strlen(kAliceUsername);
1002 CheckUsernameSelection(0, username_length);
1004 // Try previewing with a password different from the one that was initially
1005 // sent to the renderer.
1006 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1007 username_element_, kBobUsername, kCarolPassword));
1008 EXPECT_EQ(
1009 kBobUsername,
1010 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1011 EXPECT_TRUE(username_element_.isAutofilled());
1012 EXPECT_EQ(
1013 kCarolPassword,
1014 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1015 EXPECT_TRUE(password_element_.isAutofilled());
1016 username_length = strlen(kBobUsername);
1017 CheckUsernameSelection(0, username_length);
1020 // Tests that |PreviewSuggestion| properly sets the username selection range.
1021 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
1022 username_element_.setValue(WebString::fromUTF8("ali"));
1023 username_element_.setSelectionRange(3, 3);
1024 username_element_.setAutofilled(true);
1026 CheckTextFieldsDOMState("ali", true, std::string(), false);
1028 // Simulate the browser sending the login info, but set |wait_for_username|
1029 // to prevent the form from being immediately filled.
1030 fill_data_.wait_for_username = true;
1031 SimulateOnFillPasswordForm(fill_data_);
1033 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1034 username_element_, kAliceUsername, kAlicePassword));
1035 EXPECT_EQ(
1036 kAliceUsername,
1037 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1038 EXPECT_TRUE(username_element_.isAutofilled());
1039 EXPECT_EQ(
1040 kAlicePassword,
1041 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1042 EXPECT_TRUE(password_element_.isAutofilled());
1043 int username_length = strlen(kAliceUsername);
1044 CheckUsernameSelection(3, username_length);
1047 // Tests that |ClearPreview| properly clears previewed username and password
1048 // with password being previously autofilled.
1049 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
1050 password_element_.setValue(WebString::fromUTF8("sec"));
1051 password_element_.setAutofilled(true);
1053 // Simulate the browser sending the login info, but set |wait_for_username|
1054 // to prevent the form from being immediately filled.
1055 fill_data_.wait_for_username = true;
1056 SimulateOnFillPasswordForm(fill_data_);
1058 CheckTextFieldsDOMState(std::string(), false, "sec", true);
1060 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1061 username_element_, kAliceUsername, kAlicePassword));
1063 EXPECT_TRUE(
1064 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1066 EXPECT_TRUE(username_element_.value().isEmpty());
1067 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1068 EXPECT_FALSE(username_element_.isAutofilled());
1069 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1070 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1071 EXPECT_TRUE(password_element_.isAutofilled());
1072 CheckUsernameSelection(0, 0);
1075 // Tests that |ClearPreview| properly clears previewed username and password
1076 // with username being previously autofilled.
1077 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
1078 username_element_.setValue(WebString::fromUTF8("ali"));
1079 username_element_.setSelectionRange(3, 3);
1080 username_element_.setAutofilled(true);
1082 // Simulate the browser sending the login info, but set |wait_for_username|
1083 // to prevent the form from being immediately filled.
1084 fill_data_.wait_for_username = true;
1085 SimulateOnFillPasswordForm(fill_data_);
1087 CheckTextFieldsDOMState("ali", true, std::string(), false);
1089 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1090 username_element_, kAliceUsername, kAlicePassword));
1092 EXPECT_TRUE(
1093 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1095 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1096 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1097 EXPECT_TRUE(username_element_.isAutofilled());
1098 EXPECT_TRUE(password_element_.value().isEmpty());
1099 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1100 EXPECT_FALSE(password_element_.isAutofilled());
1101 CheckUsernameSelection(3, 3);
1104 // Tests that |ClearPreview| properly clears previewed username and password
1105 // with username and password being previously autofilled.
1106 TEST_F(PasswordAutofillAgentTest,
1107 ClearPreviewWithAutofilledUsernameAndPassword) {
1108 username_element_.setValue(WebString::fromUTF8("ali"));
1109 username_element_.setSelectionRange(3, 3);
1110 username_element_.setAutofilled(true);
1111 password_element_.setValue(WebString::fromUTF8("sec"));
1112 password_element_.setAutofilled(true);
1114 // Simulate the browser sending the login info, but set |wait_for_username|
1115 // to prevent the form from being immediately filled.
1116 fill_data_.wait_for_username = true;
1117 SimulateOnFillPasswordForm(fill_data_);
1119 CheckTextFieldsDOMState("ali", true, "sec", true);
1121 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1122 username_element_, kAliceUsername, kAlicePassword));
1124 EXPECT_TRUE(
1125 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1127 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1128 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1129 EXPECT_TRUE(username_element_.isAutofilled());
1130 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1131 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1132 EXPECT_TRUE(password_element_.isAutofilled());
1133 CheckUsernameSelection(3, 3);
1136 // Tests that |ClearPreview| properly clears previewed username and password
1137 // with neither username nor password being previously autofilled.
1138 TEST_F(PasswordAutofillAgentTest,
1139 ClearPreviewWithNotAutofilledUsernameAndPassword) {
1140 // Simulate the browser sending the login info, but set |wait_for_username|
1141 // to prevent the form from being immediately filled.
1142 fill_data_.wait_for_username = true;
1143 SimulateOnFillPasswordForm(fill_data_);
1145 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1147 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1148 username_element_, kAliceUsername, kAlicePassword));
1150 EXPECT_TRUE(
1151 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1153 EXPECT_TRUE(username_element_.value().isEmpty());
1154 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1155 EXPECT_FALSE(username_element_.isAutofilled());
1156 EXPECT_TRUE(password_element_.value().isEmpty());
1157 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1158 EXPECT_FALSE(password_element_.isAutofilled());
1159 CheckUsernameSelection(0, 0);
1162 // Tests that logging is off by default.
1163 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1164 render_thread_->sink().ClearMessages();
1165 SendVisiblePasswordForms();
1166 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1167 AutofillHostMsg_RecordSavePasswordProgress::ID);
1168 EXPECT_FALSE(message);
1171 // Test that logging can be turned on by a message.
1172 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1173 // Turn the logging on.
1174 AutofillMsg_SetLoggingState msg_activate(0, true);
1175 // Up-cast to access OnMessageReceived, which is private in the agent.
1176 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1177 ->OnMessageReceived(msg_activate));
1179 render_thread_->sink().ClearMessages();
1180 SendVisiblePasswordForms();
1181 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1182 AutofillHostMsg_RecordSavePasswordProgress::ID);
1183 EXPECT_TRUE(message);
1186 // Test that logging can be turned off by a message.
1187 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1188 // Turn the logging on and then off.
1189 AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
1190 // Up-cast to access OnMessageReceived, which is private in the agent.
1191 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1192 ->OnMessageReceived(msg_activate));
1193 AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
1194 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1195 ->OnMessageReceived(msg_deactivate));
1197 render_thread_->sink().ClearMessages();
1198 SendVisiblePasswordForms();
1199 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1200 AutofillHostMsg_RecordSavePasswordProgress::ID);
1201 EXPECT_FALSE(message);
1204 // Test that the agent sends an IPC call to get the current activity state of
1205 // password saving logging soon after construction.
1206 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1207 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1208 AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1209 EXPECT_TRUE(message);
1212 // Tests that one user click on a username field is sufficient to bring up a
1213 // credential suggestion popup, and the user can autocomplete the password by
1214 // selecting the credential from the popup.
1215 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1216 // SimulateElementClick() is called so that a user gesture is actually made
1217 // and the password can be filled. However, SimulateElementClick() does not
1218 // actually lead to the AutofillAgent's InputElementClicked() method being
1219 // called, so SimulateSuggestionChoice has to manually call
1220 // InputElementClicked().
1221 ClearUsernameAndPasswordFields();
1222 SimulateOnFillPasswordForm(fill_data_);
1223 SimulateElementClick(kUsernameName);
1224 SimulateSuggestionChoice(username_element_);
1225 CheckSuggestions(kAliceUsername, true);
1227 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1230 // Tests the autosuggestions that are given when the element is clicked.
1231 // Specifically, tests when the user clicks on the username element after page
1232 // load and the element is autofilled, when the user clicks on an element that
1233 // has a non-matching username, and when the user clicks on an element that's
1234 // already been autofilled and they've already modified.
1235 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1236 // Simulate the browser sending back the login info.
1237 SimulateOnFillPasswordForm(fill_data_);
1239 // Clear the text fields to start fresh.
1240 ClearUsernameAndPasswordFields();
1242 // Call SimulateElementClick() to produce a user gesture on the page so
1243 // autofill will actually fill.
1244 SimulateElementClick(kUsernameName);
1246 // Simulate a user clicking on the username element. This should produce a
1247 // message with all the usernames.
1248 render_thread_->sink().ClearMessages();
1249 static_cast<PageClickListener*>(autofill_agent_)
1250 ->FormControlElementClicked(username_element_, false);
1251 CheckSuggestions(std::string(), false);
1253 // Now simulate a user typing in an unrecognized username and then
1254 // clicking on the username element. This should also produce a message with
1255 // all the usernames.
1256 SimulateUsernameChange("baz");
1257 render_thread_->sink().ClearMessages();
1258 static_cast<PageClickListener*>(autofill_agent_)
1259 ->FormControlElementClicked(username_element_, true);
1260 CheckSuggestions("baz", true);
1261 ClearUsernameAndPasswordFields();
1264 // Tests that there are no autosuggestions from the password manager when the
1265 // user clicks on the password field and the username field is editable when
1266 // FillOnAccountSelect is enabled.
1267 TEST_F(PasswordAutofillAgentTest,
1268 FillOnAccountSelectOnlyNoCredentialsOnPasswordClick) {
1269 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1270 autofill::switches::kEnableFillOnAccountSelect);
1272 // Simulate the browser sending back the login info.
1273 SimulateOnFillPasswordForm(fill_data_);
1275 // Clear the text fields to start fresh.
1276 ClearUsernameAndPasswordFields();
1278 // Call SimulateElementClick() to produce a user gesture on the page so
1279 // autofill will actually fill.
1280 SimulateElementClick(kUsernameName);
1282 // Simulate a user clicking on the password element. This should produce no
1283 // message.
1284 render_thread_->sink().ClearMessages();
1285 static_cast<PageClickListener*>(autofill_agent_)
1286 ->FormControlElementClicked(password_element_, false);
1287 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1288 AutofillHostMsg_ShowPasswordSuggestions::ID));
1291 // Tests the autosuggestions that are given when a password element is clicked,
1292 // the username element is not editable, and FillOnAccountSelect is enabled.
1293 // Specifically, tests when the user clicks on the password element after page
1294 // load, and the corresponding username element is readonly (and thus
1295 // uneditable), that the credentials for the already-filled username are
1296 // suggested.
1297 TEST_F(PasswordAutofillAgentTest,
1298 FillOnAccountSelectOnlyCredentialsOnPasswordClick) {
1299 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1300 autofill::switches::kEnableFillOnAccountSelect);
1302 // Simulate the browser sending back the login info.
1303 SimulateOnFillPasswordForm(fill_data_);
1305 // Clear the text fields to start fresh.
1306 ClearUsernameAndPasswordFields();
1308 // Simulate the page loading with a prefilled username element that is
1309 // uneditable.
1310 username_element_.setValue("alicia");
1311 SetElementReadOnly(username_element_, true);
1313 // Call SimulateElementClick() to produce a user gesture on the page so
1314 // autofill will actually fill.
1315 SimulateElementClick(kUsernameName);
1317 // Simulate a user clicking on the password element. This should produce a
1318 // message with "alicia" suggested as the credential.
1319 render_thread_->sink().ClearMessages();
1320 static_cast<PageClickListener*>(autofill_agent_)
1321 ->FormControlElementClicked(password_element_, false);
1322 CheckSuggestions("alicia", false);
1325 // Tests that there are no autosuggestions from the password manager when the
1326 // user clicks on the password field (not the username field).
1327 TEST_F(PasswordAutofillAgentTest, NoCredentialsOnPasswordClick) {
1328 // Simulate the browser sending back the login info.
1329 SimulateOnFillPasswordForm(fill_data_);
1331 // Clear the text fields to start fresh.
1332 ClearUsernameAndPasswordFields();
1334 // Call SimulateElementClick() to produce a user gesture on the page so
1335 // autofill will actually fill.
1336 SimulateElementClick(kUsernameName);
1338 // Simulate a user clicking on the password element. This should produce no
1339 // message.
1340 render_thread_->sink().ClearMessages();
1341 static_cast<PageClickListener*>(autofill_agent_)
1342 ->FormControlElementClicked(password_element_, false);
1343 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1344 AutofillHostMsg_ShowPasswordSuggestions::ID));
1347 // The user types in a username and a password, but then just before sending
1348 // the form off, a script clears them. This test checks that
1349 // PasswordAutofillAgent can still remember the username and the password
1350 // typed by the user.
1351 TEST_F(PasswordAutofillAgentTest,
1352 RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) {
1353 SimulateUsernameChange("temp");
1354 SimulatePasswordChange("random");
1356 // Simulate that the username and the password value was cleared by the
1357 // site's JavaScript before submit.
1358 username_element_.setValue(WebString());
1359 password_element_.setValue(WebString());
1360 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1361 ->WillSubmitForm(username_element_.form());
1363 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1364 // username and password and sent that to the browser.
1365 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1368 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time
1369 // it's the user who clears the username and the password. This test checks
1370 // that in that case, the last non-empty username and password are not
1371 // remembered.
1372 TEST_F(PasswordAutofillAgentTest,
1373 RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) {
1374 SimulateUsernameChange("temp");
1375 SimulatePasswordChange("random");
1377 // Simulate that the user actually cleared the username and password again.
1378 SimulateUsernameChange("");
1379 SimulatePasswordChange("");
1380 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1381 ->WillSubmitForm(username_element_.form());
1383 // Observe that the PasswordAutofillAgent respects the user having cleared the
1384 // password.
1385 ExpectFormSubmittedWithUsernameAndPasswords("", "", "");
1388 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the
1389 // new password instead of the current password.
1390 TEST_F(PasswordAutofillAgentTest,
1391 RememberLastNonEmptyUsernameAndPasswordOnSubmit_New) {
1392 const char kNewPasswordFormHTML[] =
1393 "<FORM name='LoginTestForm'>"
1394 " <INPUT type='text' id='username' autocomplete='username'/>"
1395 " <INPUT type='password' id='password' autocomplete='new-password'/>"
1396 " <INPUT type='submit' value='Login'/>"
1397 "</FORM>";
1398 LoadHTML(kNewPasswordFormHTML);
1399 UpdateUsernameAndPasswordElements();
1401 SimulateUsernameChange("temp");
1402 SimulatePasswordChange("random");
1404 // Simulate that the username and the password value was cleared by
1405 // the site's JavaScript before submit.
1406 username_element_.setValue(WebString());
1407 password_element_.setValue(WebString());
1408 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1409 ->WillSubmitForm(username_element_.form());
1411 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1412 // password and sent that to the browser.
1413 ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random");
1416 // The user first accepts a suggestion, but then overwrites the password. This
1417 // test checks that the overwritten password is not reverted back if the user
1418 // triggers autofill through focusing (but not changing) the username again.
1419 TEST_F(PasswordAutofillAgentTest,
1420 NoopEditingDoesNotOverwriteManuallyEditedPassword) {
1421 // Simulate having credentials which needed to wait until the user starts
1422 // typing the username to be filled (e.g., PSL-matched credentials). Those are
1423 // the ones which can be filled as a result of TextFieldDidEndEditing.
1424 fill_data_.wait_for_username = true;
1425 SimulateOnFillPasswordForm(fill_data_);
1426 // Simulate that the user typed her name to make the autofill work.
1427 SimulateUsernameChange(kAliceUsername);
1428 SimulateDidEndEditing(GetMainFrame(), username_element_);
1429 const std::string old_username(username_element_.value().utf8());
1430 const std::string old_password(password_element_.value().utf8());
1431 const std::string new_password(old_password + "modify");
1433 // The user changes the password.
1434 SimulatePasswordChange(new_password);
1436 // The user switches back into the username field, but leaves that without
1437 // changes.
1438 SimulateDidEndEditing(GetMainFrame(), username_element_);
1440 // The password should have stayed as the user changed it.
1441 CheckTextFieldsDOMState(old_username, true, new_password, false);
1442 // The password should not have a suggested value.
1443 CheckTextFieldsState(old_username, true, std::string(), false);
1446 // The user types in a username and a password, but then just before sending
1447 // the form off, a script changes them. This test checks that
1448 // PasswordAutofillAgent can still remember the username and the password
1449 // typed by the user.
1450 TEST_F(PasswordAutofillAgentTest,
1451 RememberLastTypedUsernameAndPasswordOnSubmit_ScriptChanged) {
1452 SimulateUsernameChange("temp");
1453 SimulatePasswordChange("random");
1455 // Simulate that the username and the password value was changed by the
1456 // site's JavaScript before submit.
1457 username_element_.setValue(WebString("new username"));
1458 password_element_.setValue(WebString("new password"));
1459 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1460 ->WillSendSubmitEvent(username_element_.form());
1461 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1462 ->WillSubmitForm(username_element_.form());
1464 // Observe that the PasswordAutofillAgent still remembered the last typed
1465 // username and password and sent that to the browser.
1466 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1469 // The username/password is autofilled by password manager then just before
1470 // sending the form off, a script changes them. This test checks that
1471 // PasswordAutofillAgent can still get the username and the password autofilled.
1472 TEST_F(PasswordAutofillAgentTest,
1473 RememberLastAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1474 SimulateOnFillPasswordForm(fill_data_);
1476 // Simulate that the username and the password value was changed by the
1477 // site's JavaScript before submit.
1478 username_element_.setValue(WebString("new username"));
1479 password_element_.setValue(WebString("new password"));
1480 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1481 ->WillSendSubmitEvent(username_element_.form());
1482 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1483 ->WillSubmitForm(username_element_.form());
1485 // Observe that the PasswordAutofillAgent still remembered the autofilled
1486 // username and password and sent that to the browser.
1487 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, kAlicePassword,
1488 "");
1491 // The username/password is autofilled by password manager then user types in a
1492 // username and a password. Then just before sending the form off, a script
1493 // changes them. This test checks that PasswordAutofillAgent can still remember
1494 // the username and the password typed by the user.
1495 TEST_F(
1496 PasswordAutofillAgentTest,
1497 RememberLastTypedAfterAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1498 SimulateOnFillPasswordForm(fill_data_);
1500 SimulateUsernameChange("temp");
1501 SimulatePasswordChange("random");
1503 // Simulate that the username and the password value was changed by the
1504 // site's JavaScript before submit.
1505 username_element_.setValue(WebString("new username"));
1506 password_element_.setValue(WebString("new password"));
1507 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1508 ->WillSendSubmitEvent(username_element_.form());
1509 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1510 ->WillSubmitForm(username_element_.form());
1512 // Observe that the PasswordAutofillAgent still remembered the last typed
1513 // username and password and sent that to the browser.
1514 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1517 // The user starts typing username then it is autofilled.
1518 // PasswordAutofillAgent should remember the username that was autofilled,
1519 // not last typed.
1520 TEST_F(PasswordAutofillAgentTest, RememberAutofilledUsername) {
1521 SimulateUsernameChange("Te");
1522 // Simulate that the username was changed by autofilling.
1523 username_element_.setValue(WebString("temp"));
1524 SimulatePasswordChange("random");
1526 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1527 ->WillSendSubmitEvent(username_element_.form());
1528 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1529 ->WillSubmitForm(username_element_.form());
1531 // Observe that the PasswordAutofillAgent still remembered the last typed
1532 // username and password and sent that to the browser.
1533 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1536 TEST_F(PasswordAutofillAgentTest, FormFillDataMustHaveUsername) {
1537 ClearUsernameAndPasswordFields();
1539 PasswordFormFillData no_username_fill_data = fill_data_;
1540 no_username_fill_data.username_field.name = base::string16();
1541 SimulateOnFillPasswordForm(no_username_fill_data);
1543 // The username and password should not have been autocompleted.
1544 CheckTextFieldsState("", false, "", false);
1547 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnly) {
1548 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1549 autofill::switches::kEnableFillOnAccountSelect);
1551 ClearUsernameAndPasswordFields();
1553 // Simulate the browser sending back the login info for an initial page load.
1554 SimulateOnFillPasswordForm(fill_data_);
1556 CheckTextFieldsState(std::string(), true, std::string(), false);
1559 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyReadonlyUsername) {
1560 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1561 autofill::switches::kEnableFillOnAccountSelect);
1563 ClearUsernameAndPasswordFields();
1565 username_element_.setValue("alice");
1566 SetElementReadOnly(username_element_, true);
1568 // Simulate the browser sending back the login info for an initial page load.
1569 SimulateOnFillPasswordForm(fill_data_);
1571 CheckTextFieldsState(std::string("alice"), false, std::string(), true);
1574 TEST_F(PasswordAutofillAgentTest,
1575 FillOnAccountSelectOnlyReadonlyNotPreferredUsername) {
1576 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1577 autofill::switches::kEnableFillOnAccountSelect);
1579 ClearUsernameAndPasswordFields();
1581 username_element_.setValue("Carol");
1582 SetElementReadOnly(username_element_, true);
1584 // Simulate the browser sending back the login info for an initial page load.
1585 SimulateOnFillPasswordForm(fill_data_);
1587 CheckTextFieldsState(std::string("Carol"), false, std::string(), true);
1590 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) {
1591 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1592 autofill::switches::kEnableFillOnAccountSelect);
1594 // Load a form with no username and update test data.
1595 LoadHTML(kVisibleFormWithNoUsernameHTML);
1596 username_element_.reset();
1597 WebDocument document = GetMainFrame()->document();
1598 WebElement element =
1599 document.getElementById(WebString::fromUTF8(kPasswordName));
1600 ASSERT_FALSE(element.isNull());
1601 password_element_ = element.to<blink::WebInputElement>();
1602 fill_data_.username_field = FormFieldData();
1603 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1604 fill_data_.additional_logins.clear();
1605 fill_data_.other_possible_usernames.clear();
1607 password_element_.setValue("");
1608 password_element_.setAutofilled(false);
1610 // Simulate the browser sending back the login info for an initial page load.
1611 SimulateOnFillPasswordForm(fill_data_);
1613 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1614 EXPECT_TRUE(password_element_.isAutofilled());
1617 TEST_F(PasswordAutofillAgentTest, ShowPopupOnEmptyPasswordField) {
1618 // Load a form with no username and update test data.
1619 LoadHTML(kVisibleFormWithNoUsernameHTML);
1620 username_element_.reset();
1621 WebDocument document = GetMainFrame()->document();
1622 WebElement element =
1623 document.getElementById(WebString::fromUTF8(kPasswordName));
1624 ASSERT_FALSE(element.isNull());
1625 password_element_ = element.to<blink::WebInputElement>();
1626 fill_data_.username_field = FormFieldData();
1627 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1628 fill_data_.additional_logins.clear();
1629 fill_data_.other_possible_usernames.clear();
1631 password_element_.setValue("");
1632 password_element_.setAutofilled(false);
1634 // Simulate the browser sending back the login info for an initial page load.
1635 SimulateOnFillPasswordForm(fill_data_);
1637 // Show popup suggesstion when the password field is empty.
1638 password_element_.setValue("");
1639 password_element_.setAutofilled(false);
1641 SimulateSuggestionChoiceOfUsernameAndPassword(
1642 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword));
1643 CheckSuggestions(std::string(), false);
1644 EXPECT_EQ(ASCIIToUTF16(kAlicePassword), password_element_.value());
1645 EXPECT_TRUE(password_element_.isAutofilled());
1648 TEST_F(PasswordAutofillAgentTest, ShowPopupOnAutofilledPasswordField) {
1649 // Load a form with no username and update test data.
1650 LoadHTML(kVisibleFormWithNoUsernameHTML);
1651 username_element_.reset();
1652 WebDocument document = GetMainFrame()->document();
1653 WebElement element =
1654 document.getElementById(WebString::fromUTF8(kPasswordName));
1655 ASSERT_FALSE(element.isNull());
1656 password_element_ = element.to<blink::WebInputElement>();
1657 fill_data_.username_field = FormFieldData();
1658 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1659 fill_data_.additional_logins.clear();
1660 fill_data_.other_possible_usernames.clear();
1662 password_element_.setValue("");
1663 password_element_.setAutofilled(false);
1665 // Simulate the browser sending back the login info for an initial page load.
1666 SimulateOnFillPasswordForm(fill_data_);
1668 // Show popup suggesstion when the password field is autofilled.
1669 password_element_.setValue("123");
1670 password_element_.setAutofilled(true);
1672 SimulateSuggestionChoiceOfUsernameAndPassword(
1673 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword));
1674 CheckSuggestions(std::string(), false);
1675 EXPECT_EQ(ASCIIToUTF16(kAlicePassword), password_element_.value());
1676 EXPECT_TRUE(password_element_.isAutofilled());
1679 TEST_F(PasswordAutofillAgentTest, NotShowPopupPasswordField) {
1680 // Load a form with no username and update test data.
1681 LoadHTML(kVisibleFormWithNoUsernameHTML);
1682 username_element_.reset();
1683 WebDocument document = GetMainFrame()->document();
1684 WebElement element =
1685 document.getElementById(WebString::fromUTF8(kPasswordName));
1686 ASSERT_FALSE(element.isNull());
1687 password_element_ = element.to<blink::WebInputElement>();
1688 fill_data_.username_field = FormFieldData();
1689 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1690 fill_data_.additional_logins.clear();
1691 fill_data_.other_possible_usernames.clear();
1693 password_element_.setValue("");
1694 password_element_.setAutofilled(false);
1696 // Simulate the browser sending back the login info for an initial page load.
1697 SimulateOnFillPasswordForm(fill_data_);
1699 // Do not show popup suggesstion when the password field is not-empty and not
1700 // autofilled.
1701 password_element_.setValue("123");
1702 password_element_.setAutofilled(false);
1704 SimulateSuggestionChoiceOfUsernameAndPassword(
1705 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword));
1706 ASSERT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1707 AutofillHostMsg_ShowPasswordSuggestions::ID));
1710 // Tests with fill-on-account-select enabled that if the username element is
1711 // read-only and filled with an unknown username, then the password field is not
1712 // highlighted as autofillable (regression test for https://crbug.com/442564).
1713 TEST_F(PasswordAutofillAgentTest,
1714 FillOnAccountSelectOnlyReadonlyUnknownUsername) {
1715 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1716 autofill::switches::kEnableFillOnAccountSelect);
1718 ClearUsernameAndPasswordFields();
1720 username_element_.setValue("foobar");
1721 SetElementReadOnly(username_element_, true);
1723 CheckTextFieldsState(std::string("foobar"), false, std::string(), false);
1726 // Test that the last plain text field before a password field is chosen as a
1727 // username, in a form with 2 plain text fields without username predictions.
1728 TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) {
1729 LoadHTML(kFormHTMLWithTwoTextFields);
1730 UpdateUsernameAndPasswordElements();
1731 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1732 SimulateUsernameChange("temp");
1733 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1734 SimulatePasswordChange("random");
1735 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1736 ->WillSendSubmitEvent(username_element_.form());
1737 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1738 ->WillSubmitForm(username_element_.form());
1740 // Observe that the PasswordAutofillAgent identifies the second field (e-mail)
1741 // as username.
1742 ExpectFormSubmittedWithUsernameAndPasswords("temp@google.com", "random", "");
1745 // Tests that field predictions are followed when identifying the username
1746 // and password in a password form with two plain text fields.
1747 TEST_F(PasswordAutofillAgentTest, FindingFieldsWithAutofillPredictions) {
1748 LoadHTML(kFormHTMLWithTwoTextFields);
1749 UpdateUsernameAndPasswordElements();
1750 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1751 SimulateUsernameChange("temp");
1752 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1753 SimulatePasswordChange("random");
1754 // Find FormData for visible password form.
1755 blink::WebFormElement form_element = username_element_.form();
1756 FormData form_data;
1757 ASSERT_TRUE(WebFormElementToFormData(form_element,
1758 blink::WebFormControlElement(),
1759 EXTRACT_NONE, &form_data, nullptr));
1760 // Simulate Autofill predictions: the first field is username, the third
1761 // one is password.
1762 std::map<autofill::FormData, PasswordFormFieldPredictionMap> predictions;
1763 predictions[form_data][form_data.fields[0]] = PREDICTION_USERNAME;
1764 predictions[form_data][form_data.fields[2]] = PREDICTION_NEW_PASSWORD;
1765 AutofillMsg_AutofillUsernameAndPasswordDataReceived msg(0, predictions);
1766 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1767 ->OnMessageReceived(msg);
1769 // The predictions should still match even if the form changes, as long
1770 // as the particular elements don't change.
1771 std::string add_field_to_form =
1772 "var form = document.getElementById('LoginTestForm');"
1773 "var new_input = document.createElement('input');"
1774 "new_input.setAttribute('type', 'text');"
1775 "new_input.setAttribute('id', 'other_field');"
1776 "form.appendChild(new_input);";
1777 ExecuteJavaScriptForTests(add_field_to_form.c_str());
1779 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1780 ->WillSendSubmitEvent(username_element_.form());
1781 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1782 ->WillSubmitForm(username_element_.form());
1784 // Observe that the PasswordAutofillAgent identifies the first field as
1785 // username.
1786 // TODO(msramek): We should also test that adding another password field
1787 // won't override the password field prediction either. However, the password
1788 // field predictions are not taken into account yet.
1789 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1792 // The user types in a username and a password. Then JavaScript changes password
1793 // field to readonly state before submit. PasswordAutofillAgent can correctly
1794 // process readonly password field. This test models behaviour of gmail.com.
1795 TEST_F(PasswordAutofillAgentTest, ReadonlyPasswordFieldOnSubmit) {
1796 SimulateUsernameChange("temp");
1797 SimulatePasswordChange("random");
1799 // Simulate that JavaScript makes password field readonly.
1800 SetElementReadOnly(password_element_, true);
1801 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1802 ->WillSubmitForm(username_element_.form());
1804 // Observe that the PasswordAutofillAgent can correctly process submitted
1805 // form.
1806 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1809 // Verify that typed passwords are saved correctly when autofill and generation
1810 // both trigger. Regression test for https://crbug.com/493455
1811 TEST_F(PasswordAutofillAgentTest, PasswordGenerationTriggered_TypedPassword) {
1812 SimulateOnFillPasswordForm(fill_data_);
1814 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1815 SetAccountCreationFormsDetectedMessage(password_generation_,
1816 GetMainFrame()->document(),
1819 SimulateUsernameChange("NewGuy");
1820 SimulatePasswordChange("NewPassword");
1821 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1822 ->WillSendSubmitEvent(username_element_.form());
1823 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1824 ->WillSubmitForm(username_element_.form());
1826 ExpectFormSubmittedWithUsernameAndPasswords("NewGuy", "NewPassword", "");
1829 // Verify that generated passwords are saved correctly when autofill and
1830 // generation both trigger. Regression test for https://crbug.com/493455.
1831 TEST_F(PasswordAutofillAgentTest,
1832 PasswordGenerationTriggered_GeneratedPassword) {
1833 SimulateOnFillPasswordForm(fill_data_);
1835 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1836 SetAccountCreationFormsDetectedMessage(password_generation_,
1837 GetMainFrame()->document(),
1840 base::string16 password = base::ASCIIToUTF16("NewPass22");
1841 AutofillMsg_GeneratedPasswordAccepted msg(0, password);
1842 password_generation_->OnMessageReceived(msg);
1844 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1845 ->WillSendSubmitEvent(username_element_.form());
1846 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1847 ->WillSubmitForm(username_element_.form());
1849 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, "NewPass22", "");
1852 // If password generation is enabled for a field, password autofill should not
1853 // show UI.
1854 TEST_F(PasswordAutofillAgentTest, PasswordGenerationSupersedesAutofill) {
1855 LoadHTML(kSignupFormHTML);
1857 // Update password_element_;
1858 WebDocument document = GetMainFrame()->document();
1859 WebElement element =
1860 document.getElementById(WebString::fromUTF8("new_password"));
1861 ASSERT_FALSE(element.isNull());
1862 password_element_ = element.to<blink::WebInputElement>();
1864 // Update fill_data_ for the new form and simulate filling. Pretend as if
1865 // the password manager didn't detect a username field so it will try to
1866 // show UI when the password field is focused.
1867 fill_data_.wait_for_username = true;
1868 fill_data_.username_field = FormFieldData();
1869 fill_data_.password_field.name = base::ASCIIToUTF16("new_password");
1870 UpdateOriginForHTML(kSignupFormHTML);
1871 SimulateOnFillPasswordForm(fill_data_);
1873 // Simulate generation triggering.
1874 SetNotBlacklistedMessage(password_generation_,
1875 kSignupFormHTML);
1876 SetAccountCreationFormsDetectedMessage(password_generation_,
1877 GetMainFrame()->document(),
1880 // Simulate the field being clicked to start typing. This should trigger
1881 // generation but not password autofill.
1882 SetFocused(password_element_);
1883 SimulateElementClick("new_password");
1884 EXPECT_EQ(nullptr,
1885 render_thread_->sink().GetFirstMessageMatching(
1886 AutofillHostMsg_ShowPasswordSuggestions::ID));
1887 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
1888 AutofillHostMsg_ShowPasswordGenerationPopup::ID));
1891 // Tests that a password change form is properly filled with the username and
1892 // password.
1893 TEST_F(PasswordAutofillAgentTest, FillSuggestionPasswordChangeForms) {
1894 LoadHTML(kPasswordChangeFormHTML);
1895 UpdateOriginForHTML(kPasswordChangeFormHTML);
1896 UpdateUsernameAndPasswordElements();
1897 // Simulate the browser sending the login info, but set |wait_for_username|
1898 // to prevent the form from being immediately filled.
1899 fill_data_.wait_for_username = true;
1900 fill_data_.is_possible_change_password_form = true;
1901 SimulateOnFillPasswordForm(fill_data_);
1903 // Neither field should have been autocompleted.
1904 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1906 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1907 username_element_, kAliceUsername, kAlicePassword));
1908 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1911 // Tests that a password change form is properly filled with the password when
1912 // the user click on the password field.
1913 TEST_F(PasswordAutofillAgentTest,
1914 FillSuggestionPasswordChangeFormsOnlyPassword) {
1915 LoadHTML(kPasswordChangeFormHTML);
1916 UpdateOriginForHTML(kPasswordChangeFormHTML);
1917 UpdateUsernameAndPasswordElements();
1918 // Simulate the browser sending the login info, but set |wait_for_username|
1919 // to prevent the form from being immediately filled.
1920 fill_data_.wait_for_username = true;
1921 fill_data_.is_possible_change_password_form = true;
1922 SimulateOnFillPasswordForm(fill_data_);
1924 // Neither field should have been autocompleted.
1925 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1927 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1928 password_element_, kAliceUsername, kAlicePassword));
1929 CheckTextFieldsDOMState("", false, kAlicePassword, true);
1932 // Tests that one user click on a username field is sufficient to bring up a
1933 // credential suggestion popup on a change password form.
1934 TEST_F(PasswordAutofillAgentTest,
1935 SuggestionsOnUsernameFieldOfChangePasswordForm) {
1936 LoadHTML(kPasswordChangeFormHTML);
1937 UpdateOriginForHTML(kPasswordChangeFormHTML);
1938 UpdateUsernameAndPasswordElements();
1940 ClearUsernameAndPasswordFields();
1941 fill_data_.wait_for_username = true;
1942 fill_data_.is_possible_change_password_form = true;
1943 SimulateOnFillPasswordForm(fill_data_);
1944 // Simulate a user clicking on the username element. This should produce a
1945 // message.
1946 render_thread_->sink().ClearMessages();
1947 static_cast<PageClickListener*>(autofill_agent_)
1948 ->FormControlElementClicked(username_element_, true);
1949 CheckSuggestions("", true);
1952 // Tests that one user click on a password field is sufficient to bring up a
1953 // credential suggestion popup on a change password form.
1954 TEST_F(PasswordAutofillAgentTest,
1955 SuggestionsOnPasswordFieldOfChangePasswordForm) {
1956 LoadHTML(kPasswordChangeFormHTML);
1957 UpdateOriginForHTML(kPasswordChangeFormHTML);
1958 UpdateUsernameAndPasswordElements();
1960 ClearUsernameAndPasswordFields();
1961 fill_data_.wait_for_username = true;
1962 fill_data_.is_possible_change_password_form = true;
1963 SimulateOnFillPasswordForm(fill_data_);
1964 // Simulate a user clicking on the password element. This should produce a
1965 // message.
1966 render_thread_->sink().ClearMessages();
1967 static_cast<PageClickListener*>(autofill_agent_)
1968 ->FormControlElementClicked(password_element_, true);
1969 CheckSuggestions("", false);
1972 // Tests that there are no autosuggestions from the password manager when the
1973 // user clicks on the password field of change password form after the user
1974 // typed in the username field.
1975 TEST_F(PasswordAutofillAgentTest,
1976 NoSuggestionsOnPasswordFieldOfChangePasswordFormAfterUsernameTyping) {
1977 LoadHTML(kPasswordChangeFormHTML);
1978 UpdateOriginForHTML(kPasswordChangeFormHTML);
1979 UpdateUsernameAndPasswordElements();
1981 ClearUsernameAndPasswordFields();
1982 fill_data_.wait_for_username = true;
1983 fill_data_.is_possible_change_password_form = true;
1984 SimulateOnFillPasswordForm(fill_data_);
1986 // Clear the text fields to start fresh.
1987 SimulateUsernameChange("temp");
1989 // Simulate a user clicking on the password element. This should produce no
1990 // message.
1991 render_thread_->sink().ClearMessages();
1992 static_cast<PageClickListener*>(autofill_agent_)
1993 ->FormControlElementClicked(password_element_, false);
1994 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1995 AutofillHostMsg_ShowPasswordSuggestions::ID));
1998 // Tests that NOT_PASSWORD field predictions are followed so that no password
1999 // form is submitted.
2000 TEST_F(PasswordAutofillAgentTest, IgnoreNotPasswordFields) {
2001 LoadHTML(kCreditCardFormHTML);
2002 blink::WebInputElement credit_card_owner_element =
2003 GetInputElementByID(kCreditCardOwnerName);
2004 blink::WebInputElement credit_card_number_element =
2005 GetInputElementByID(kCreditCardNumberName);
2006 blink::WebInputElement credit_card_verification_element =
2007 GetInputElementByID(kCreditCardVerificationName);
2008 SimulateUserInputChangeForElement(&credit_card_owner_element, "JohnSmith");
2009 SimulateUserInputChangeForElement(&credit_card_number_element,
2010 "1234123412341234");
2011 SimulateUserInputChangeForElement(&credit_card_verification_element, "123");
2012 // Find FormData for visible form.
2013 blink::WebFormElement form_element = credit_card_number_element.form();
2014 FormData form_data;
2015 ASSERT_TRUE(WebFormElementToFormData(form_element,
2016 blink::WebFormControlElement(),
2017 EXTRACT_NONE, &form_data, nullptr));
2018 // Simulate Autofill predictions: the third field is not a password.
2019 std::map<autofill::FormData, PasswordFormFieldPredictionMap> predictions;
2020 predictions[form_data][form_data.fields[2]] = PREDICTION_NOT_PASSWORD;
2021 AutofillMsg_AutofillUsernameAndPasswordDataReceived msg(0, predictions);
2022 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
2023 ->OnMessageReceived(msg);
2025 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
2026 ->WillSendSubmitEvent(form_element);
2027 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
2028 ->WillSubmitForm(form_element);
2030 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
2031 AutofillHostMsg_PasswordFormSubmitted::ID);
2032 ASSERT_FALSE(message);
2035 // Tests that only the password field is autocompleted when the browser sends
2036 // back data with only one credentials and empty username.
2037 TEST_F(PasswordAutofillAgentTest, NotAutofillNoUsername) {
2038 fill_data_.username_field.value.clear();
2039 fill_data_.additional_logins.clear();
2040 SimulateOnFillPasswordForm(fill_data_);
2042 CheckTextFieldsState("", false, kAlicePassword, true);
2045 // Tests that both the username and the password fields are autocompleted
2046 // despite the empty username, when the browser sends back data more than one
2047 // credential.
2048 TEST_F(PasswordAutofillAgentTest,
2049 AutofillNoUsernameWhenOtherCredentialsStored) {
2050 fill_data_.username_field.value.clear();
2051 ASSERT_FALSE(fill_data_.additional_logins.empty());
2052 SimulateOnFillPasswordForm(fill_data_);
2054 CheckTextFieldsState("", true, kAlicePassword, true);
2057 TEST_F(PasswordAutofillAgentTest, NoForm_PromptForAJAXSubmitWithoutNavigation) {
2058 LoadHTML(kNoFormHTML);
2059 UpdateUsernameAndPasswordElements();
2061 SimulateUsernameChange("Bob");
2062 SimulatePasswordChange("mypassword");
2064 username_element_.setAttribute("style", "display:none;");
2065 password_element_.setAttribute("style", "display:none;");
2067 password_autofill_agent_->AJAXSucceeded();
2069 ExpectInPageNavigationWithUsernameAndPasswords("Bob", "mypassword", "");
2072 TEST_F(PasswordAutofillAgentTest,
2073 NoForm_NoPromptForAJAXSubmitWithoutNavigationAndElementsVisible) {
2074 LoadHTML(kNoFormHTML);
2075 UpdateUsernameAndPasswordElements();
2077 SimulateUsernameChange("Bob");
2078 SimulatePasswordChange("mypassword");
2080 password_autofill_agent_->AJAXSucceeded();
2082 const IPC::Message* message =
2083 render_thread_->sink().GetFirstMessageMatching(
2084 AutofillHostMsg_PasswordFormSubmitted::ID);
2085 ASSERT_FALSE(message);
2088 } // namespace autofill