Revert "Fix for missing change in the revert of default surprise me behaviour."
[chromium-blink-merge.git] / chrome / renderer / autofill / password_autofill_agent_browsertest.cc
blob05403e77a28f3191f97fa08f034428344e5c14ef
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/test/base/chrome_render_view_test.h"
8 #include "components/autofill/content/common/autofill_messages.h"
9 #include "components/autofill/content/renderer/autofill_agent.h"
10 #include "components/autofill/content/renderer/form_autofill_util.h"
11 #include "components/autofill/content/renderer/password_autofill_agent.h"
12 #include "components/autofill/content/renderer/test_password_autofill_agent.h"
13 #include "components/autofill/core/common/form_data.h"
14 #include "components/autofill/core/common/form_field_data.h"
15 #include "components/autofill/core/common/password_autofill_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/platform/WebVector.h"
19 #include "third_party/WebKit/public/web/WebDocument.h"
20 #include "third_party/WebKit/public/web/WebElement.h"
21 #include "third_party/WebKit/public/web/WebFormElement.h"
22 #include "third_party/WebKit/public/web/WebInputElement.h"
23 #include "third_party/WebKit/public/web/WebLocalFrame.h"
24 #include "third_party/WebKit/public/web/WebNode.h"
25 #include "third_party/WebKit/public/web/WebView.h"
26 #include "ui/events/keycodes/keyboard_codes.h"
28 using autofill::PasswordForm;
29 using base::ASCIIToUTF16;
30 using base::UTF16ToUTF8;
31 using blink::WebDocument;
32 using blink::WebElement;
33 using blink::WebFrame;
34 using blink::WebInputElement;
35 using blink::WebString;
36 using blink::WebView;
38 namespace {
40 // The name of the username/password element in the form.
41 const char kUsernameName[] = "username";
42 const char kPasswordName[] = "password";
44 const char kAliceUsername[] = "alice";
45 const char kAlicePassword[] = "password";
46 const char kBobUsername[] = "bob";
47 const char kBobPassword[] = "secret";
48 const char kCarolUsername[] = "Carol";
49 const char kCarolPassword[] = "test";
50 const char kCarolAlternateUsername[] = "RealCarolUsername";
52 const char kFormHTML[] =
53 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
54 " <INPUT type='text' id='username'/>"
55 " <INPUT type='password' id='password'/>"
56 " <INPUT type='submit' value='Login'/>"
57 "</FORM>";
59 const char kVisibleFormHTML[] =
60 "<head> <style> form {display: inline;} </style> </head>"
61 "<body>"
62 " <form>"
63 " <div>"
64 " <input type='password' id='password'/>"
65 " </div>"
66 " </form>"
67 "</body>";
69 const char kEmptyFormHTML[] =
70 "<head> <style> form {display: inline;} </style> </head>"
71 "<body> <form> </form> </body>";
73 const char kNonVisibleFormHTML[] =
74 "<head> <style> form {display: none;} </style> </head>"
75 "<body>"
76 " <form>"
77 " <div>"
78 " <input type='password' id='password'/>"
79 " </div>"
80 " </form>"
81 "</body>";
83 const char kEmptyWebpage[] =
84 "<html>"
85 " <head>"
86 " </head>"
87 " <body>"
88 " </body>"
89 "</html>";
91 const char kRedirectionWebpage[] =
92 "<html>"
93 " <head>"
94 " <meta http-equiv='Content-Type' content='text/html'>"
95 " <title>Redirection page</title>"
96 " <script></script>"
97 " </head>"
98 " <body>"
99 " <script type='text/javascript'>"
100 " function test(){}"
101 " </script>"
102 " </body>"
103 "</html>";
105 const char kSimpleWebpage[] =
106 "<html>"
107 " <head>"
108 " <meta charset='utf-8' />"
109 " <title>Title</title>"
110 " </head>"
111 " <body>"
112 " <form name='LoginTestForm'>"
113 " <input type='text' id='username'/>"
114 " <input type='password' id='password'/>"
115 " <input type='submit' value='Login'/>"
116 " </form>"
117 " </body>"
118 "</html>";
120 const char kWebpageWithDynamicContent[] =
121 "<html>"
122 " <head>"
123 " <meta charset='utf-8' />"
124 " <title>Title</title>"
125 " </head>"
126 " <body>"
127 " <script type='text/javascript'>"
128 " function addParagraph() {"
129 " var p = document.createElement('p');"
130 " document.body.appendChild(p);"
131 " }"
132 " window.onload = addParagraph;"
133 " </script>"
134 " </body>"
135 "</html>";
137 const char kJavaScriptClick[] =
138 "var event = new MouseEvent('click', {"
139 " 'view': window,"
140 " 'bubbles': true,"
141 " 'cancelable': true"
142 "});"
143 "var form = document.getElementById('myform1');"
144 "form.dispatchEvent(event);"
145 "console.log('clicked!');";
147 const char kOnChangeDetectionScript[] =
148 "<script>"
149 " usernameOnchangeCalled = false;"
150 " passwordOnchangeCalled = false;"
151 " document.getElementById('username').onchange = function() {"
152 " usernameOnchangeCalled = true;"
153 " };"
154 " document.getElementById('password').onchange = function() {"
155 " passwordOnchangeCalled = true;"
156 " };"
157 "</script>";
159 // Sets the "readonly" attribute of |element| to the value given by |read_only|.
160 void SetElementReadOnly(WebInputElement& element, bool read_only) {
161 element.setAttribute(WebString::fromUTF8("readonly"),
162 read_only ? WebString::fromUTF8("true") : WebString());
165 } // namespace
167 namespace autofill {
169 class PasswordAutofillAgentTest : public ChromeRenderViewTest {
170 public:
171 PasswordAutofillAgentTest() {
174 // Simulates the fill password form message being sent to the renderer.
175 // We use that so we don't have to make RenderView::OnFillPasswordForm()
176 // protected.
177 void SimulateOnFillPasswordForm(
178 const PasswordFormFillData& fill_data) {
179 AutofillMsg_FillPasswordForm msg(0, fill_data);
180 password_autofill_->OnMessageReceived(msg);
183 void SendVisiblePasswordForms() {
184 password_autofill_->SendPasswordForms(GetMainFrame(),
185 true /* only_visible */);
188 virtual void SetUp() {
189 ChromeRenderViewTest::SetUp();
191 // Add a preferred login and an additional login to the FillData.
192 username1_ = ASCIIToUTF16(kAliceUsername);
193 password1_ = ASCIIToUTF16(kAlicePassword);
194 username2_ = ASCIIToUTF16(kBobUsername);
195 password2_ = ASCIIToUTF16(kBobPassword);
196 username3_ = ASCIIToUTF16(kCarolUsername);
197 password3_ = ASCIIToUTF16(kCarolPassword);
198 alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
200 FormFieldData username_field;
201 username_field.name = ASCIIToUTF16(kUsernameName);
202 username_field.value = username1_;
203 fill_data_.basic_data.fields.push_back(username_field);
205 FormFieldData password_field;
206 password_field.name = ASCIIToUTF16(kPasswordName);
207 password_field.value = password1_;
208 password_field.form_control_type = "password";
209 fill_data_.basic_data.fields.push_back(password_field);
211 PasswordAndRealm password2;
212 password2.password = password2_;
213 fill_data_.additional_logins[username2_] = password2;
214 PasswordAndRealm password3;
215 password3.password = password3_;
216 fill_data_.additional_logins[username3_] = password3;
218 UsernamesCollectionKey key;
219 key.username = username3_;
220 key.password = password3_;
221 key.realm = "google.com";
222 fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
224 // We need to set the origin so it matches the frame URL and the action so
225 // it matches the form action, otherwise we won't autocomplete.
226 UpdateOriginForHTML(kFormHTML);
227 fill_data_.basic_data.action = GURL("http://www.bidule.com");
229 LoadHTML(kFormHTML);
231 // Now retrieve the input elements so the test can access them.
232 UpdateUsernameAndPasswordElements();
235 virtual void TearDown() {
236 username_element_.reset();
237 password_element_.reset();
238 ChromeRenderViewTest::TearDown();
241 void UpdateOriginForHTML(const std::string& html) {
242 std::string origin = "data:text/html;charset=utf-8," + html;
243 fill_data_.basic_data.origin = GURL(origin);
246 void UpdateUsernameAndPasswordElements() {
247 WebDocument document = GetMainFrame()->document();
248 WebElement element =
249 document.getElementById(WebString::fromUTF8(kUsernameName));
250 ASSERT_FALSE(element.isNull());
251 username_element_ = element.to<blink::WebInputElement>();
252 element = document.getElementById(WebString::fromUTF8(kPasswordName));
253 ASSERT_FALSE(element.isNull());
254 password_element_ = element.to<blink::WebInputElement>();
257 void ClearUsernameAndPasswordFields() {
258 username_element_.setValue("");
259 username_element_.setAutofilled(false);
260 password_element_.setValue("");
261 password_element_.setAutofilled(false);
264 void SimulateUsernameChangeForElement(const std::string& username,
265 bool move_caret_to_end,
266 WebFrame* input_frame,
267 WebInputElement& username_input,
268 bool is_user_input) {
269 username_input.setValue(WebString::fromUTF8(username), is_user_input);
270 // The field must have focus or AutofillAgent will think the
271 // change should be ignored.
272 while (!username_input.focused())
273 input_frame->document().frame()->view()->advanceFocus(false);
274 if (move_caret_to_end)
275 username_input.setSelectionRange(username.length(), username.length());
276 if (is_user_input)
277 password_autofill_agent()->FirstUserGestureObserved();
278 autofill_agent_->textFieldDidChange(username_input);
279 // Processing is delayed because of a Blink bug:
280 // https://bugs.webkit.org/show_bug.cgi?id=16976
281 // See PasswordAutofillAgent::TextDidChangeInTextField() for details.
283 // Autocomplete will trigger a style recalculation when we put up the next
284 // frame, but we don't want to wait that long. Instead, trigger a style
285 // recalcuation manually after TextFieldDidChangeImpl runs.
286 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
287 &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this)));
289 base::MessageLoop::current()->RunUntilIdle();
292 void SimulateSuggestionChoice(WebInputElement& username_input) {
293 blink::WebString blink_username =
294 blink::WebString::fromUTF8(kAliceUsername);
295 blink::WebString blink_password =
296 blink::WebString::fromUTF8(kAlicePassword);
298 // This call is necessary to setup the autofill agent appropriate for the
299 // user selection; simulates the menu actually popping up.
300 render_thread_->sink().ClearMessages();
301 autofill_agent_->FormControlElementClicked(username_input, false);
303 autofill_agent_->OnFillPasswordSuggestion(blink_username, blink_password);
306 void LayoutMainFrame() {
307 GetMainFrame()->view()->layout();
310 void SimulateUsernameChange(const std::string& username,
311 bool move_caret_to_end,
312 bool is_user_input = false) {
313 SimulateUsernameChangeForElement(username,
314 move_caret_to_end,
315 GetMainFrame(),
316 username_element_,
317 is_user_input);
320 // Tests that no suggestion popup is generated when the username_element_ is
321 // edited.
322 void ExpectNoSuggestionsPopup() {
323 // The first test below ensures that the suggestions have been handled by
324 // the password_autofill_agent, even though autocomplete='off' is set. The
325 // second check ensures that, although handled, no "show suggestions" IPC to
326 // the browser was generated.
328 // This is interesting in the specific case of an autocomplete='off' form
329 // that also has a remembered username and password
330 // (http://crbug.com/326679). To fix the DCHECK that this case used to hit,
331 // |true| is returned from ShowSuggestions for all forms with valid
332 // usersnames that are autocomplete='off', prentending that a selection box
333 // has been shown to the user. Of course, it hasn't, so a message is never
334 // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing
335 // is filled).
337 // These tests only make sense in the context of not ignoring
338 // autocomplete='off', so only test them if the disable autocomplete='off'
339 // flag is not enabled.
340 // TODO(jww): Remove this function and callers once autocomplete='off' is
341 // permanently ignored.
342 if (!ShouldIgnoreAutocompleteOffForPasswordFields()) {
343 EXPECT_TRUE(
344 password_autofill_agent()->ShowSuggestions(username_element_, false));
346 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
347 AutofillHostMsg_ShowPasswordSuggestions::ID));
351 void SimulateKeyDownEvent(const WebInputElement& element,
352 ui::KeyboardCode key_code) {
353 blink::WebKeyboardEvent key_event;
354 key_event.windowsKeyCode = key_code;
355 autofill_agent_->textFieldDidReceiveKeyDown(element, key_event);
358 void CheckTextFieldsStateForElements(const WebInputElement& username_element,
359 const std::string& username,
360 bool username_autofilled,
361 const WebInputElement& password_element,
362 const std::string& password,
363 bool password_autofilled,
364 bool checkSuggestedValue) {
365 EXPECT_EQ(username,
366 static_cast<std::string>(username_element.value().utf8()));
367 EXPECT_EQ(username_autofilled, username_element.isAutofilled());
368 EXPECT_EQ(password,
369 static_cast<std::string>(
370 checkSuggestedValue ? password_element.suggestedValue().utf8()
371 : password_element.value().utf8()));
372 EXPECT_EQ(password_autofilled, password_element.isAutofilled());
375 // Checks the DOM-accessible value of the username element and the
376 // *suggested* value of the password element.
377 void CheckTextFieldsState(const std::string& username,
378 bool username_autofilled,
379 const std::string& password,
380 bool password_autofilled) {
381 CheckTextFieldsStateForElements(username_element_,
382 username,
383 username_autofilled,
384 password_element_,
385 password,
386 password_autofilled,
387 true);
390 // Checks the DOM-accessible value of the username element and the
391 // DOM-accessible value of the password element.
392 void CheckTextFieldsDOMState(const std::string& username,
393 bool username_autofilled,
394 const std::string& password,
395 bool password_autofilled) {
396 CheckTextFieldsStateForElements(username_element_,
397 username,
398 username_autofilled,
399 password_element_,
400 password,
401 password_autofilled,
402 false);
405 void CheckUsernameSelection(int start, int end) {
406 EXPECT_EQ(start, username_element_.selectionStart());
407 EXPECT_EQ(end, username_element_.selectionEnd());
410 void ExpectOneCredential(const base::string16& username) {
411 const IPC::Message* message =
412 render_thread_->sink().GetFirstMessageMatching(
413 AutofillHostMsg_ShowPasswordSuggestions::ID);
414 ASSERT_TRUE(message);
415 Tuple4<autofill::FormFieldData,
416 gfx::RectF,
417 std::vector<base::string16>,
418 std::vector<base::string16> > args;
419 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
420 ASSERT_EQ(1u, args.c.size());
421 EXPECT_TRUE(args.c[0] == username);
424 void ExpectAllCredentials() {
425 std::set<base::string16> usernames;
426 usernames.insert(username1_);
427 usernames.insert(username2_);
428 usernames.insert(username3_);
429 usernames.insert(alternate_username3_);
431 const IPC::Message* message =
432 render_thread_->sink().GetFirstMessageMatching(
433 AutofillHostMsg_ShowPasswordSuggestions::ID);
434 ASSERT_TRUE(message);
435 Tuple4<autofill::FormFieldData,
436 gfx::RectF,
437 std::vector<base::string16>,
438 std::vector<base::string16> > args;
439 AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
440 ASSERT_EQ(4u, args.c.size());
441 std::set<base::string16>::iterator it;
443 for (int i = 0; i < 4; i++) {
444 it = usernames.find(args.c[i]);
445 EXPECT_TRUE(it != usernames.end());
446 if (it != usernames.end())
447 usernames.erase(it);
450 EXPECT_TRUE(usernames.empty());
452 render_thread_->sink().ClearMessages();
455 PasswordAutofillAgent* password_autofill_agent() {
456 return autofill_agent_->password_autofill_agent_;
459 void ExpectFormSubmittedWithPasswords(const std::string& password_value,
460 const std::string& new_password_value) {
461 const IPC::Message* message =
462 render_thread_->sink().GetFirstMessageMatching(
463 AutofillHostMsg_PasswordFormSubmitted::ID);
464 ASSERT_TRUE(message);
465 Tuple1<autofill::PasswordForm> args;
466 AutofillHostMsg_PasswordFormSubmitted::Read(message, &args);
467 EXPECT_EQ(ASCIIToUTF16(password_value), args.a.password_value);
468 EXPECT_EQ(ASCIIToUTF16(new_password_value), args.a.new_password_value);
471 base::string16 username1_;
472 base::string16 username2_;
473 base::string16 username3_;
474 base::string16 password1_;
475 base::string16 password2_;
476 base::string16 password3_;
477 base::string16 alternate_username3_;
478 PasswordFormFillData fill_data_;
480 WebInputElement username_element_;
481 WebInputElement password_element_;
483 private:
484 DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
487 // Tests that the password login is autocompleted as expected when the browser
488 // sends back the password info.
489 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
491 * Right now we are not sending the message to the browser because we are
492 * loading a data URL and the security origin canAccessPasswordManager()
493 * returns false. May be we should mock URL loading to cirmcuvent this?
494 TODO(jcivelli): find a way to make the security origin not deny access to the
495 password manager and then reenable this code.
497 // The form has been loaded, we should have sent the browser a message about
498 // the form.
499 const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
500 AutofillHostMsg_PasswordFormsParsed::ID);
501 ASSERT_TRUE(msg != NULL);
503 Tuple1<std::vector<PasswordForm> > forms;
504 AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
505 ASSERT_EQ(1U, forms.a.size());
506 PasswordForm password_form = forms.a[0];
507 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
508 EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
509 EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
512 // Simulate the browser sending back the login info, it triggers the
513 // autocomplete.
514 SimulateOnFillPasswordForm(fill_data_);
516 // The username and password should have been autocompleted.
517 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
520 // Tests that we correctly fill forms having an empty 'action' attribute.
521 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
522 const char kEmptyActionFormHTML[] =
523 "<FORM name='LoginTestForm'>"
524 " <INPUT type='text' id='username'/>"
525 " <INPUT type='password' id='password'/>"
526 " <INPUT type='submit' value='Login'/>"
527 "</FORM>";
528 LoadHTML(kEmptyActionFormHTML);
530 // Retrieve the input elements so the test can access them.
531 WebDocument document = GetMainFrame()->document();
532 WebElement element =
533 document.getElementById(WebString::fromUTF8(kUsernameName));
534 ASSERT_FALSE(element.isNull());
535 username_element_ = element.to<blink::WebInputElement>();
536 element = document.getElementById(WebString::fromUTF8(kPasswordName));
537 ASSERT_FALSE(element.isNull());
538 password_element_ = element.to<blink::WebInputElement>();
540 // Set the expected form origin and action URLs.
541 UpdateOriginForHTML(kEmptyActionFormHTML);
542 fill_data_.basic_data.action = fill_data_.basic_data.origin;
544 // Simulate the browser sending back the login info, it triggers the
545 // autocomplete.
546 SimulateOnFillPasswordForm(fill_data_);
548 // The username and password should have been autocompleted.
549 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
552 // Tests that if a password is marked as readonly, neither field is autofilled
553 // on page load.
554 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
555 SetElementReadOnly(password_element_, true);
557 // Simulate the browser sending back the login info, it triggers the
558 // autocomplete.
559 SimulateOnFillPasswordForm(fill_data_);
561 CheckTextFieldsState(std::string(), false, std::string(), false);
564 // Can still fill a password field if the username is set to a value that
565 // matches.
566 TEST_F(PasswordAutofillAgentTest,
567 AutocompletePasswordForReadonlyUsernameMatched) {
568 username_element_.setValue(username3_);
569 SetElementReadOnly(username_element_, true);
571 // Filled even though username is not the preferred match.
572 SimulateOnFillPasswordForm(fill_data_);
573 CheckTextFieldsState(UTF16ToUTF8(username3_), false,
574 UTF16ToUTF8(password3_), true);
577 // If a username field is empty and readonly, don't autofill.
578 TEST_F(PasswordAutofillAgentTest,
579 NoAutocompletePasswordForReadonlyUsernameUnmatched) {
580 username_element_.setValue(WebString::fromUTF8(""));
581 SetElementReadOnly(username_element_, true);
583 SimulateOnFillPasswordForm(fill_data_);
584 CheckTextFieldsState(std::string(), false, std::string(), false);
587 // Tests that having a non-matching username precludes the autocomplete.
588 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
589 username_element_.setValue(WebString::fromUTF8("bogus"));
591 // Simulate the browser sending back the login info, it triggers the
592 // autocomplete.
593 SimulateOnFillPasswordForm(fill_data_);
595 // Neither field should be autocompleted.
596 CheckTextFieldsState("bogus", false, std::string(), false);
599 // Don't try to complete a prefilled value even if it's a partial match
600 // to a username.
601 TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
602 username_element_.setValue(WebString::fromUTF8("ali"));
604 SimulateOnFillPasswordForm(fill_data_);
606 CheckTextFieldsState("ali", false, std::string(), false);
609 TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
610 const char kNoFormInputs[] =
611 "<input type='text' id='username'/>"
612 "<input type='password' id='password'/>";
613 LoadHTML(kNoFormInputs);
615 SimulateOnFillPasswordForm(fill_data_);
617 // Input elements that aren't in a <form> won't autofill.
618 CheckTextFieldsState(std::string(), false, std::string(), false);
621 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
622 const char kTextFieldPasswordFormHTML[] =
623 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
624 " <INPUT type='text' id='username'/>"
625 " <INPUT type='text' id='password'/>"
626 " <INPUT type='submit' value='Login'/>"
627 "</FORM>";
628 LoadHTML(kTextFieldPasswordFormHTML);
630 // Retrieve the input elements so the test can access them.
631 WebDocument document = GetMainFrame()->document();
632 WebElement element =
633 document.getElementById(WebString::fromUTF8(kUsernameName));
634 ASSERT_FALSE(element.isNull());
635 username_element_ = element.to<blink::WebInputElement>();
636 element = document.getElementById(WebString::fromUTF8(kPasswordName));
637 ASSERT_FALSE(element.isNull());
638 password_element_ = element.to<blink::WebInputElement>();
640 // Set the expected form origin URL.
641 UpdateOriginForHTML(kTextFieldPasswordFormHTML);
643 SimulateOnFillPasswordForm(fill_data_);
645 // Fields should still be empty.
646 CheckTextFieldsState(std::string(), false, std::string(), false);
649 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
650 const char kPasswordFieldUsernameFormHTML[] =
651 "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
652 " <INPUT type='password' id='username'/>"
653 " <INPUT type='password' id='password'/>"
654 " <INPUT type='submit' value='Login'/>"
655 "</FORM>";
656 LoadHTML(kPasswordFieldUsernameFormHTML);
658 // Retrieve the input elements so the test can access them.
659 WebDocument document = GetMainFrame()->document();
660 WebElement element =
661 document.getElementById(WebString::fromUTF8(kUsernameName));
662 ASSERT_FALSE(element.isNull());
663 username_element_ = element.to<blink::WebInputElement>();
664 element = document.getElementById(WebString::fromUTF8(kPasswordName));
665 ASSERT_FALSE(element.isNull());
666 password_element_ = element.to<blink::WebInputElement>();
668 // Set the expected form origin URL.
669 UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
671 SimulateOnFillPasswordForm(fill_data_);
673 // Fields should still be empty.
674 CheckTextFieldsState(std::string(), false, std::string(), false);
677 // Tests that having a matching username does not preclude the autocomplete.
678 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
679 username_element_.setValue(WebString::fromUTF8(kAliceUsername));
681 // Simulate the browser sending back the login info, it triggers the
682 // autocomplete.
683 SimulateOnFillPasswordForm(fill_data_);
685 // The username and password should have been autocompleted.
686 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
689 // Tests that editing the password clears the autocompleted password field.
690 TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
691 // Simulate the browser sending back the login info, it triggers the
692 // autocomplete.
693 SimulateOnFillPasswordForm(fill_data_);
695 // Simulate the user changing the username to some unknown username.
696 SimulateUsernameChange("alicia", true);
698 // The password should have been cleared.
699 CheckTextFieldsState("alicia", false, std::string(), false);
702 // Tests that we only autocomplete on focus lost and with a full username match
703 // when |wait_for_username| is true.
704 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
705 // Simulate the browser sending back the login info.
706 fill_data_.wait_for_username = true;
707 SimulateOnFillPasswordForm(fill_data_);
709 // No auto-fill should have taken place.
710 CheckTextFieldsState(std::string(), false, std::string(), false);
712 // No autocomplete should happen when text is entered in the username.
713 SimulateUsernameChange("a", true);
714 CheckTextFieldsState("a", false, std::string(), false);
715 SimulateUsernameChange("al", true);
716 CheckTextFieldsState("al", false, std::string(), false);
717 SimulateUsernameChange(kAliceUsername, true);
718 CheckTextFieldsState(kAliceUsername, false, std::string(), false);
720 // Autocomplete should happen only when the username textfield is blurred with
721 // a full match.
722 username_element_.setValue("a");
723 autofill_agent_->textFieldDidEndEditing(username_element_);
724 CheckTextFieldsState("a", false, std::string(), false);
725 username_element_.setValue("al");
726 autofill_agent_->textFieldDidEndEditing(username_element_);
727 CheckTextFieldsState("al", false, std::string(), false);
728 username_element_.setValue("alices");
729 autofill_agent_->textFieldDidEndEditing(username_element_);
730 CheckTextFieldsState("alices", false, std::string(), false);
731 username_element_.setValue(ASCIIToUTF16(kAliceUsername));
732 autofill_agent_->textFieldDidEndEditing(username_element_);
733 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
736 // Tests that inline autocompletion works properly.
737 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
738 // Simulate the browser sending back the login info.
739 SimulateOnFillPasswordForm(fill_data_);
741 ClearUsernameAndPasswordFields();
743 // Simulate the user typing in the first letter of 'alice', a stored
744 // username.
745 SimulateUsernameChange("a", true);
746 // Both the username and password text fields should reflect selection of the
747 // stored login.
748 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
749 // And the selection should have been set to 'lice', the last 4 letters.
750 CheckUsernameSelection(1, 5);
752 // Now the user types the next letter of the same username, 'l'.
753 SimulateUsernameChange("al", true);
754 // Now the fields should have the same value, but the selection should have a
755 // different start value.
756 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
757 CheckUsernameSelection(2, 5);
759 // Test that deleting does not trigger autocomplete.
760 SimulateKeyDownEvent(username_element_, ui::VKEY_BACK);
761 SimulateUsernameChange("alic", true);
762 CheckTextFieldsState("alic", false, std::string(), false);
763 CheckUsernameSelection(4, 4); // No selection.
764 // Reset the last pressed key to something other than backspace.
765 SimulateKeyDownEvent(username_element_, ui::VKEY_A);
767 // Now lets say the user goes astray from the stored username and types the
768 // letter 'f', spelling 'alf'. We don't know alf (that's just sad), so in
769 // practice the username should no longer be 'alice' and the selected range
770 // should be empty.
771 SimulateUsernameChange("alf", true);
772 CheckTextFieldsState("alf", false, std::string(), false);
773 CheckUsernameSelection(3, 3); // No selection.
775 // Ok, so now the user removes all the text and enters the letter 'b'.
776 SimulateUsernameChange("b", true);
777 // The username and password fields should match the 'bob' entry.
778 CheckTextFieldsState(kBobUsername, true, kBobPassword, true);
779 CheckUsernameSelection(1, 3);
781 // Then, the user again removes all the text and types an uppercase 'C'.
782 SimulateUsernameChange("C", true);
783 // The username and password fields should match the 'Carol' entry.
784 CheckTextFieldsState(kCarolUsername, true, kCarolPassword, true);
785 CheckUsernameSelection(1, 5);
786 // The user removes all the text and types a lowercase 'c'. We only
787 // want case-sensitive autocompletion, so the username and the selected range
788 // should be empty.
789 SimulateUsernameChange("c", true);
790 CheckTextFieldsState("c", false, std::string(), false);
791 CheckUsernameSelection(1, 1);
793 // Check that we complete other_possible_usernames as well.
794 SimulateUsernameChange("R", true);
795 CheckTextFieldsState(kCarolAlternateUsername, true, kCarolPassword, true);
796 CheckUsernameSelection(1, 17);
799 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
800 blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
801 blink::WebFrame* frame;
803 LoadHTML(kVisibleFormHTML);
804 frame = GetMainFrame();
805 frame->document().forms(forms1);
806 ASSERT_EQ(1u, forms1.size());
807 EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
809 LoadHTML(kEmptyFormHTML);
810 frame = GetMainFrame();
811 frame->document().forms(forms2);
812 ASSERT_EQ(1u, forms2.size());
813 EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
815 LoadHTML(kNonVisibleFormHTML);
816 frame = GetMainFrame();
817 frame->document().forms(forms3);
818 ASSERT_EQ(1u, forms3.size());
819 EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
822 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
823 render_thread_->sink().ClearMessages();
824 LoadHTML(kVisibleFormHTML);
825 const IPC::Message* message = render_thread_->sink()
826 .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
827 EXPECT_TRUE(message);
828 Tuple2<std::vector<autofill::PasswordForm>, bool > param;
829 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
830 EXPECT_TRUE(param.a.size());
832 render_thread_->sink().ClearMessages();
833 LoadHTML(kEmptyFormHTML);
834 message = render_thread_->sink().GetFirstMessageMatching(
835 AutofillHostMsg_PasswordFormsRendered::ID);
836 EXPECT_TRUE(message);
837 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
838 EXPECT_FALSE(param.a.size());
840 render_thread_->sink().ClearMessages();
841 LoadHTML(kNonVisibleFormHTML);
842 message = render_thread_->sink().GetFirstMessageMatching(
843 AutofillHostMsg_PasswordFormsRendered::ID);
844 EXPECT_TRUE(message);
845 AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
846 EXPECT_FALSE(param.a.size());
849 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
850 render_thread_->sink().ClearMessages();
851 LoadHTML(kEmptyWebpage);
852 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
853 AutofillHostMsg_PasswordFormsRendered::ID));
855 render_thread_->sink().ClearMessages();
856 LoadHTML(kRedirectionWebpage);
857 EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
858 AutofillHostMsg_PasswordFormsRendered::ID));
860 render_thread_->sink().ClearMessages();
861 LoadHTML(kSimpleWebpage);
862 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
863 AutofillHostMsg_PasswordFormsRendered::ID));
865 render_thread_->sink().ClearMessages();
866 LoadHTML(kWebpageWithDynamicContent);
867 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
868 AutofillHostMsg_PasswordFormsRendered::ID));
871 // Tests that a password form in an iframe will not be filled in until a user
872 // interaction with the form.
873 TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) {
874 const char kIframeName[] = "iframe";
875 const char kWebpageWithIframeStart[] =
876 "<html>"
877 " <head>"
878 " <meta charset='utf-8' />"
879 " <title>Title</title>"
880 " </head>"
881 " <body>"
882 " <iframe name='iframe' src=\"";
883 const char kWebpageWithIframeEnd[] =
884 "\"></iframe>"
885 " </body>"
886 "</html>";
888 std::string origin("data:text/html;charset=utf-8,");
889 origin += kSimpleWebpage;
891 std::string page_html(kWebpageWithIframeStart);
892 page_html += origin;
893 page_html += kWebpageWithIframeEnd;
895 LoadHTML(page_html.c_str());
897 // Set the expected form origin and action URLs.
898 fill_data_.basic_data.origin = GURL(origin);
899 fill_data_.basic_data.action = GURL(origin);
901 SimulateOnFillPasswordForm(fill_data_);
903 // Retrieve the input elements from the iframe since that is where we want to
904 // test the autofill.
905 WebFrame* iframe = GetMainFrame()->findChildByName(kIframeName);
906 ASSERT_TRUE(iframe);
907 WebDocument document = iframe->document();
909 WebElement username_element = document.getElementById(kUsernameName);
910 WebElement password_element = document.getElementById(kPasswordName);
911 ASSERT_FALSE(username_element.isNull());
912 ASSERT_FALSE(password_element.isNull());
914 WebInputElement username_input = username_element.to<WebInputElement>();
915 WebInputElement password_input = password_element.to<WebInputElement>();
916 ASSERT_FALSE(username_element.isNull());
918 CheckTextFieldsStateForElements(
919 username_input, "", false, password_input, "", false, false);
921 // Simulate the user typing in the username in the iframe which should cause
922 // an autofill.
923 SimulateUsernameChangeForElement(
924 kAliceUsername, true, iframe, username_input, true);
926 CheckTextFieldsStateForElements(username_input,
927 kAliceUsername,
928 true,
929 password_input,
930 kAlicePassword,
931 true,
932 false);
935 // Tests that a password will only be filled as a suggested and will not be
936 // accessible by the DOM until a user gesture has occurred.
937 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
938 // Trigger the initial autocomplete.
939 SimulateOnFillPasswordForm(fill_data_);
941 // The username and password should have been autocompleted.
942 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
944 // However, it should only have completed with the suggested value, as tested
945 // above, and it should not have completed into the DOM accessible value for
946 // the password field.
947 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
949 // Simulate a user click so that the password field's real value is filled.
950 SimulateElementClick(kUsernameName);
951 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
954 // Verfies that a DOM-activated UI event will not cause an autofill.
955 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
956 // Trigger the initial autocomplete.
957 SimulateOnFillPasswordForm(fill_data_);
959 ExecuteJavaScript(kJavaScriptClick);
960 CheckTextFieldsDOMState(kAliceUsername, true, "", true);
963 // Regression test for http://crbug.com/326679
964 TEST_F(PasswordAutofillAgentTest, SelectUsernameWithUsernameAutofillOff) {
965 // Simulate the browser sending back the login info.
966 SimulateOnFillPasswordForm(fill_data_);
968 // Set the username element to autocomplete='off'
969 username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
970 WebString::fromUTF8("off"));
972 // Simulate the user changing the username to some known username.
973 SimulateUsernameChange(kAliceUsername, true);
975 ExpectNoSuggestionsPopup();
978 // Regression test for http://crbug.com/326679
979 TEST_F(PasswordAutofillAgentTest,
980 SelectUnknownUsernameWithUsernameAutofillOff) {
981 // Simulate the browser sending back the login info.
982 SimulateOnFillPasswordForm(fill_data_);
984 // Set the username element to autocomplete='off'
985 username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
986 WebString::fromUTF8("off"));
988 // Simulate the user changing the username to some unknown username.
989 SimulateUsernameChange("foo", true);
991 ExpectNoSuggestionsPopup();
994 // Regression test for http://crbug.com/326679
995 TEST_F(PasswordAutofillAgentTest, SelectUsernameWithPasswordAutofillOff) {
996 // Simulate the browser sending back the login info.
997 SimulateOnFillPasswordForm(fill_data_);
999 // Set the main password element to autocomplete='off'
1000 password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
1001 WebString::fromUTF8("off"));
1003 // Simulate the user changing the username to some known username.
1004 SimulateUsernameChange(kAliceUsername, true);
1006 ExpectNoSuggestionsPopup();
1009 // Regression test for http://crbug.com/326679
1010 TEST_F(PasswordAutofillAgentTest,
1011 SelectUnknownUsernameWithPasswordAutofillOff) {
1012 // Simulate the browser sending back the login info.
1013 SimulateOnFillPasswordForm(fill_data_);
1015 // Set the main password element to autocomplete='off'
1016 password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
1017 WebString::fromUTF8("off"));
1019 // Simulate the user changing the username to some unknown username.
1020 SimulateUsernameChange("foo", true);
1022 ExpectNoSuggestionsPopup();
1025 // Verifies that password autofill triggers onChange events in JavaScript for
1026 // forms that are filled on page load.
1027 TEST_F(PasswordAutofillAgentTest,
1028 PasswordAutofillTriggersOnChangeEventsOnLoad) {
1029 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
1030 LoadHTML(html.c_str());
1031 UpdateOriginForHTML(html);
1032 UpdateUsernameAndPasswordElements();
1034 // Simulate the browser sending back the login info, it triggers the
1035 // autocomplete.
1036 SimulateOnFillPasswordForm(fill_data_);
1038 // The username and password should have been autocompleted...
1039 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
1040 // ... but since there hasn't been a user gesture yet, the autocompleted
1041 // password should only be visible to the user.
1042 CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
1044 // A JavaScript onChange event should have been triggered for the username,
1045 // but not yet for the password.
1046 int username_onchange_called = -1;
1047 int password_onchange_called = -1;
1048 ASSERT_TRUE(
1049 ExecuteJavaScriptAndReturnIntValue(
1050 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
1051 &username_onchange_called));
1052 EXPECT_EQ(1, username_onchange_called);
1053 ASSERT_TRUE(
1054 ExecuteJavaScriptAndReturnIntValue(
1055 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1056 &password_onchange_called));
1057 // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
1058 // EXPECT_EQ(0, password_onchange_called);
1060 // Simulate a user click so that the password field's real value is filled.
1061 SimulateElementClick(kUsernameName);
1062 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1064 // Now, a JavaScript onChange event should have been triggered for the
1065 // password as well.
1066 ASSERT_TRUE(
1067 ExecuteJavaScriptAndReturnIntValue(
1068 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1069 &password_onchange_called));
1070 EXPECT_EQ(1, password_onchange_called);
1073 // Verifies that password autofill triggers onChange events in JavaScript for
1074 // forms that are filled after page load.
1075 TEST_F(PasswordAutofillAgentTest,
1076 PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
1077 std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
1078 LoadHTML(html.c_str());
1079 UpdateOriginForHTML(html);
1080 UpdateUsernameAndPasswordElements();
1082 // Simulate the browser sending back the login info, it triggers the
1083 // autocomplete.
1084 fill_data_.wait_for_username = true;
1085 SimulateOnFillPasswordForm(fill_data_);
1087 // The username and password should not yet have been autocompleted.
1088 CheckTextFieldsState(std::string(), false, std::string(), false);
1090 // Simulate a click just to force a user gesture, since the username value is
1091 // set directly.
1092 SimulateElementClick(kUsernameName);
1094 // Simulate the user entering her username and selecting the matching autofill
1095 // from the dropdown.
1096 SimulateUsernameChange(kAliceUsername, true, true);
1097 SimulateSuggestionChoice(username_element_);
1099 // The username and password should now have been autocompleted.
1100 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1102 // JavaScript onChange events should have been triggered both for the username
1103 // and for the password.
1104 int username_onchange_called = -1;
1105 int password_onchange_called = -1;
1106 ASSERT_TRUE(
1107 ExecuteJavaScriptAndReturnIntValue(
1108 ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
1109 &username_onchange_called));
1110 EXPECT_EQ(1, username_onchange_called);
1111 ASSERT_TRUE(
1112 ExecuteJavaScriptAndReturnIntValue(
1113 ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1114 &password_onchange_called));
1115 EXPECT_EQ(1, password_onchange_called);
1118 // Tests that |FillSuggestion| properly fills the username and password.
1119 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
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 // Neither field should have been autocompleted.
1126 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1128 // If the password field is not autocompletable, it should not be affected.
1129 SetElementReadOnly(password_element_, true);
1130 EXPECT_FALSE(password_autofill_->FillSuggestion(
1131 username_element_, kAliceUsername, kAlicePassword));
1132 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1133 SetElementReadOnly(password_element_, false);
1135 // After filling with the suggestion, both fields should be autocompleted.
1136 EXPECT_TRUE(password_autofill_->FillSuggestion(
1137 username_element_, kAliceUsername, kAlicePassword));
1138 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1139 int username_length = strlen(kAliceUsername);
1140 CheckUsernameSelection(username_length, username_length);
1142 // Try Filling with a suggestion with password different from the one that was
1143 // initially sent to the renderer.
1144 EXPECT_TRUE(password_autofill_->FillSuggestion(
1145 username_element_, kBobUsername, kCarolPassword));
1146 CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
1147 username_length = strlen(kBobUsername);
1148 CheckUsernameSelection(username_length, username_length);
1151 // Tests that |PreviewSuggestion| properly previews the username and password.
1152 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
1153 // Simulate the browser sending the login info, but set |wait_for_username|
1154 // to prevent the form from being immediately filled.
1155 fill_data_.wait_for_username = true;
1156 SimulateOnFillPasswordForm(fill_data_);
1158 // Neither field should have been autocompleted.
1159 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1161 // If the password field is not autocompletable, it should not be affected.
1162 SetElementReadOnly(password_element_, true);
1163 EXPECT_FALSE(password_autofill_->PreviewSuggestion(
1164 username_element_, kAliceUsername, kAlicePassword));
1165 EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
1166 EXPECT_FALSE(username_element_.isAutofilled());
1167 EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
1168 EXPECT_FALSE(password_element_.isAutofilled());
1169 SetElementReadOnly(password_element_, false);
1171 // After selecting the suggestion, both fields should be previewed
1172 // with suggested values.
1173 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1174 username_element_, kAliceUsername, kAlicePassword));
1175 EXPECT_EQ(
1176 kAliceUsername,
1177 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1178 EXPECT_TRUE(username_element_.isAutofilled());
1179 EXPECT_EQ(
1180 kAlicePassword,
1181 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1182 EXPECT_TRUE(password_element_.isAutofilled());
1183 int username_length = strlen(kAliceUsername);
1184 CheckUsernameSelection(0, username_length);
1186 // Try previewing with a password different from the one that was initially
1187 // sent to the renderer.
1188 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1189 username_element_, kBobUsername, kCarolPassword));
1190 EXPECT_EQ(
1191 kBobUsername,
1192 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1193 EXPECT_TRUE(username_element_.isAutofilled());
1194 EXPECT_EQ(
1195 kCarolPassword,
1196 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1197 EXPECT_TRUE(password_element_.isAutofilled());
1198 username_length = strlen(kBobUsername);
1199 CheckUsernameSelection(0, username_length);
1202 // Tests that |PreviewSuggestion| properly sets the username selection range.
1203 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
1204 username_element_.setValue(WebString::fromUTF8("ali"));
1205 username_element_.setSelectionRange(3, 3);
1206 username_element_.setAutofilled(true);
1208 CheckTextFieldsDOMState("ali", true, std::string(), false);
1210 // Simulate the browser sending the login info, but set |wait_for_username|
1211 // to prevent the form from being immediately filled.
1212 fill_data_.wait_for_username = true;
1213 SimulateOnFillPasswordForm(fill_data_);
1215 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1216 username_element_, kAliceUsername, kAlicePassword));
1217 EXPECT_EQ(
1218 kAliceUsername,
1219 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1220 EXPECT_TRUE(username_element_.isAutofilled());
1221 EXPECT_EQ(
1222 kAlicePassword,
1223 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1224 EXPECT_TRUE(password_element_.isAutofilled());
1225 int username_length = strlen(kAliceUsername);
1226 CheckUsernameSelection(3, username_length);
1229 // Tests that |ClearPreview| properly clears previewed username and password
1230 // with password being previously autofilled.
1231 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
1232 password_element_.setValue(WebString::fromUTF8("sec"));
1233 password_element_.setAutofilled(true);
1235 // Simulate the browser sending the login info, but set |wait_for_username|
1236 // to prevent the form from being immediately filled.
1237 fill_data_.wait_for_username = true;
1238 SimulateOnFillPasswordForm(fill_data_);
1240 CheckTextFieldsDOMState(std::string(), false, "sec", true);
1242 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1243 username_element_, kAliceUsername, kAlicePassword));
1245 EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
1246 username_element_));
1248 EXPECT_TRUE(username_element_.value().isEmpty());
1249 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1250 EXPECT_FALSE(username_element_.isAutofilled());
1251 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1252 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1253 EXPECT_TRUE(password_element_.isAutofilled());
1254 CheckUsernameSelection(0, 0);
1257 // Tests that |ClearPreview| properly clears previewed username and password
1258 // with username being previously autofilled.
1259 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
1260 username_element_.setValue(WebString::fromUTF8("ali"));
1261 username_element_.setSelectionRange(3, 3);
1262 username_element_.setAutofilled(true);
1264 // Simulate the browser sending the login info, but set |wait_for_username|
1265 // to prevent the form from being immediately filled.
1266 fill_data_.wait_for_username = true;
1267 SimulateOnFillPasswordForm(fill_data_);
1269 CheckTextFieldsDOMState("ali", true, std::string(), false);
1271 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1272 username_element_, kAliceUsername, kAlicePassword));
1274 EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
1275 username_element_));
1277 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1278 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1279 EXPECT_TRUE(username_element_.isAutofilled());
1280 EXPECT_TRUE(password_element_.value().isEmpty());
1281 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1282 EXPECT_FALSE(password_element_.isAutofilled());
1283 CheckUsernameSelection(3, 3);
1286 // Tests that |ClearPreview| properly clears previewed username and password
1287 // with username and password being previously autofilled.
1288 TEST_F(PasswordAutofillAgentTest,
1289 ClearPreviewWithAutofilledUsernameAndPassword) {
1290 username_element_.setValue(WebString::fromUTF8("ali"));
1291 username_element_.setSelectionRange(3, 3);
1292 username_element_.setAutofilled(true);
1293 password_element_.setValue(WebString::fromUTF8("sec"));
1294 password_element_.setAutofilled(true);
1296 // Simulate the browser sending the login info, but set |wait_for_username|
1297 // to prevent the form from being immediately filled.
1298 fill_data_.wait_for_username = true;
1299 SimulateOnFillPasswordForm(fill_data_);
1301 CheckTextFieldsDOMState("ali", true, "sec", true);
1303 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1304 username_element_, kAliceUsername, kAlicePassword));
1306 EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
1307 username_element_));
1309 EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1310 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1311 EXPECT_TRUE(username_element_.isAutofilled());
1312 EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1313 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1314 EXPECT_TRUE(password_element_.isAutofilled());
1315 CheckUsernameSelection(3, 3);
1318 // Tests that |ClearPreview| properly clears previewed username and password
1319 // with neither username nor password being previously autofilled.
1320 TEST_F(PasswordAutofillAgentTest,
1321 ClearPreviewWithNotAutofilledUsernameAndPassword) {
1322 // Simulate the browser sending the login info, but set |wait_for_username|
1323 // to prevent the form from being immediately filled.
1324 fill_data_.wait_for_username = true;
1325 SimulateOnFillPasswordForm(fill_data_);
1327 CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1329 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1330 username_element_, kAliceUsername, kAlicePassword));
1332 EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
1333 username_element_));
1335 EXPECT_TRUE(username_element_.value().isEmpty());
1336 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1337 EXPECT_FALSE(username_element_.isAutofilled());
1338 EXPECT_TRUE(password_element_.value().isEmpty());
1339 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1340 EXPECT_FALSE(password_element_.isAutofilled());
1341 CheckUsernameSelection(0, 0);
1344 // Tests that |ClearPreview| properly restores the original selection range of
1345 // username field that has initially been filled by inline autocomplete.
1346 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) {
1347 // Simulate the browser sending back the login info.
1348 SimulateOnFillPasswordForm(fill_data_);
1350 // Clear the text fields to start fresh.
1351 ClearUsernameAndPasswordFields();
1353 // Simulate the user typing in the first letter of 'alice', a stored username.
1354 SimulateUsernameChange("a", true);
1355 // Both the username and password text fields should reflect selection of the
1356 // stored login.
1357 CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
1358 // The selection should have been set to 'lice', the last 4 letters.
1359 CheckUsernameSelection(1, 5);
1361 EXPECT_TRUE(password_autofill_->PreviewSuggestion(
1362 username_element_, "alicia", "secret"));
1363 EXPECT_EQ(
1364 "alicia",
1365 static_cast<std::string>(username_element_.suggestedValue().utf8()));
1366 EXPECT_TRUE(username_element_.isAutofilled());
1367 EXPECT_EQ(
1368 "secret",
1369 static_cast<std::string>(password_element_.suggestedValue().utf8()));
1370 EXPECT_TRUE(password_element_.isAutofilled());
1371 CheckUsernameSelection(1, 6);
1373 EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
1374 username_element_));
1376 EXPECT_EQ(kAliceUsername, username_element_.value().utf8());
1377 EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1378 EXPECT_TRUE(username_element_.isAutofilled());
1379 EXPECT_TRUE(password_element_.value().isEmpty());
1380 EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1381 EXPECT_TRUE(password_element_.isAutofilled());
1382 CheckUsernameSelection(1, 5);
1385 // Tests that logging is off by default.
1386 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1387 render_thread_->sink().ClearMessages();
1388 SendVisiblePasswordForms();
1389 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1390 AutofillHostMsg_RecordSavePasswordProgress::ID);
1391 EXPECT_FALSE(message);
1394 // Test that logging can be turned on by a message.
1395 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1396 // Turn the logging on.
1397 AutofillMsg_SetLoggingState msg_activate(0, true);
1398 // Up-cast to access OnMessageReceived, which is private in the agent.
1399 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
1400 ->OnMessageReceived(msg_activate));
1402 render_thread_->sink().ClearMessages();
1403 SendVisiblePasswordForms();
1404 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1405 AutofillHostMsg_RecordSavePasswordProgress::ID);
1406 EXPECT_TRUE(message);
1409 // Test that logging can be turned off by a message.
1410 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1411 // Turn the logging on and then off.
1412 AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
1413 // Up-cast to access OnMessageReceived, which is private in the agent.
1414 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
1415 ->OnMessageReceived(msg_activate));
1416 AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
1417 EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
1418 ->OnMessageReceived(msg_deactivate));
1420 render_thread_->sink().ClearMessages();
1421 SendVisiblePasswordForms();
1422 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1423 AutofillHostMsg_RecordSavePasswordProgress::ID);
1424 EXPECT_FALSE(message);
1427 // Test that the agent sends an IPC call to get the current activity state of
1428 // password saving logging soon after construction.
1429 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1430 const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1431 AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1432 EXPECT_TRUE(message);
1435 // Tests that one user click on a username field is sufficient to bring up a
1436 // credential suggestion popup, and the user can autocomplete the password by
1437 // selecting the credential from the popup.
1438 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1439 // SimulateElementClick() is called so that a user gesture is actually made
1440 // and the password can be filled. However, SimulateElementClick() does not
1441 // actually lead to the AutofillAgent's InputElementClicked() method being
1442 // called, so SimulateSuggestionChoice has to manually call
1443 // InputElementClicked().
1444 ClearUsernameAndPasswordFields();
1445 SimulateOnFillPasswordForm(fill_data_);
1446 SimulateElementClick(kUsernameName);
1447 SimulateSuggestionChoice(username_element_);
1448 ExpectAllCredentials();
1450 CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1453 // Tests the autosuggestions that are given when the element is clicked.
1454 // Specifically, tests when the user clicks on the username element after page
1455 // load and the element is autofilled, when the user clicks on an element that
1456 // has a non-matching username, and when the user clicks on an element that's
1457 // already been autofilled and they've already modified.
1458 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1459 // Simulate the browser sending back the login info.
1460 SimulateOnFillPasswordForm(fill_data_);
1462 // Clear the text fields to start fresh.
1463 ClearUsernameAndPasswordFields();
1465 // Call SimulateElementClick() to produce a user gesture on the page so
1466 // autofill will actually fill.
1467 SimulateElementClick(kUsernameName);
1469 // Simulate a user clicking on the username element. This should produce a
1470 // message with all the usernames.
1471 render_thread_->sink().ClearMessages();
1472 autofill_agent_->FormControlElementClicked(username_element_, false);
1473 ExpectAllCredentials();
1475 // Now simulate a user typing in an unrecognized username and then
1476 // clicking on the username element. This should also produce a message with
1477 // all the usernames.
1478 SimulateUsernameChange("baz", true);
1479 render_thread_->sink().ClearMessages();
1480 autofill_agent_->FormControlElementClicked(username_element_, true);
1481 ExpectAllCredentials();
1483 // Now simulate a user typing in the first letter of the username and then
1484 // clicking on the username element. While the typing of the first letter will
1485 // inline autocomplete, clicking on the element should still produce a full
1486 // suggestion list.
1487 SimulateUsernameChange("a", true);
1488 render_thread_->sink().ClearMessages();
1489 autofill_agent_->FormControlElementClicked(username_element_, true);
1490 ExpectAllCredentials();
1493 // The user types in a password, but then just before sending the form off, a
1494 // script clears that password. This test checks that PasswordAutofillAgent can
1495 // still remember the password typed by the user.
1496 TEST_F(PasswordAutofillAgentTest,
1497 RememberLastNonEmptyPasswordOnSubmit_ScriptCleared) {
1498 SimulateUsernameChangeForElement(
1499 "temp", true, GetMainFrame(), username_element_, true);
1500 SimulateUsernameChangeForElement(
1501 "random", true, GetMainFrame(), password_element_, true);
1503 // Simulate that the password value was cleared by the site's JavaScript
1504 // before submit.
1505 password_element_.setValue(WebString());
1506 static_cast<content::RenderViewObserver*>(password_autofill_agent())
1507 ->WillSubmitForm(GetMainFrame(), username_element_.form());
1509 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1510 // password and sent that to the browser.
1511 ExpectFormSubmittedWithPasswords("random", "");
1514 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time
1515 // it's the user who clears the password. This test checks that in that case,
1516 // the last non-empty password is not remembered.
1517 TEST_F(PasswordAutofillAgentTest,
1518 RememberLastNonEmptyPasswordOnSubmit_UserCleared) {
1519 SimulateUsernameChangeForElement(
1520 "temp", true, GetMainFrame(), username_element_, true);
1521 SimulateUsernameChangeForElement(
1522 "random", true, GetMainFrame(), password_element_, true);
1524 // Simulate that the user actually cleared the password again.
1525 SimulateUsernameChangeForElement(
1526 "", true, GetMainFrame(), password_element_, true);
1527 static_cast<content::RenderViewObserver*>(password_autofill_agent())
1528 ->WillSubmitForm(GetMainFrame(), username_element_.form());
1530 // Observe that the PasswordAutofillAgent respects the user having cleared the
1531 // password.
1532 ExpectFormSubmittedWithPasswords("", "");
1535 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the
1536 // new password instead of the current password.
1537 TEST_F(PasswordAutofillAgentTest,
1538 RememberLastNonEmptyPasswordOnSubmit_NewPassword) {
1539 const char kNewPasswordFormHTML[] =
1540 "<FORM name='LoginTestForm'>"
1541 " <INPUT type='text' id='username' autocomplete='username'/>"
1542 " <INPUT type='password' id='password' autocomplete='new-password'/>"
1543 " <INPUT type='submit' value='Login'/>"
1544 "</FORM>";
1545 LoadHTML(kNewPasswordFormHTML);
1546 UpdateUsernameAndPasswordElements();
1548 SimulateUsernameChangeForElement(
1549 "temp", true, GetMainFrame(), username_element_, true);
1550 SimulateUsernameChangeForElement(
1551 "random", true, GetMainFrame(), password_element_, true);
1553 // Simulate that the password value was cleared by the site's JavaScript
1554 // before submit.
1555 password_element_.setValue(WebString());
1556 static_cast<content::RenderViewObserver*>(password_autofill_agent())
1557 ->WillSubmitForm(GetMainFrame(), username_element_.form());
1559 // Observe that the PasswordAutofillAgent still remembered the last non-empty
1560 // password and sent that to the browser.
1561 ExpectFormSubmittedWithPasswords("", "random");
1564 } // namespace autofill