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