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