Update CrOS OOBE throbber to MD throbber; delete old asset
[chromium-blink-merge.git] / chrome / renderer / autofill / password_autofill_agent_browsertest.cc
blobf3743717e9bfd4f12302e90fd41aa43fbabd4239
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 // Sets the "readonly" attribute of |element| to the value given by |read_only|.
207 void SetElementReadOnly(WebInputElement& element, bool read_only) {
208 element.setAttribute(WebString::fromUTF8("readonly"),
209 read_only ? WebString::fromUTF8("true") : WebString());
212 } // namespace
214 namespace autofill {
216 class PasswordAutofillAgentTest : public ChromeRenderViewTest {
217 public:
218 PasswordAutofillAgentTest() {
221 // Simulates the fill password form message being sent to the renderer.
222 // We use that so we don't have to make RenderView::OnFillPasswordForm()
223 // protected.
224 void SimulateOnFillPasswordForm(
225 const PasswordFormFillData& fill_data) {
226 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data);
227 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
228 ->OnMessageReceived(msg);
231 // As above, but fills for an iframe.
232 void SimulateOnFillPasswordFormForFrame(
233 WebFrame* frame,
234 const PasswordFormFillData& fill_data) {
235 AutofillMsg_FillPasswordForm msg(0, kPasswordFillFormDataId, fill_data);
236 content::RenderFrame::FromWebFrame(frame)->OnMessageReceived(msg);
239 void SendVisiblePasswordForms() {
240 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
241 ->DidFinishLoad();
244 void SetUp() override {
245 ChromeRenderViewTest::SetUp();
247 // Add a preferred login and an additional login to the FillData.
248 username1_ = ASCIIToUTF16(kAliceUsername);
249 password1_ = ASCIIToUTF16(kAlicePassword);
250 username2_ = ASCIIToUTF16(kBobUsername);
251 password2_ = ASCIIToUTF16(kBobPassword);
252 username3_ = ASCIIToUTF16(kCarolUsername);
253 password3_ = ASCIIToUTF16(kCarolPassword);
254 alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
256 FormFieldData username_field;
257 username_field.name = ASCIIToUTF16(kUsernameName);
258 username_field.value = username1_;
259 fill_data_.username_field = username_field;
261 FormFieldData password_field;
262 password_field.name = ASCIIToUTF16(kPasswordName);
263 password_field.value = password1_;
264 password_field.form_control_type = "password";
265 fill_data_.password_field = password_field;
267 PasswordAndRealm password2;
268 password2.password = password2_;
269 fill_data_.additional_logins[username2_] = password2;
270 PasswordAndRealm password3;
271 password3.password = password3_;
272 fill_data_.additional_logins[username3_] = password3;
274 UsernamesCollectionKey key;
275 key.username = username3_;
276 key.password = password3_;
277 key.realm = "google.com";
278 fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
280 // We need to set the origin so it matches the frame URL and the action so
281 // it matches the form action, otherwise we won't autocomplete.
282 UpdateOriginForHTML(kFormHTML);
283 fill_data_.action = GURL("http://www.bidule.com");
285 LoadHTML(kFormHTML);
287 // Necessary for SimulateElementClick() to work correctly.
288 GetWebWidget()->resize(blink::WebSize(500, 500));
289 GetWebWidget()->setFocus(true);
291 // Now retrieve the input elements so the test can access them.
292 UpdateUsernameAndPasswordElements();
295 void TearDown() override {
296 username_element_.reset();
297 password_element_.reset();
298 ChromeRenderViewTest::TearDown();
301 void UpdateOriginForHTML(const std::string& html) {
302 std::string origin = "data:text/html;charset=utf-8," + html;
303 fill_data_.origin = GURL(origin);
306 void UpdateUsernameAndPasswordElements() {
307 WebDocument document = GetMainFrame()->document();
308 WebElement element =
309 document.getElementById(WebString::fromUTF8(kUsernameName));
310 ASSERT_FALSE(element.isNull());
311 username_element_ = element.to<blink::WebInputElement>();
312 element = document.getElementById(WebString::fromUTF8(kPasswordName));
313 ASSERT_FALSE(element.isNull());
314 password_element_ = element.to<blink::WebInputElement>();
317 blink::WebInputElement GetInputElementByID(const std::string& id) {
318 WebDocument document = GetMainFrame()->document();
319 WebElement element =
320 document.getElementById(WebString::fromUTF8(id.c_str()));
321 return element.to<blink::WebInputElement>();
324 void ClearUsernameAndPasswordFields() {
325 username_element_.setValue("");
326 username_element_.setAutofilled(false);
327 password_element_.setValue("");
328 password_element_.setAutofilled(false);
331 void SimulateDidEndEditing(WebFrame* input_frame, WebInputElement& input) {
332 static_cast<blink::WebAutofillClient*>(autofill_agent_)
333 ->textFieldDidEndEditing(input);
336 void SimulateSuggestionChoice(WebInputElement& username_input) {
337 base::string16 username(base::ASCIIToUTF16(kAliceUsername));
338 base::string16 password(base::ASCIIToUTF16(kAlicePassword));
339 SimulateSuggestionChoiceOfUsernameAndPassword(username_input, username,
340 password);
343 void SimulateSuggestionChoiceOfUsernameAndPassword(
344 WebInputElement& input,
345 const base::string16& username,
346 const base::string16& password) {
347 // This call is necessary to setup the autofill agent appropriate for the
348 // user selection; simulates the menu actually popping up.
349 render_thread_->sink().ClearMessages();
350 static_cast<autofill::PageClickListener*>(autofill_agent_)
351 ->FormControlElementClicked(input, false);
353 AutofillMsg_FillPasswordSuggestion msg(0, username, password);
354 static_cast<content::RenderFrameObserver*>(autofill_agent_)
355 ->OnMessageReceived(msg);
358 void SimulateUsernameChange(const std::string& username) {
359 SimulateUserInputChangeForElement(&username_element_, username);
362 void SimulatePasswordChange(const std::string& password) {
363 SimulateUserInputChangeForElement(&password_element_, password);
366 void CheckTextFieldsStateForElements(const WebInputElement& username_element,
367 const std::string& username,
368 bool username_autofilled,
369 const WebInputElement& password_element,
370 const std::string& password,
371 bool password_autofilled,
372 bool checkSuggestedValue) {
373 EXPECT_EQ(username,
374 static_cast<std::string>(username_element.value().utf8()));
375 EXPECT_EQ(username_autofilled, username_element.isAutofilled());
376 EXPECT_EQ(password,
377 static_cast<std::string>(
378 checkSuggestedValue ? password_element.suggestedValue().utf8()
379 : password_element.value().utf8()))
380 << "checkSuggestedValue == " << checkSuggestedValue;
381 EXPECT_EQ(password_autofilled, password_element.isAutofilled());
384 // Checks the DOM-accessible value of the username element and the
385 // *suggested* value of the password element.
386 void CheckTextFieldsState(const std::string& username,
387 bool username_autofilled,
388 const std::string& password,
389 bool password_autofilled) {
390 CheckTextFieldsStateForElements(username_element_,
391 username,
392 username_autofilled,
393 password_element_,
394 password,
395 password_autofilled,
396 true);
399 // Checks the DOM-accessible value of the username element and the
400 // DOM-accessible value of the password element.
401 void CheckTextFieldsDOMState(const std::string& username,
402 bool username_autofilled,
403 const std::string& password,
404 bool password_autofilled) {
405 CheckTextFieldsStateForElements(username_element_,
406 username,
407 username_autofilled,
408 password_element_,
409 password,
410 password_autofilled,
411 false);
414 void CheckUsernameSelection(int start, int end) {
415 EXPECT_EQ(start, username_element_.selectionStart());
416 EXPECT_EQ(end, username_element_.selectionEnd());
419 // Checks the message sent to PasswordAutofillManager to build the suggestion
420 // list. |username| is the expected username field value, and |show_all| is
421 // the expected flag for the PasswordAutofillManager, whether to show all
422 // suggestions, or only those starting with |username|.
423 void CheckSuggestions(const std::string& username, bool show_all) {
424 const IPC::Message* message =
425 render_thread_->sink().GetFirstMessageMatching(
426 AutofillHostMsg_ShowPasswordSuggestions::ID);
427 ASSERT_TRUE(message);
428 base::Tuple<int, base::i18n::TextDirection, base::string16, int, gfx::RectF>
429 args;
430 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
431 EXPECT_EQ(kPasswordFillFormDataId, base::get<0>(args));
432 EXPECT_EQ(ASCIIToUTF16(username), base::get<2>(args));
433 EXPECT_EQ(show_all,
434 static_cast<bool>(base::get<3>(args) & autofill::SHOW_ALL));
436 render_thread_->sink().ClearMessages();
439 void ExpectFormSubmittedWithUsernameAndPasswords(
440 const std::string& username_value,
441 const std::string& password_value,
442 const std::string& new_password_value) {
443 const IPC::Message* message =
444 render_thread_->sink().GetFirstMessageMatching(
445 AutofillHostMsg_PasswordFormSubmitted::ID);
446 ASSERT_TRUE(message);
447 base::Tuple<autofill::PasswordForm> args;
448 AutofillHostMsg_PasswordFormSubmitted::Read(message, &args);
449 EXPECT_EQ(ASCIIToUTF16(username_value), base::get<0>(args).username_value);
450 EXPECT_EQ(ASCIIToUTF16(password_value), base::get<0>(args).password_value);
451 EXPECT_EQ(ASCIIToUTF16(new_password_value),
452 base::get<0>(args).new_password_value);
455 base::string16 username1_;
456 base::string16 username2_;
457 base::string16 username3_;
458 base::string16 password1_;
459 base::string16 password2_;
460 base::string16 password3_;
461 base::string16 alternate_username3_;
462 PasswordFormFillData fill_data_;
464 WebInputElement username_element_;
465 WebInputElement password_element_;
467 private:
468 DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
471 // Tests that the password login is autocompleted as expected when the browser
472 // sends back the password info.
473 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
475 * Right now we are not sending the message to the browser because we are
476 * loading a data URL and the security origin canAccessPasswordManager()
477 * returns false. May be we should mock URL loading to cirmcuvent this?
478 TODO(jcivelli): find a way to make the security origin not deny access to the
479 password manager and then reenable this code.
481 // The form has been loaded, we should have sent the browser a message about
482 // the form.
483 const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
484 AutofillHostMsg_PasswordFormsParsed::ID);
485 ASSERT_TRUE(msg != NULL);
487 base::Tuple1<std::vector<PasswordForm> > forms;
488 AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
489 ASSERT_EQ(1U, forms.a.size());
490 PasswordForm password_form = forms.a[0];
491 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
492 EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
493 EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
496 // Simulate the browser sending back the login info, it triggers the
497 // autocomplete.
498 SimulateOnFillPasswordForm(fill_data_);
500 // The username and password should have been autocompleted.
501 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
504 // Tests that we correctly fill forms having an empty 'action' attribute.
505 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
506 const char kEmptyActionFormHTML[] =
507 "<FORM name='LoginTestForm'>"
508 " <INPUT type='text' id='username'/>"
509 " <INPUT type='password' id='password'/>"
510 " <INPUT type='submit' value='Login'/>"
511 "</FORM>";
512 LoadHTML(kEmptyActionFormHTML);
514 // Retrieve the input elements so the test can access them.
515 WebDocument document = GetMainFrame()->document();
516 WebElement element =
517 document.getElementById(WebString::fromUTF8(kUsernameName));
518 ASSERT_FALSE(element.isNull());
519 username_element_ = element.to<blink::WebInputElement>();
520 element = document.getElementById(WebString::fromUTF8(kPasswordName));
521 ASSERT_FALSE(element.isNull());
522 password_element_ = element.to<blink::WebInputElement>();
524 // Set the expected form origin and action URLs.
525 UpdateOriginForHTML(kEmptyActionFormHTML);
526 fill_data_.action = fill_data_.origin;
528 // Simulate the browser sending back the login info, it triggers the
529 // autocomplete.
530 SimulateOnFillPasswordForm(fill_data_);
532 // The username and password should have been autocompleted.
533 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
536 // Tests that if a password is marked as readonly, neither field is autofilled
537 // on page load.
538 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
539 SetElementReadOnly(password_element_, true);
541 // Simulate the browser sending back the login info, it triggers the
542 // autocomplete.
543 SimulateOnFillPasswordForm(fill_data_);
545 CheckTextFieldsState(std::string(), false, std::string(), false);
548 // Can still fill a password field if the username is set to a value that
549 // matches.
550 TEST_F(PasswordAutofillAgentTest,
551 AutocompletePasswordForReadonlyUsernameMatched) {
552 username_element_.setValue(username3_);
553 SetElementReadOnly(username_element_, true);
555 // Filled even though username is not the preferred match.
556 SimulateOnFillPasswordForm(fill_data_);
557 CheckTextFieldsState(UTF16ToUTF8(username3_), false,
558 UTF16ToUTF8(password3_), true);
561 // If a username field is empty and readonly, don't autofill.
562 TEST_F(PasswordAutofillAgentTest,
563 NoAutocompletePasswordForReadonlyUsernameUnmatched) {
564 username_element_.setValue(WebString::fromUTF8(""));
565 SetElementReadOnly(username_element_, true);
567 SimulateOnFillPasswordForm(fill_data_);
568 CheckTextFieldsState(std::string(), false, std::string(), false);
571 // Tests that having a non-matching username precludes the autocomplete.
572 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
573 username_element_.setValue(WebString::fromUTF8("bogus"));
575 // Simulate the browser sending back the login info, it triggers the
576 // autocomplete.
577 SimulateOnFillPasswordForm(fill_data_);
579 // Neither field should be autocompleted.
580 CheckTextFieldsState("bogus", false, std::string(), false);
583 // Don't try to complete a prefilled value even if it's a partial match
584 // to a username.
585 TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
586 username_element_.setValue(WebString::fromUTF8("ali"));
588 SimulateOnFillPasswordForm(fill_data_);
590 CheckTextFieldsState("ali", false, std::string(), false);
593 TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
594 const char kNoFormInputs[] =
595 "<input type='text' id='username'/>"
596 "<input type='password' id='password'/>";
597 LoadHTML(kNoFormInputs);
599 SimulateOnFillPasswordForm(fill_data_);
601 // Input elements that aren't in a <form> won't autofill.
602 CheckTextFieldsState(std::string(), false, std::string(), false);
605 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
606 const char kTextFieldPasswordFormHTML[] =
607 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
608 " <INPUT type='text' id='username'/>"
609 " <INPUT type='text' id='password'/>"
610 " <INPUT type='submit' value='Login'/>"
611 "</FORM>";
612 LoadHTML(kTextFieldPasswordFormHTML);
614 // Retrieve the input elements so the test can access them.
615 WebDocument document = GetMainFrame()->document();
616 WebElement element =
617 document.getElementById(WebString::fromUTF8(kUsernameName));
618 ASSERT_FALSE(element.isNull());
619 username_element_ = element.to<blink::WebInputElement>();
620 element = document.getElementById(WebString::fromUTF8(kPasswordName));
621 ASSERT_FALSE(element.isNull());
622 password_element_ = element.to<blink::WebInputElement>();
624 // Set the expected form origin URL.
625 UpdateOriginForHTML(kTextFieldPasswordFormHTML);
627 SimulateOnFillPasswordForm(fill_data_);
629 // Fields should still be empty.
630 CheckTextFieldsState(std::string(), false, std::string(), false);
633 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
634 const char kPasswordFieldUsernameFormHTML[] =
635 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
636 " <INPUT type='password' id='username'/>"
637 " <INPUT type='password' id='password'/>"
638 " <INPUT type='submit' value='Login'/>"
639 "</FORM>";
640 LoadHTML(kPasswordFieldUsernameFormHTML);
642 // Retrieve the input elements so the test can access them.
643 WebDocument document = GetMainFrame()->document();
644 WebElement element =
645 document.getElementById(WebString::fromUTF8(kUsernameName));
646 ASSERT_FALSE(element.isNull());
647 username_element_ = element.to<blink::WebInputElement>();
648 element = document.getElementById(WebString::fromUTF8(kPasswordName));
649 ASSERT_FALSE(element.isNull());
650 password_element_ = element.to<blink::WebInputElement>();
652 // Set the expected form origin URL.
653 UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
655 SimulateOnFillPasswordForm(fill_data_);
657 // Fields should still be empty.
658 CheckTextFieldsState(std::string(), false, std::string(), false);
661 // Tests that having a matching username does not preclude the autocomplete.
662 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
663 username_element_.setValue(WebString::fromUTF8(kAliceUsername));
665 // Simulate the browser sending back the login info, it triggers the
666 // autocomplete.
667 SimulateOnFillPasswordForm(fill_data_);
669 // The username and password should have been autocompleted.
670 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
673 TEST_F(PasswordAutofillAgentTest, PasswordNotClearedOnEdit) {
674 // Simulate the browser sending back the login info, it triggers the
675 // autocomplete.
676 SimulateOnFillPasswordForm(fill_data_);
678 // Simulate the user changing the username to some unknown username.
679 SimulateUsernameChange("alicia");
681 // The password should not have been cleared.
682 CheckTextFieldsDOMState("alicia", false, kAlicePassword, true);
685 // Tests that we only autocomplete on focus lost and with a full username match
686 // when |wait_for_username| is true.
687 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
688 // Simulate the browser sending back the login info.
689 fill_data_.wait_for_username = true;
690 SimulateOnFillPasswordForm(fill_data_);
692 // No auto-fill should have taken place.
693 CheckTextFieldsState(std::string(), false, std::string(), false);
695 // No autocomplete should happen when text is entered in the username.
696 SimulateUsernameChange("a");
697 CheckTextFieldsState("a", false, std::string(), false);
698 SimulateUsernameChange("al");
699 CheckTextFieldsState("al", false, std::string(), false);
700 SimulateUsernameChange(kAliceUsername);
701 CheckTextFieldsState(kAliceUsername, false, std::string(), false);
703 // Autocomplete should happen only when the username textfield is blurred with
704 // a full match.
705 SimulateUsernameChange("a");
706 static_cast<blink::WebAutofillClient*>(autofill_agent_)
707 ->textFieldDidEndEditing(username_element_);
708 CheckTextFieldsState("a", false, std::string(), false);
709 SimulateUsernameChange("al");
710 static_cast<blink::WebAutofillClient*>(autofill_agent_)
711 ->textFieldDidEndEditing(username_element_);
712 CheckTextFieldsState("al", false, std::string(), false);
713 SimulateUsernameChange("alices");
714 static_cast<blink::WebAutofillClient*>(autofill_agent_)
715 ->textFieldDidEndEditing(username_element_);
716 CheckTextFieldsState("alices", false, std::string(), false);
717 SimulateUsernameChange(kAliceUsername);
718 static_cast<blink::WebAutofillClient*>(autofill_agent_)
719 ->textFieldDidEndEditing(username_element_);
720 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
723 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
724 blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
725 blink::WebFrame* frame;
727 LoadHTML(kVisibleFormWithNoUsernameHTML);
728 frame = GetMainFrame();
729 frame->document().forms(forms1);
730 ASSERT_EQ(1u, forms1.size());
731 EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
733 LoadHTML(kEmptyFormHTML);
734 frame = GetMainFrame();
735 frame->document().forms(forms2);
736 ASSERT_EQ(1u, forms2.size());
737 EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
739 LoadHTML(kNonVisibleFormHTML);
740 frame = GetMainFrame();
741 frame->document().forms(forms3);
742 ASSERT_EQ(1u, forms3.size());
743 EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
746 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
747 render_thread_->sink().ClearMessages();
748 LoadHTML(kVisibleFormWithNoUsernameHTML);
749 const IPC::Message* message = render_thread_->sink()
750 .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
751 EXPECT_TRUE(message);
752 base::Tuple<std::vector<autofill::PasswordForm>, bool> param;
753 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
754 EXPECT_TRUE(base::get<0>(param).size());
756 render_thread_->sink().ClearMessages();
757 LoadHTML(kEmptyFormHTML);
758 message = render_thread_->sink().GetFirstMessageMatching(
759 AutofillHostMsg_PasswordFormsRendered::ID);
760 EXPECT_TRUE(message);
761 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
762 EXPECT_FALSE(base::get<0>(param).size());
764 render_thread_->sink().ClearMessages();
765 LoadHTML(kNonVisibleFormHTML);
766 message = render_thread_->sink().GetFirstMessageMatching(
767 AutofillHostMsg_PasswordFormsRendered::ID);
768 EXPECT_TRUE(message);
769 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
770 EXPECT_FALSE(base::get<0>(param).size());
773 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
774 render_thread_->sink().ClearMessages();
775 LoadHTML(kEmptyWebpage);
776 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
777 AutofillHostMsg_PasswordFormsRendered::ID));
779 render_thread_->sink().ClearMessages();
780 LoadHTML(kRedirectionWebpage);
781 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
782 AutofillHostMsg_PasswordFormsRendered::ID));
784 render_thread_->sink().ClearMessages();
785 LoadHTML(kSimpleWebpage);
786 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
787 AutofillHostMsg_PasswordFormsRendered::ID));
789 render_thread_->sink().ClearMessages();
790 LoadHTML(kWebpageWithDynamicContent);
791 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
792 AutofillHostMsg_PasswordFormsRendered::ID));
795 // Tests that a password will only be filled as a suggested and will not be
796 // accessible by the DOM until a user gesture has occurred.
797 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
798 // Trigger the initial autocomplete.
799 SimulateOnFillPasswordForm(fill_data_);
801 // The username and password should have been autocompleted.
802 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
804 // However, it should only have completed with the suggested value, as tested
805 // above, and it should not have completed into the DOM accessible value for
806 // the password field.
807 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
809 // Simulate a user click so that the password field's real value is filled.
810 SimulateElementClick(kUsernameName);
811 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
814 // Verfies that a DOM-activated UI event will not cause an autofill.
815 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
816 // Trigger the initial autocomplete.
817 SimulateOnFillPasswordForm(fill_data_);
819 ExecuteJavaScriptForTests(kJavaScriptClick);
820 CheckTextFieldsDOMState(kAliceUsername, true, "", true);
823 // Verifies that password autofill triggers onChange events in JavaScript for
824 // forms that are filled on page load.
825 TEST_F(PasswordAutofillAgentTest,
826 PasswordAutofillTriggersOnChangeEventsOnLoad) {
827 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
828 LoadHTML(html.c_str());
829 UpdateOriginForHTML(html);
830 UpdateUsernameAndPasswordElements();
832 // Simulate the browser sending back the login info, it triggers the
833 // autocomplete.
834 SimulateOnFillPasswordForm(fill_data_);
836 // The username and password should have been autocompleted...
837 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
838 // ... but since there hasn't been a user gesture yet, the autocompleted
839 // password should only be visible to the user.
840 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
842 // A JavaScript onChange event should have been triggered for the username,
843 // but not yet for the password.
844 int username_onchange_called = -1;
845 int password_onchange_called = -1;
846 ASSERT_TRUE(
847 ExecuteJavaScriptAndReturnIntValue(
848 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
849 &username_onchange_called));
850 EXPECT_EQ(1, username_onchange_called);
851 ASSERT_TRUE(
852 ExecuteJavaScriptAndReturnIntValue(
853 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
854 &password_onchange_called));
855 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
856 // EXPECT_EQ(0, password_onchange_called);
858 // Simulate a user click so that the password field's real value is filled.
859 SimulateElementClick(kUsernameName);
860 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
862 // Now, a JavaScript onChange event should have been triggered for the
863 // password as well.
864 ASSERT_TRUE(
865 ExecuteJavaScriptAndReturnIntValue(
866 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
867 &password_onchange_called));
868 EXPECT_EQ(1, password_onchange_called);
871 // Verifies that password autofill triggers onChange events in JavaScript for
872 // forms that are filled after page load.
873 TEST_F(PasswordAutofillAgentTest,
874 PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
875 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
876 LoadHTML(html.c_str());
877 UpdateOriginForHTML(html);
878 UpdateUsernameAndPasswordElements();
880 // Simulate the browser sending back the login info, it triggers the
881 // autocomplete.
882 fill_data_.wait_for_username = true;
883 SimulateOnFillPasswordForm(fill_data_);
885 // The username and password should not yet have been autocompleted.
886 CheckTextFieldsState(std::string(), false, std::string(), false);
888 // Simulate a click just to force a user gesture, since the username value is
889 // set directly.
890 SimulateElementClick(kUsernameName);
892 // Simulate the user entering the first letter of her username and selecting
893 // the matching autofill from the dropdown.
894 SimulateUsernameChange("a");
895 SimulateSuggestionChoice(username_element_);
897 // The username and password should now have been autocompleted.
898 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
900 // JavaScript onChange events should have been triggered both for the username
901 // and for the password.
902 int username_onchange_called = -1;
903 int password_onchange_called = -1;
904 ASSERT_TRUE(
905 ExecuteJavaScriptAndReturnIntValue(
906 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
907 &username_onchange_called));
908 EXPECT_EQ(1, username_onchange_called);
909 ASSERT_TRUE(
910 ExecuteJavaScriptAndReturnIntValue(
911 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
912 &password_onchange_called));
913 EXPECT_EQ(1, password_onchange_called);
916 // Tests that |FillSuggestion| properly fills the username and password.
917 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
918 // Simulate the browser sending the login info, but set |wait_for_username|
919 // to prevent the form from being immediately filled.
920 fill_data_.wait_for_username = true;
921 SimulateOnFillPasswordForm(fill_data_);
923 // Neither field should have been autocompleted.
924 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
926 // If the password field is not autocompletable, it should not be affected.
927 SetElementReadOnly(password_element_, true);
928 EXPECT_FALSE(password_autofill_agent_->FillSuggestion(
929 username_element_, kAliceUsername, kAlicePassword));
930 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
931 SetElementReadOnly(password_element_, false);
933 // After filling with the suggestion, both fields should be autocompleted.
934 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
935 username_element_, kAliceUsername, kAlicePassword));
936 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
937 int username_length = strlen(kAliceUsername);
938 CheckUsernameSelection(username_length, username_length);
940 // Try Filling with a suggestion with password different from the one that was
941 // initially sent to the renderer.
942 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
943 username_element_, kBobUsername, kCarolPassword));
944 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
945 username_length = strlen(kBobUsername);
946 CheckUsernameSelection(username_length, username_length);
949 // Tests that |PreviewSuggestion| properly previews the username and password.
950 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
951 // Simulate the browser sending the login info, but set |wait_for_username|
952 // to prevent the form from being immediately filled.
953 fill_data_.wait_for_username = true;
954 SimulateOnFillPasswordForm(fill_data_);
956 // Neither field should have been autocompleted.
957 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
959 // If the password field is not autocompletable, it should not be affected.
960 SetElementReadOnly(password_element_, true);
961 EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion(
962 username_element_, kAliceUsername, kAlicePassword));
963 EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
964 EXPECT_FALSE(username_element_.isAutofilled());
965 EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
966 EXPECT_FALSE(password_element_.isAutofilled());
967 SetElementReadOnly(password_element_, false);
969 // After selecting the suggestion, both fields should be previewed
970 // with suggested values.
971 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
972 username_element_, kAliceUsername, kAlicePassword));
973 EXPECT_EQ(
974 kAliceUsername,
975 static_cast<std::string>(username_element_.suggestedValue().utf8()));
976 EXPECT_TRUE(username_element_.isAutofilled());
977 EXPECT_EQ(
978 kAlicePassword,
979 static_cast<std::string>(password_element_.suggestedValue().utf8()));
980 EXPECT_TRUE(password_element_.isAutofilled());
981 int username_length = strlen(kAliceUsername);
982 CheckUsernameSelection(0, username_length);
984 // Try previewing with a password different from the one that was initially
985 // sent to the renderer.
986 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
987 username_element_, kBobUsername, kCarolPassword));
988 EXPECT_EQ(
989 kBobUsername,
990 static_cast<std::string>(username_element_.suggestedValue().utf8()));
991 EXPECT_TRUE(username_element_.isAutofilled());
992 EXPECT_EQ(
993 kCarolPassword,
994 static_cast<std::string>(password_element_.suggestedValue().utf8()));
995 EXPECT_TRUE(password_element_.isAutofilled());
996 username_length = strlen(kBobUsername);
997 CheckUsernameSelection(0, username_length);
1000 // Tests that |PreviewSuggestion| properly sets the username selection range.
1001 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
1002 username_element_.setValue(WebString::fromUTF8("ali"));
1003 username_element_.setSelectionRange(3, 3);
1004 username_element_.setAutofilled(true);
1006 CheckTextFieldsDOMState("ali", true, std::string(), false);
1008 // Simulate the browser sending the login info, but set |wait_for_username|
1009 // to prevent the form from being immediately filled.
1010 fill_data_.wait_for_username = true;
1011 SimulateOnFillPasswordForm(fill_data_);
1013 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1014 username_element_, kAliceUsername, kAlicePassword));
1015 EXPECT_EQ(
1016 kAliceUsername,
1017 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1018 EXPECT_TRUE(username_element_.isAutofilled());
1019 EXPECT_EQ(
1020 kAlicePassword,
1021 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1022 EXPECT_TRUE(password_element_.isAutofilled());
1023 int username_length = strlen(kAliceUsername);
1024 CheckUsernameSelection(3, username_length);
1027 // Tests that |ClearPreview| properly clears previewed username and password
1028 // with password being previously autofilled.
1029 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
1030 password_element_.setValue(WebString::fromUTF8("sec"));
1031 password_element_.setAutofilled(true);
1033 // Simulate the browser sending the login info, but set |wait_for_username|
1034 // to prevent the form from being immediately filled.
1035 fill_data_.wait_for_username = true;
1036 SimulateOnFillPasswordForm(fill_data_);
1038 CheckTextFieldsDOMState(std::string(), false, "sec", true);
1040 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1041 username_element_, kAliceUsername, kAlicePassword));
1043 EXPECT_TRUE(
1044 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1046 EXPECT_TRUE(username_element_.value().isEmpty());
1047 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1048 EXPECT_FALSE(username_element_.isAutofilled());
1049 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1050 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1051 EXPECT_TRUE(password_element_.isAutofilled());
1052 CheckUsernameSelection(0, 0);
1055 // Tests that |ClearPreview| properly clears previewed username and password
1056 // with username being previously autofilled.
1057 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
1058 username_element_.setValue(WebString::fromUTF8("ali"));
1059 username_element_.setSelectionRange(3, 3);
1060 username_element_.setAutofilled(true);
1062 // Simulate the browser sending the login info, but set |wait_for_username|
1063 // to prevent the form from being immediately filled.
1064 fill_data_.wait_for_username = true;
1065 SimulateOnFillPasswordForm(fill_data_);
1067 CheckTextFieldsDOMState("ali", true, std::string(), false);
1069 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1070 username_element_, kAliceUsername, kAlicePassword));
1072 EXPECT_TRUE(
1073 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1075 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1076 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1077 EXPECT_TRUE(username_element_.isAutofilled());
1078 EXPECT_TRUE(password_element_.value().isEmpty());
1079 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1080 EXPECT_FALSE(password_element_.isAutofilled());
1081 CheckUsernameSelection(3, 3);
1084 // Tests that |ClearPreview| properly clears previewed username and password
1085 // with username and password being previously autofilled.
1086 TEST_F(PasswordAutofillAgentTest,
1087 ClearPreviewWithAutofilledUsernameAndPassword) {
1088 username_element_.setValue(WebString::fromUTF8("ali"));
1089 username_element_.setSelectionRange(3, 3);
1090 username_element_.setAutofilled(true);
1091 password_element_.setValue(WebString::fromUTF8("sec"));
1092 password_element_.setAutofilled(true);
1094 // Simulate the browser sending the login info, but set |wait_for_username|
1095 // to prevent the form from being immediately filled.
1096 fill_data_.wait_for_username = true;
1097 SimulateOnFillPasswordForm(fill_data_);
1099 CheckTextFieldsDOMState("ali", true, "sec", true);
1101 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1102 username_element_, kAliceUsername, kAlicePassword));
1104 EXPECT_TRUE(
1105 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1107 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1108 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1109 EXPECT_TRUE(username_element_.isAutofilled());
1110 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1111 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1112 EXPECT_TRUE(password_element_.isAutofilled());
1113 CheckUsernameSelection(3, 3);
1116 // Tests that |ClearPreview| properly clears previewed username and password
1117 // with neither username nor password being previously autofilled.
1118 TEST_F(PasswordAutofillAgentTest,
1119 ClearPreviewWithNotAutofilledUsernameAndPassword) {
1120 // Simulate the browser sending the login info, but set |wait_for_username|
1121 // to prevent the form from being immediately filled.
1122 fill_data_.wait_for_username = true;
1123 SimulateOnFillPasswordForm(fill_data_);
1125 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1127 EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1128 username_element_, kAliceUsername, kAlicePassword));
1130 EXPECT_TRUE(
1131 password_autofill_agent_->DidClearAutofillSelection(username_element_));
1133 EXPECT_TRUE(username_element_.value().isEmpty());
1134 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1135 EXPECT_FALSE(username_element_.isAutofilled());
1136 EXPECT_TRUE(password_element_.value().isEmpty());
1137 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1138 EXPECT_FALSE(password_element_.isAutofilled());
1139 CheckUsernameSelection(0, 0);
1142 // Tests that logging is off by default.
1143 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1144 render_thread_->sink().ClearMessages();
1145 SendVisiblePasswordForms();
1146 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1147 AutofillHostMsg_RecordSavePasswordProgress::ID);
1148 EXPECT_FALSE(message);
1151 // Test that logging can be turned on by a message.
1152 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1153 // Turn the logging on.
1154 AutofillMsg_SetLoggingState msg_activate(0, true);
1155 // Up-cast to access OnMessageReceived, which is private in the agent.
1156 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1157 ->OnMessageReceived(msg_activate));
1159 render_thread_->sink().ClearMessages();
1160 SendVisiblePasswordForms();
1161 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1162 AutofillHostMsg_RecordSavePasswordProgress::ID);
1163 EXPECT_TRUE(message);
1166 // Test that logging can be turned off by a message.
1167 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1168 // Turn the logging on and then off.
1169 AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
1170 // Up-cast to access OnMessageReceived, which is private in the agent.
1171 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1172 ->OnMessageReceived(msg_activate));
1173 AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
1174 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1175 ->OnMessageReceived(msg_deactivate));
1177 render_thread_->sink().ClearMessages();
1178 SendVisiblePasswordForms();
1179 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1180 AutofillHostMsg_RecordSavePasswordProgress::ID);
1181 EXPECT_FALSE(message);
1184 // Test that the agent sends an IPC call to get the current activity state of
1185 // password saving logging soon after construction.
1186 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1187 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1188 AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1189 EXPECT_TRUE(message);
1192 // Tests that one user click on a username field is sufficient to bring up a
1193 // credential suggestion popup, and the user can autocomplete the password by
1194 // selecting the credential from the popup.
1195 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1196 // SimulateElementClick() is called so that a user gesture is actually made
1197 // and the password can be filled. However, SimulateElementClick() does not
1198 // actually lead to the AutofillAgent's InputElementClicked() method being
1199 // called, so SimulateSuggestionChoice has to manually call
1200 // InputElementClicked().
1201 ClearUsernameAndPasswordFields();
1202 SimulateOnFillPasswordForm(fill_data_);
1203 SimulateElementClick(kUsernameName);
1204 SimulateSuggestionChoice(username_element_);
1205 CheckSuggestions(kAliceUsername, true);
1207 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1210 // Tests the autosuggestions that are given when the element is clicked.
1211 // Specifically, tests when the user clicks on the username element after page
1212 // load and the element is autofilled, when the user clicks on an element that
1213 // has a non-matching username, and when the user clicks on an element that's
1214 // already been autofilled and they've already modified.
1215 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1216 // Simulate the browser sending back the login info.
1217 SimulateOnFillPasswordForm(fill_data_);
1219 // Clear the text fields to start fresh.
1220 ClearUsernameAndPasswordFields();
1222 // Call SimulateElementClick() to produce a user gesture on the page so
1223 // autofill will actually fill.
1224 SimulateElementClick(kUsernameName);
1226 // Simulate a user clicking on the username element. This should produce a
1227 // message with all the usernames.
1228 render_thread_->sink().ClearMessages();
1229 static_cast<PageClickListener*>(autofill_agent_)
1230 ->FormControlElementClicked(username_element_, false);
1231 CheckSuggestions(std::string(), false);
1233 // Now simulate a user typing in an unrecognized username and then
1234 // clicking on the username element. This should also produce a message with
1235 // all the usernames.
1236 SimulateUsernameChange("baz");
1237 render_thread_->sink().ClearMessages();
1238 static_cast<PageClickListener*>(autofill_agent_)
1239 ->FormControlElementClicked(username_element_, true);
1240 CheckSuggestions("baz", true);
1241 ClearUsernameAndPasswordFields();
1244 // Tests that there are no autosuggestions from the password manager when the
1245 // user clicks on the password field and the username field is editable when
1246 // FillOnAccountSelect is enabled.
1247 TEST_F(PasswordAutofillAgentTest,
1248 FillOnAccountSelectOnlyNoCredentialsOnPasswordClick) {
1249 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1250 autofill::switches::kEnableFillOnAccountSelect);
1252 // Simulate the browser sending back the login info.
1253 SimulateOnFillPasswordForm(fill_data_);
1255 // Clear the text fields to start fresh.
1256 ClearUsernameAndPasswordFields();
1258 // Call SimulateElementClick() to produce a user gesture on the page so
1259 // autofill will actually fill.
1260 SimulateElementClick(kUsernameName);
1262 // Simulate a user clicking on the password element. This should produce no
1263 // message.
1264 render_thread_->sink().ClearMessages();
1265 static_cast<PageClickListener*>(autofill_agent_)
1266 ->FormControlElementClicked(password_element_, false);
1267 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1268 AutofillHostMsg_ShowPasswordSuggestions::ID));
1271 // Tests the autosuggestions that are given when a password element is clicked,
1272 // the username element is not editable, and FillOnAccountSelect is enabled.
1273 // Specifically, tests when the user clicks on the password element after page
1274 // load, and the corresponding username element is readonly (and thus
1275 // uneditable), that the credentials for the already-filled username are
1276 // suggested.
1277 TEST_F(PasswordAutofillAgentTest,
1278 FillOnAccountSelectOnlyCredentialsOnPasswordClick) {
1279 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1280 autofill::switches::kEnableFillOnAccountSelect);
1282 // Simulate the browser sending back the login info.
1283 SimulateOnFillPasswordForm(fill_data_);
1285 // Clear the text fields to start fresh.
1286 ClearUsernameAndPasswordFields();
1288 // Simulate the page loading with a prefilled username element that is
1289 // uneditable.
1290 username_element_.setValue("alicia");
1291 SetElementReadOnly(username_element_, true);
1293 // Call SimulateElementClick() to produce a user gesture on the page so
1294 // autofill will actually fill.
1295 SimulateElementClick(kUsernameName);
1297 // Simulate a user clicking on the password element. This should produce a
1298 // message with "alicia" suggested as the credential.
1299 render_thread_->sink().ClearMessages();
1300 static_cast<PageClickListener*>(autofill_agent_)
1301 ->FormControlElementClicked(password_element_, false);
1302 CheckSuggestions("alicia", false);
1305 // Tests that there are no autosuggestions from the password manager when the
1306 // user clicks on the password field (not the username field).
1307 TEST_F(PasswordAutofillAgentTest, NoCredentialsOnPasswordClick) {
1308 // Simulate the browser sending back the login info.
1309 SimulateOnFillPasswordForm(fill_data_);
1311 // Clear the text fields to start fresh.
1312 ClearUsernameAndPasswordFields();
1314 // Call SimulateElementClick() to produce a user gesture on the page so
1315 // autofill will actually fill.
1316 SimulateElementClick(kUsernameName);
1318 // Simulate a user clicking on the password element. This should produce no
1319 // message.
1320 render_thread_->sink().ClearMessages();
1321 static_cast<PageClickListener*>(autofill_agent_)
1322 ->FormControlElementClicked(password_element_, false);
1323 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1324 AutofillHostMsg_ShowPasswordSuggestions::ID));
1327 // The user types in a username and a password, but then just before sending
1328 // the form off, a script clears them. This test checks that
1329 // PasswordAutofillAgent can still remember the username and the password
1330 // typed by the user.
1331 TEST_F(PasswordAutofillAgentTest,
1332 RememberLastNonEmptyUsernameAndPasswordOnSubmit_ScriptCleared) {
1333 SimulateUsernameChange("temp");
1334 SimulatePasswordChange("random");
1336 // Simulate that the username and the password value was cleared by the
1337 // site's JavaScript before submit.
1338 username_element_.setValue(WebString());
1339 password_element_.setValue(WebString());
1340 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1341 ->WillSubmitForm(username_element_.form());
1343 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1344 // username and password and sent that to the browser.
1345 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1348 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time
1349 // it's the user who clears the username and the password. This test checks
1350 // that in that case, the last non-empty username and password are not
1351 // remembered.
1352 TEST_F(PasswordAutofillAgentTest,
1353 RememberLastNonEmptyUsernameAndPasswordOnSubmit_UserCleared) {
1354 SimulateUsernameChange("temp");
1355 SimulatePasswordChange("random");
1357 // Simulate that the user actually cleared the username and password again.
1358 SimulateUsernameChange("");
1359 SimulatePasswordChange("");
1360 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1361 ->WillSubmitForm(username_element_.form());
1363 // Observe that the PasswordAutofillAgent respects the user having cleared the
1364 // password.
1365 ExpectFormSubmittedWithUsernameAndPasswords("", "", "");
1368 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the
1369 // new password instead of the current password.
1370 TEST_F(PasswordAutofillAgentTest,
1371 RememberLastNonEmptyUsernameAndPasswordOnSubmit_New) {
1372 const char kNewPasswordFormHTML[] =
1373 "<FORM name='LoginTestForm'>"
1374 " <INPUT type='text' id='username' autocomplete='username'/>"
1375 " <INPUT type='password' id='password' autocomplete='new-password'/>"
1376 " <INPUT type='submit' value='Login'/>"
1377 "</FORM>";
1378 LoadHTML(kNewPasswordFormHTML);
1379 UpdateUsernameAndPasswordElements();
1381 SimulateUsernameChange("temp");
1382 SimulatePasswordChange("random");
1384 // Simulate that the username and the password value was cleared by
1385 // the site's JavaScript before submit.
1386 username_element_.setValue(WebString());
1387 password_element_.setValue(WebString());
1388 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1389 ->WillSubmitForm(username_element_.form());
1391 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1392 // password and sent that to the browser.
1393 ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random");
1396 // The user first accepts a suggestion, but then overwrites the password. This
1397 // test checks that the overwritten password is not reverted back if the user
1398 // triggers autofill through focusing (but not changing) the username again.
1399 TEST_F(PasswordAutofillAgentTest,
1400 NoopEditingDoesNotOverwriteManuallyEditedPassword) {
1401 // Simulate having credentials which needed to wait until the user starts
1402 // typing the username to be filled (e.g., PSL-matched credentials). Those are
1403 // the ones which can be filled as a result of TextFieldDidEndEditing.
1404 fill_data_.wait_for_username = true;
1405 SimulateOnFillPasswordForm(fill_data_);
1406 // Simulate that the user typed her name to make the autofill work.
1407 SimulateUsernameChange(kAliceUsername);
1408 SimulateDidEndEditing(GetMainFrame(), username_element_);
1409 const std::string old_username(username_element_.value().utf8());
1410 const std::string old_password(password_element_.value().utf8());
1411 const std::string new_password(old_password + "modify");
1413 // The user changes the password.
1414 SimulatePasswordChange(new_password);
1416 // The user switches back into the username field, but leaves that without
1417 // changes.
1418 SimulateDidEndEditing(GetMainFrame(), username_element_);
1420 // The password should have stayed as the user changed it.
1421 CheckTextFieldsDOMState(old_username, true, new_password, false);
1422 // The password should not have a suggested value.
1423 CheckTextFieldsState(old_username, true, std::string(), false);
1426 // The user types in a username and a password, but then just before sending
1427 // the form off, a script changes them. This test checks that
1428 // PasswordAutofillAgent can still remember the username and the password
1429 // typed by the user.
1430 TEST_F(PasswordAutofillAgentTest,
1431 RememberLastTypedUsernameAndPasswordOnSubmit_ScriptChanged) {
1432 SimulateUsernameChange("temp");
1433 SimulatePasswordChange("random");
1435 // Simulate that the username and the password value was changed by the
1436 // site's JavaScript before submit.
1437 username_element_.setValue(WebString("new username"));
1438 password_element_.setValue(WebString("new password"));
1439 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1440 ->WillSendSubmitEvent(username_element_.form());
1441 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1442 ->WillSubmitForm(username_element_.form());
1444 // Observe that the PasswordAutofillAgent still remembered the last typed
1445 // username and password and sent that to the browser.
1446 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1449 // The username/password is autofilled by password manager then just before
1450 // sending the form off, a script changes them. This test checks that
1451 // PasswordAutofillAgent can still get the username and the password autofilled.
1452 TEST_F(PasswordAutofillAgentTest,
1453 RememberLastAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1454 SimulateOnFillPasswordForm(fill_data_);
1456 // Simulate that the username and the password value was changed by the
1457 // site's JavaScript before submit.
1458 username_element_.setValue(WebString("new username"));
1459 password_element_.setValue(WebString("new password"));
1460 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1461 ->WillSendSubmitEvent(username_element_.form());
1462 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1463 ->WillSubmitForm(username_element_.form());
1465 // Observe that the PasswordAutofillAgent still remembered the autofilled
1466 // username and password and sent that to the browser.
1467 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, kAlicePassword,
1468 "");
1471 // The username/password is autofilled by password manager then user types in a
1472 // username and a password. Then just before sending the form off, a script
1473 // changes them. This test checks that PasswordAutofillAgent can still remember
1474 // the username and the password typed by the user.
1475 TEST_F(
1476 PasswordAutofillAgentTest,
1477 RememberLastTypedAfterAutofilledUsernameAndPasswordOnSubmit_ScriptChanged) {
1478 SimulateOnFillPasswordForm(fill_data_);
1480 SimulateUsernameChange("temp");
1481 SimulatePasswordChange("random");
1483 // Simulate that the username and the password value was changed by the
1484 // site's JavaScript before submit.
1485 username_element_.setValue(WebString("new username"));
1486 password_element_.setValue(WebString("new password"));
1487 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1488 ->WillSendSubmitEvent(username_element_.form());
1489 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1490 ->WillSubmitForm(username_element_.form());
1492 // Observe that the PasswordAutofillAgent still remembered the last typed
1493 // username and password and sent that to the browser.
1494 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1497 // The user starts typing username then it is autofilled.
1498 // PasswordAutofillAgent should remember the username that was autofilled,
1499 // not last typed.
1500 TEST_F(PasswordAutofillAgentTest, RememberAutofilledUsername) {
1501 SimulateUsernameChange("Te");
1502 // Simulate that the username was changed by autofilling.
1503 username_element_.setValue(WebString("temp"));
1504 SimulatePasswordChange("random");
1506 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1507 ->WillSendSubmitEvent(username_element_.form());
1508 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1509 ->WillSubmitForm(username_element_.form());
1511 // Observe that the PasswordAutofillAgent still remembered the last typed
1512 // username and password and sent that to the browser.
1513 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1516 TEST_F(PasswordAutofillAgentTest, FormFillDataMustHaveUsername) {
1517 ClearUsernameAndPasswordFields();
1519 PasswordFormFillData no_username_fill_data = fill_data_;
1520 no_username_fill_data.username_field.name = base::string16();
1521 SimulateOnFillPasswordForm(no_username_fill_data);
1523 // The username and password should not have been autocompleted.
1524 CheckTextFieldsState("", false, "", false);
1527 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnly) {
1528 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1529 autofill::switches::kEnableFillOnAccountSelect);
1531 ClearUsernameAndPasswordFields();
1533 // Simulate the browser sending back the login info for an initial page load.
1534 SimulateOnFillPasswordForm(fill_data_);
1536 CheckTextFieldsState(std::string(), true, std::string(), false);
1539 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyReadonlyUsername) {
1540 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1541 autofill::switches::kEnableFillOnAccountSelect);
1543 ClearUsernameAndPasswordFields();
1545 username_element_.setValue("alice");
1546 SetElementReadOnly(username_element_, true);
1548 // Simulate the browser sending back the login info for an initial page load.
1549 SimulateOnFillPasswordForm(fill_data_);
1551 CheckTextFieldsState(std::string("alice"), false, std::string(), true);
1554 TEST_F(PasswordAutofillAgentTest,
1555 FillOnAccountSelectOnlyReadonlyNotPreferredUsername) {
1556 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1557 autofill::switches::kEnableFillOnAccountSelect);
1559 ClearUsernameAndPasswordFields();
1561 username_element_.setValue("Carol");
1562 SetElementReadOnly(username_element_, true);
1564 // Simulate the browser sending back the login info for an initial page load.
1565 SimulateOnFillPasswordForm(fill_data_);
1567 CheckTextFieldsState(std::string("Carol"), false, std::string(), true);
1570 TEST_F(PasswordAutofillAgentTest, FillOnAccountSelectOnlyNoUsername) {
1571 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1572 autofill::switches::kEnableFillOnAccountSelect);
1574 // Load a form with no username and update test data.
1575 LoadHTML(kVisibleFormWithNoUsernameHTML);
1576 username_element_.reset();
1577 WebDocument document = GetMainFrame()->document();
1578 WebElement element =
1579 document.getElementById(WebString::fromUTF8(kPasswordName));
1580 ASSERT_FALSE(element.isNull());
1581 password_element_ = element.to<blink::WebInputElement>();
1582 fill_data_.username_field = FormFieldData();
1583 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1584 fill_data_.additional_logins.clear();
1585 fill_data_.other_possible_usernames.clear();
1587 password_element_.setValue("");
1588 password_element_.setAutofilled(false);
1590 // Simulate the browser sending back the login info for an initial page load.
1591 SimulateOnFillPasswordForm(fill_data_);
1593 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1594 EXPECT_TRUE(password_element_.isAutofilled());
1597 TEST_F(PasswordAutofillAgentTest, ShowPopupNoUsername) {
1598 // Load a form with no username and update test data.
1599 LoadHTML(kVisibleFormWithNoUsernameHTML);
1600 username_element_.reset();
1601 WebDocument document = GetMainFrame()->document();
1602 WebElement element =
1603 document.getElementById(WebString::fromUTF8(kPasswordName));
1604 ASSERT_FALSE(element.isNull());
1605 password_element_ = element.to<blink::WebInputElement>();
1606 fill_data_.username_field = FormFieldData();
1607 UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
1608 fill_data_.additional_logins.clear();
1609 fill_data_.other_possible_usernames.clear();
1611 password_element_.setValue("");
1612 password_element_.setAutofilled(false);
1614 // Simulate the browser sending back the login info for an initial page load.
1615 SimulateOnFillPasswordForm(fill_data_);
1617 password_element_.setValue("123");
1618 password_element_.setAutofilled(false);
1620 SimulateSuggestionChoiceOfUsernameAndPassword(
1621 password_element_, base::string16(), ASCIIToUTF16(kAlicePassword));
1622 CheckSuggestions(std::string(), false);
1623 EXPECT_EQ(ASCIIToUTF16(kAlicePassword), password_element_.value());
1624 EXPECT_TRUE(password_element_.isAutofilled());
1627 // Tests with fill-on-account-select enabled that if the username element is
1628 // read-only and filled with an unknown username, then the password field is not
1629 // highlighted as autofillable (regression test for https://crbug.com/442564).
1630 TEST_F(PasswordAutofillAgentTest,
1631 FillOnAccountSelectOnlyReadonlyUnknownUsername) {
1632 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1633 autofill::switches::kEnableFillOnAccountSelect);
1635 ClearUsernameAndPasswordFields();
1637 username_element_.setValue("foobar");
1638 SetElementReadOnly(username_element_, true);
1640 CheckTextFieldsState(std::string("foobar"), false, std::string(), false);
1643 // Test that the last plain text field before a password field is chosen as a
1644 // username, in a form with 2 plain text fields without username predictions.
1645 TEST_F(PasswordAutofillAgentTest, FindingUsernameWithoutAutofillPredictions) {
1646 LoadHTML(kFormHTMLWithTwoTextFields);
1647 UpdateUsernameAndPasswordElements();
1648 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1649 SimulateUsernameChange("temp");
1650 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1651 SimulatePasswordChange("random");
1652 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1653 ->WillSendSubmitEvent(username_element_.form());
1654 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1655 ->WillSubmitForm(username_element_.form());
1657 // Observe that the PasswordAutofillAgent identifies the second field (e-mail)
1658 // as username.
1659 ExpectFormSubmittedWithUsernameAndPasswords("temp@google.com", "random", "");
1662 // Tests that field predictions are followed when identifying the username
1663 // and password in a password form with two plain text fields.
1664 TEST_F(PasswordAutofillAgentTest, FindingFieldsWithAutofillPredictions) {
1665 LoadHTML(kFormHTMLWithTwoTextFields);
1666 UpdateUsernameAndPasswordElements();
1667 blink::WebInputElement email_element = GetInputElementByID(kEmailName);
1668 SimulateUsernameChange("temp");
1669 SimulateUserInputChangeForElement(&email_element, "temp@google.com");
1670 SimulatePasswordChange("random");
1671 // Find FormData for visible password form.
1672 blink::WebFormElement form_element = username_element_.form();
1673 FormData form_data;
1674 ASSERT_TRUE(WebFormElementToFormData(form_element,
1675 blink::WebFormControlElement(),
1676 EXTRACT_NONE, &form_data, nullptr));
1677 // Simulate Autofill predictions: the first field is username, the third
1678 // one is password.
1679 std::map<autofill::FormData, PasswordFormFieldPredictionMap> predictions;
1680 predictions[form_data][form_data.fields[0]] = PREDICTION_USERNAME;
1681 predictions[form_data][form_data.fields[2]] = PREDICTION_NEW_PASSWORD;
1682 AutofillMsg_AutofillUsernameAndPasswordDataReceived msg(0, predictions);
1683 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1684 ->OnMessageReceived(msg);
1686 // The predictions should still match even if the form changes, as long
1687 // as the particular elements don't change.
1688 std::string add_field_to_form =
1689 "var form = document.getElementById('LoginTestForm');"
1690 "var new_input = document.createElement('input');"
1691 "new_input.setAttribute('type', 'text');"
1692 "new_input.setAttribute('id', 'other_field');"
1693 "form.appendChild(new_input);";
1694 ExecuteJavaScriptForTests(add_field_to_form.c_str());
1696 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1697 ->WillSendSubmitEvent(username_element_.form());
1698 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1699 ->WillSubmitForm(username_element_.form());
1701 // Observe that the PasswordAutofillAgent identifies the first field as
1702 // username.
1703 // TODO(msramek): We should also test that adding another password field
1704 // won't override the password field prediction either. However, the password
1705 // field predictions are not taken into account yet.
1706 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1709 // The user types in a username and a password. Then JavaScript changes password
1710 // field to readonly state before submit. PasswordAutofillAgent can correctly
1711 // process readonly password field. This test models behaviour of gmail.com.
1712 TEST_F(PasswordAutofillAgentTest, ReadonlyPasswordFieldOnSubmit) {
1713 SimulateUsernameChange("temp");
1714 SimulatePasswordChange("random");
1716 // Simulate that JavaScript makes password field readonly.
1717 SetElementReadOnly(password_element_, true);
1718 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1719 ->WillSubmitForm(username_element_.form());
1721 // Observe that the PasswordAutofillAgent can correctly process submitted
1722 // form.
1723 ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", "");
1726 // Verify that typed passwords are saved correctly when autofill and generation
1727 // both trigger. Regression test for https://crbug.com/493455
1728 TEST_F(PasswordAutofillAgentTest, PasswordGenerationTriggered_TypedPassword) {
1729 SimulateOnFillPasswordForm(fill_data_);
1731 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1732 SetAccountCreationFormsDetectedMessage(password_generation_,
1733 GetMainFrame()->document(),
1736 SimulateUsernameChange("NewGuy");
1737 SimulatePasswordChange("NewPassword");
1738 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1739 ->WillSendSubmitEvent(username_element_.form());
1740 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1741 ->WillSubmitForm(username_element_.form());
1743 ExpectFormSubmittedWithUsernameAndPasswords("NewGuy", "NewPassword", "");
1746 // Verify that generated passwords are saved correctly when autofill and
1747 // generation both trigger. Regression test for https://crbug.com/493455.
1748 TEST_F(PasswordAutofillAgentTest,
1749 PasswordGenerationTriggered_GeneratedPassword) {
1750 SimulateOnFillPasswordForm(fill_data_);
1752 SetNotBlacklistedMessage(password_generation_, kFormHTML);
1753 SetAccountCreationFormsDetectedMessage(password_generation_,
1754 GetMainFrame()->document(),
1757 base::string16 password = base::ASCIIToUTF16("NewPass22");
1758 AutofillMsg_GeneratedPasswordAccepted msg(0, password);
1759 password_generation_->OnMessageReceived(msg);
1761 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1762 ->WillSendSubmitEvent(username_element_.form());
1763 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1764 ->WillSubmitForm(username_element_.form());
1766 ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, "NewPass22", "");
1769 // If password generation is enabled for a field, password autofill should not
1770 // show UI.
1771 TEST_F(PasswordAutofillAgentTest, PasswordGenerationSupersedesAutofill) {
1772 LoadHTML(kSignupFormHTML);
1774 // Update password_element_;
1775 WebDocument document = GetMainFrame()->document();
1776 WebElement element =
1777 document.getElementById(WebString::fromUTF8("new_password"));
1778 ASSERT_FALSE(element.isNull());
1779 password_element_ = element.to<blink::WebInputElement>();
1781 // Update fill_data_ for the new form and simulate filling. Pretend as if
1782 // the password manager didn't detect a username field so it will try to
1783 // show UI when the password field is focused.
1784 fill_data_.wait_for_username = true;
1785 fill_data_.username_field = FormFieldData();
1786 fill_data_.password_field.name = base::ASCIIToUTF16("new_password");
1787 UpdateOriginForHTML(kSignupFormHTML);
1788 SimulateOnFillPasswordForm(fill_data_);
1790 // Simulate generation triggering.
1791 SetNotBlacklistedMessage(password_generation_,
1792 kSignupFormHTML);
1793 SetAccountCreationFormsDetectedMessage(password_generation_,
1794 GetMainFrame()->document(),
1797 // Simulate the field being clicked to start typing. This should trigger
1798 // generation but not password autofill.
1799 SetFocused(password_element_);
1800 SimulateElementClick("new_password");
1801 EXPECT_EQ(nullptr,
1802 render_thread_->sink().GetFirstMessageMatching(
1803 AutofillHostMsg_ShowPasswordSuggestions::ID));
1804 ExpectPasswordGenerationAvailable(password_generation_, true);
1807 // Tests that a password change form is properly filled with the username and
1808 // password.
1809 TEST_F(PasswordAutofillAgentTest, FillSuggestionPasswordChangeForms) {
1810 LoadHTML(kPasswordChangeFormHTML);
1811 UpdateOriginForHTML(kPasswordChangeFormHTML);
1812 UpdateUsernameAndPasswordElements();
1813 // Simulate the browser sending the login info, but set |wait_for_username|
1814 // to prevent the form from being immediately filled.
1815 fill_data_.wait_for_username = true;
1816 fill_data_.is_possible_change_password_form = true;
1817 SimulateOnFillPasswordForm(fill_data_);
1819 // Neither field should have been autocompleted.
1820 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1822 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1823 username_element_, kAliceUsername, kAlicePassword));
1824 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1827 // Tests that a password change form is properly filled with the password when
1828 // the user click on the password field.
1829 TEST_F(PasswordAutofillAgentTest,
1830 FillSuggestionPasswordChangeFormsOnlyPassword) {
1831 LoadHTML(kPasswordChangeFormHTML);
1832 UpdateOriginForHTML(kPasswordChangeFormHTML);
1833 UpdateUsernameAndPasswordElements();
1834 // Simulate the browser sending the login info, but set |wait_for_username|
1835 // to prevent the form from being immediately filled.
1836 fill_data_.wait_for_username = true;
1837 fill_data_.is_possible_change_password_form = true;
1838 SimulateOnFillPasswordForm(fill_data_);
1840 // Neither field should have been autocompleted.
1841 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1843 EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1844 password_element_, kAliceUsername, kAlicePassword));
1845 CheckTextFieldsDOMState("", false, kAlicePassword, true);
1848 // Tests that one user click on a username field is sufficient to bring up a
1849 // credential suggestion popup on a change password form.
1850 TEST_F(PasswordAutofillAgentTest,
1851 SuggestionsOnUsernameFieldOfChangePasswordForm) {
1852 LoadHTML(kPasswordChangeFormHTML);
1853 UpdateOriginForHTML(kPasswordChangeFormHTML);
1854 UpdateUsernameAndPasswordElements();
1856 ClearUsernameAndPasswordFields();
1857 fill_data_.wait_for_username = true;
1858 fill_data_.is_possible_change_password_form = true;
1859 SimulateOnFillPasswordForm(fill_data_);
1860 // Simulate a user clicking on the username element. This should produce a
1861 // message.
1862 render_thread_->sink().ClearMessages();
1863 static_cast<PageClickListener*>(autofill_agent_)
1864 ->FormControlElementClicked(username_element_, true);
1865 CheckSuggestions("", true);
1868 // Tests that one user click on a password field is sufficient to bring up a
1869 // credential suggestion popup on a change password form.
1870 TEST_F(PasswordAutofillAgentTest,
1871 SuggestionsOnPasswordFieldOfChangePasswordForm) {
1872 LoadHTML(kPasswordChangeFormHTML);
1873 UpdateOriginForHTML(kPasswordChangeFormHTML);
1874 UpdateUsernameAndPasswordElements();
1876 ClearUsernameAndPasswordFields();
1877 fill_data_.wait_for_username = true;
1878 fill_data_.is_possible_change_password_form = true;
1879 SimulateOnFillPasswordForm(fill_data_);
1880 // Simulate a user clicking on the password element. This should produce a
1881 // message.
1882 render_thread_->sink().ClearMessages();
1883 static_cast<PageClickListener*>(autofill_agent_)
1884 ->FormControlElementClicked(password_element_, true);
1885 CheckSuggestions("", false);
1888 // Tests that there are no autosuggestions from the password manager when the
1889 // user clicks on the password field of change password form after the user
1890 // typed in the username field.
1891 TEST_F(PasswordAutofillAgentTest,
1892 NoSuggestionsOnPasswordFieldOfChangePasswordFormAfterUsernameTyping) {
1893 LoadHTML(kPasswordChangeFormHTML);
1894 UpdateOriginForHTML(kPasswordChangeFormHTML);
1895 UpdateUsernameAndPasswordElements();
1897 ClearUsernameAndPasswordFields();
1898 fill_data_.wait_for_username = true;
1899 fill_data_.is_possible_change_password_form = true;
1900 SimulateOnFillPasswordForm(fill_data_);
1902 // Clear the text fields to start fresh.
1903 SimulateUsernameChange("temp");
1905 // Simulate a user clicking on the password element. This should produce no
1906 // message.
1907 render_thread_->sink().ClearMessages();
1908 static_cast<PageClickListener*>(autofill_agent_)
1909 ->FormControlElementClicked(password_element_, false);
1910 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
1911 AutofillHostMsg_ShowPasswordSuggestions::ID));
1914 // Tests that NOT_PASSWORD field predictions are followed so that no password
1915 // form is submitted.
1916 TEST_F(PasswordAutofillAgentTest, IgnoreNotPasswordFields) {
1917 LoadHTML(kCreditCardFormHTML);
1918 blink::WebInputElement credit_card_owner_element =
1919 GetInputElementByID(kCreditCardOwnerName);
1920 blink::WebInputElement credit_card_number_element =
1921 GetInputElementByID(kCreditCardNumberName);
1922 blink::WebInputElement credit_card_verification_element =
1923 GetInputElementByID(kCreditCardVerificationName);
1924 SimulateUserInputChangeForElement(&credit_card_owner_element, "JohnSmith");
1925 SimulateUserInputChangeForElement(&credit_card_number_element,
1926 "1234123412341234");
1927 SimulateUserInputChangeForElement(&credit_card_verification_element, "123");
1928 // Find FormData for visible form.
1929 blink::WebFormElement form_element = credit_card_number_element.form();
1930 FormData form_data;
1931 ASSERT_TRUE(WebFormElementToFormData(form_element,
1932 blink::WebFormControlElement(),
1933 EXTRACT_NONE, &form_data, nullptr));
1934 // Simulate Autofill predictions: the third field is not a password.
1935 std::map<autofill::FormData, PasswordFormFieldPredictionMap> predictions;
1936 predictions[form_data][form_data.fields[2]] = PREDICTION_NOT_PASSWORD;
1937 AutofillMsg_AutofillUsernameAndPasswordDataReceived msg(0, predictions);
1938 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1939 ->OnMessageReceived(msg);
1941 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1942 ->WillSendSubmitEvent(form_element);
1943 static_cast<content::RenderFrameObserver*>(password_autofill_agent_)
1944 ->WillSubmitForm(form_element);
1946 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1947 AutofillHostMsg_PasswordFormSubmitted::ID);
1948 ASSERT_FALSE(message);
1951 // Tests that only the password field is autocompleted when the browser sends
1952 // back data with only one credentials and empty username.
1953 TEST_F(PasswordAutofillAgentTest, NotAutofillNoUsername) {
1954 fill_data_.username_field.value.clear();
1955 fill_data_.additional_logins.clear();
1956 SimulateOnFillPasswordForm(fill_data_);
1958 CheckTextFieldsState("", false, kAlicePassword, true);
1961 // Tests that both the username and the password fields are autocompleted
1962 // despite the empty username, when the browser sends back data more than one
1963 // credential.
1964 TEST_F(PasswordAutofillAgentTest,
1965 AutofillNoUsernameWhenOtherCredentialsStored) {
1966 fill_data_.username_field.value.clear();
1967 ASSERT_FALSE(fill_data_.additional_logins.empty());
1968 SimulateOnFillPasswordForm(fill_data_);
1970 CheckTextFieldsState("", true, kAlicePassword, true);
1973 } // namespace autofill