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