Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / autofill / password_autofill_agent_browsertest.cc
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.
4
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"
27
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;
37
38 namespace {
39
40 // The name of the username/password element in the form.
41 const char kUsernameName[] = "username";
42 const char kPasswordName[] = "password";
43
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";
51
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>";
58
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>";
68
69 const char kEmptyFormHTML[] =
70     "<head> <style> form {display: inline;} </style> </head>"
71     "<body> <form> </form> </body>";
72
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>";
82
83 const char kEmptyWebpage[] =
84     "<html>"
85     "   <head>"
86     "   </head>"
87     "   <body>"
88     "   </body>"
89     "</html>";
90
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>";
104
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>";
119
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>";
136
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!');";
146
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>";
158
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());
163 }
164
165 }  // namespace
166
167 namespace autofill {
168
169 class PasswordAutofillAgentTest : public ChromeRenderViewTest {
170  public:
171   PasswordAutofillAgentTest() {
172   }
173
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     static_cast<content::RenderViewObserver*>(password_autofill_agent_)
181         ->OnMessageReceived(msg);
182   }
183
184   void SendVisiblePasswordForms() {
185     static_cast<content::RenderViewObserver*>(password_autofill_agent_)
186         ->DidFinishLoad(GetMainFrame());
187   }
188
189   virtual void SetUp() {
190     ChromeRenderViewTest::SetUp();
191
192     // Add a preferred login and an additional login to the FillData.
193     username1_ = ASCIIToUTF16(kAliceUsername);
194     password1_ = ASCIIToUTF16(kAlicePassword);
195     username2_ = ASCIIToUTF16(kBobUsername);
196     password2_ = ASCIIToUTF16(kBobPassword);
197     username3_ = ASCIIToUTF16(kCarolUsername);
198     password3_ = ASCIIToUTF16(kCarolPassword);
199     alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
200
201     FormFieldData username_field;
202     username_field.name = ASCIIToUTF16(kUsernameName);
203     username_field.value = username1_;
204     fill_data_.basic_data.fields.push_back(username_field);
205
206     FormFieldData password_field;
207     password_field.name = ASCIIToUTF16(kPasswordName);
208     password_field.value = password1_;
209     password_field.form_control_type = "password";
210     fill_data_.basic_data.fields.push_back(password_field);
211
212     PasswordAndRealm password2;
213     password2.password = password2_;
214     fill_data_.additional_logins[username2_] = password2;
215     PasswordAndRealm password3;
216     password3.password = password3_;
217     fill_data_.additional_logins[username3_] = password3;
218
219     UsernamesCollectionKey key;
220     key.username = username3_;
221     key.password = password3_;
222     key.realm = "google.com";
223     fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
224
225     // We need to set the origin so it matches the frame URL and the action so
226     // it matches the form action, otherwise we won't autocomplete.
227     UpdateOriginForHTML(kFormHTML);
228     fill_data_.basic_data.action = GURL("http://www.bidule.com");
229
230     LoadHTML(kFormHTML);
231
232     // Now retrieve the input elements so the test can access them.
233     UpdateUsernameAndPasswordElements();
234   }
235
236   virtual void TearDown() {
237     username_element_.reset();
238     password_element_.reset();
239     ChromeRenderViewTest::TearDown();
240   }
241
242   void UpdateOriginForHTML(const std::string& html) {
243     std::string origin = "data:text/html;charset=utf-8," + html;
244     fill_data_.basic_data.origin = GURL(origin);
245   }
246
247   void UpdateUsernameAndPasswordElements() {
248     WebDocument document = GetMainFrame()->document();
249     WebElement element =
250         document.getElementById(WebString::fromUTF8(kUsernameName));
251     ASSERT_FALSE(element.isNull());
252     username_element_ = element.to<blink::WebInputElement>();
253     element = document.getElementById(WebString::fromUTF8(kPasswordName));
254     ASSERT_FALSE(element.isNull());
255     password_element_ = element.to<blink::WebInputElement>();
256   }
257
258   void ClearUsernameAndPasswordFields() {
259     username_element_.setValue("");
260     username_element_.setAutofilled(false);
261     password_element_.setValue("");
262     password_element_.setAutofilled(false);
263   }
264
265   void SimulateDidEndEditing(WebFrame* input_frame, WebInputElement& input) {
266     static_cast<blink::WebAutofillClient*>(autofill_agent_)
267         ->textFieldDidEndEditing(input);
268   }
269
270   void SimulateInputChangeForElement(const std::string& new_value,
271                                      bool move_caret_to_end,
272                                      WebFrame* input_frame,
273                                      WebInputElement& input,
274                                      bool is_user_input) {
275     input.setValue(WebString::fromUTF8(new_value), is_user_input);
276     // The field must have focus or AutofillAgent will think the
277     // change should be ignored.
278     while (!input.focused())
279       input_frame->document().frame()->view()->advanceFocus(false);
280     if (move_caret_to_end)
281       input.setSelectionRange(new_value.length(), new_value.length());
282     if (is_user_input)
283       password_autofill_agent_->FirstUserGestureObserved();
284     static_cast<blink::WebAutofillClient*>(autofill_agent_)
285         ->textFieldDidChange(input);
286     // Processing is delayed because of a Blink bug:
287     // https://bugs.webkit.org/show_bug.cgi?id=16976
288     // See PasswordAutofillAgent::TextDidChangeInTextField() for details.
289
290     // Autocomplete will trigger a style recalculation when we put up the next
291     // frame, but we don't want to wait that long. Instead, trigger a style
292     // recalcuation manually after TextFieldDidChangeImpl runs.
293     base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
294         &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this)));
295
296     base::MessageLoop::current()->RunUntilIdle();
297   }
298
299   void SimulateSuggestionChoice(WebInputElement& username_input) {
300     base::string16 username(base::ASCIIToUTF16(kAliceUsername));
301     base::string16 password(base::ASCIIToUTF16(kAlicePassword));
302
303     // This call is necessary to setup the autofill agent appropriate for the
304     // user selection; simulates the menu actually popping up.
305     render_thread_->sink().ClearMessages();
306     static_cast<autofill::PageClickListener*>(autofill_agent_)
307         ->FormControlElementClicked(username_input, false);
308
309     AutofillMsg_FillPasswordSuggestion msg(0, username, password);
310     static_cast<content::RenderViewObserver*>(autofill_agent_)
311         ->OnMessageReceived(msg);
312   }
313
314   void LayoutMainFrame() {
315     GetMainFrame()->view()->layout();
316   }
317
318   void SimulateUsernameChange(const std::string& username,
319                               bool move_caret_to_end,
320                               bool is_user_input = false) {
321     SimulateInputChangeForElement(username,
322                                   move_caret_to_end,
323                                   GetMainFrame(),
324                                   username_element_,
325                                   is_user_input);
326   }
327
328   // Tests that no suggestion popup is generated when the username_element_ is
329   // edited.
330   void ExpectNoSuggestionsPopup() {
331     // The first test below ensures that the suggestions have been handled by
332     // the password_autofill_agent, even though autocomplete='off' is set. The
333     // second check ensures that, although handled, no "show suggestions" IPC to
334     // the browser was generated.
335     //
336     // This is interesting in the specific case of an autocomplete='off' form
337     // that also has a remembered username and password
338     // (http://crbug.com/326679). To fix the DCHECK that this case used to hit,
339     // |true| is returned from ShowSuggestions for all forms with valid
340     // usersnames that are autocomplete='off', prentending that a selection box
341     // has been shown to the user. Of course, it hasn't, so a message is never
342     // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing
343     // is filled).
344     //
345     // These tests only make sense in the context of not ignoring
346     // autocomplete='off', so only test them if the disable autocomplete='off'
347     // flag is not enabled.
348     // TODO(jww): Remove this function and callers once autocomplete='off' is
349     // permanently ignored.
350     if (!ShouldIgnoreAutocompleteOffForPasswordFields()) {
351       EXPECT_TRUE(
352           password_autofill_agent_->ShowSuggestions(username_element_, false));
353
354       EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
355           AutofillHostMsg_ShowPasswordSuggestions::ID));
356     }
357   }
358
359   void SimulateKeyDownEvent(const WebInputElement& element,
360                             ui::KeyboardCode key_code) {
361     blink::WebKeyboardEvent key_event;
362     key_event.windowsKeyCode = key_code;
363     static_cast<blink::WebAutofillClient*>(autofill_agent_)
364         ->textFieldDidReceiveKeyDown(element, key_event);
365   }
366
367   void CheckTextFieldsStateForElements(const WebInputElement& username_element,
368                                        const std::string& username,
369                                        bool username_autofilled,
370                                        const WebInputElement& password_element,
371                                        const std::string& password,
372                                        bool password_autofilled,
373                                        bool checkSuggestedValue) {
374     EXPECT_EQ(username,
375               static_cast<std::string>(username_element.value().utf8()));
376     EXPECT_EQ(username_autofilled, username_element.isAutofilled());
377     EXPECT_EQ(password,
378               static_cast<std::string>(
379                   checkSuggestedValue ? password_element.suggestedValue().utf8()
380                                       : password_element.value().utf8()))
381         << "checkSuggestedValue == " << checkSuggestedValue;
382     EXPECT_EQ(password_autofilled, password_element.isAutofilled());
383   }
384
385   // Checks the DOM-accessible value of the username element and the
386   // *suggested* value of the password element.
387   void CheckTextFieldsState(const std::string& username,
388                             bool username_autofilled,
389                             const std::string& password,
390                             bool password_autofilled) {
391     CheckTextFieldsStateForElements(username_element_,
392                                     username,
393                                     username_autofilled,
394                                     password_element_,
395                                     password,
396                                     password_autofilled,
397                                     true);
398   }
399
400   // Checks the DOM-accessible value of the username element and the
401   // DOM-accessible value of the password element.
402   void CheckTextFieldsDOMState(const std::string& username,
403                                bool username_autofilled,
404                                const std::string& password,
405                                bool password_autofilled) {
406     CheckTextFieldsStateForElements(username_element_,
407                                     username,
408                                     username_autofilled,
409                                     password_element_,
410                                     password,
411                                     password_autofilled,
412                                     false);
413   }
414
415   void CheckUsernameSelection(int start, int end) {
416     EXPECT_EQ(start, username_element_.selectionStart());
417     EXPECT_EQ(end, username_element_.selectionEnd());
418   }
419
420   void ExpectOneCredential(const base::string16& username) {
421     const IPC::Message* message =
422         render_thread_->sink().GetFirstMessageMatching(
423             AutofillHostMsg_ShowPasswordSuggestions::ID);
424     ASSERT_TRUE(message);
425     Tuple4<autofill::FormFieldData,
426            gfx::RectF,
427            std::vector<base::string16>,
428            std::vector<base::string16> > args;
429     AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
430     ASSERT_EQ(1u, args.c.size());
431     EXPECT_TRUE(args.c[0] == username);
432   }
433
434   void ExpectAllCredentials() {
435     std::set<base::string16> usernames;
436     usernames.insert(username1_);
437     usernames.insert(username2_);
438     usernames.insert(username3_);
439     usernames.insert(alternate_username3_);
440
441     const IPC::Message* message =
442         render_thread_->sink().GetFirstMessageMatching(
443             AutofillHostMsg_ShowPasswordSuggestions::ID);
444     ASSERT_TRUE(message);
445     Tuple4<autofill::FormFieldData,
446            gfx::RectF,
447            std::vector<base::string16>,
448            std::vector<base::string16> > args;
449     AutofillHostMsg_ShowPasswordSuggestions::Read(message, &args);
450     ASSERT_EQ(4u, args.c.size());
451     std::set<base::string16>::iterator it;
452
453     for (int i = 0; i < 4; i++) {
454       it = usernames.find(args.c[i]);
455       EXPECT_TRUE(it != usernames.end());
456       if (it != usernames.end())
457         usernames.erase(it);
458     }
459
460     EXPECT_TRUE(usernames.empty());
461
462     render_thread_->sink().ClearMessages();
463   }
464
465   void ExpectFormSubmittedWithPasswords(const std::string& password_value,
466                                         const std::string& new_password_value) {
467     const IPC::Message* message =
468         render_thread_->sink().GetFirstMessageMatching(
469             AutofillHostMsg_PasswordFormSubmitted::ID);
470     ASSERT_TRUE(message);
471     Tuple1<autofill::PasswordForm> args;
472     AutofillHostMsg_PasswordFormSubmitted::Read(message, &args);
473     EXPECT_EQ(ASCIIToUTF16(password_value), args.a.password_value);
474     EXPECT_EQ(ASCIIToUTF16(new_password_value), args.a.new_password_value);
475   }
476
477   base::string16 username1_;
478   base::string16 username2_;
479   base::string16 username3_;
480   base::string16 password1_;
481   base::string16 password2_;
482   base::string16 password3_;
483   base::string16 alternate_username3_;
484   PasswordFormFillData fill_data_;
485
486   WebInputElement username_element_;
487   WebInputElement password_element_;
488
489  private:
490   DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
491 };
492
493 // Tests that the password login is autocompleted as expected when the browser
494 // sends back the password info.
495 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
496   /*
497    * Right now we are not sending the message to the browser because we are
498    * loading a data URL and the security origin canAccessPasswordManager()
499    * returns false.  May be we should mock URL loading to cirmcuvent this?
500    TODO(jcivelli): find a way to make the security origin not deny access to the
501                    password manager and then reenable this code.
502
503   // The form has been loaded, we should have sent the browser a message about
504   // the form.
505   const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
506       AutofillHostMsg_PasswordFormsParsed::ID);
507   ASSERT_TRUE(msg != NULL);
508
509   Tuple1<std::vector<PasswordForm> > forms;
510   AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
511   ASSERT_EQ(1U, forms.a.size());
512   PasswordForm password_form = forms.a[0];
513   EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
514   EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
515   EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
516   */
517
518   // Simulate the browser sending back the login info, it triggers the
519   // autocomplete.
520   SimulateOnFillPasswordForm(fill_data_);
521
522   // The username and password should have been autocompleted.
523   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
524 }
525
526 // Tests that we correctly fill forms having an empty 'action' attribute.
527 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
528   const char kEmptyActionFormHTML[] =
529       "<FORM name='LoginTestForm'>"
530       "  <INPUT type='text' id='username'/>"
531       "  <INPUT type='password' id='password'/>"
532       "  <INPUT type='submit' value='Login'/>"
533       "</FORM>";
534   LoadHTML(kEmptyActionFormHTML);
535
536   // Retrieve the input elements so the test can access them.
537   WebDocument document = GetMainFrame()->document();
538   WebElement element =
539       document.getElementById(WebString::fromUTF8(kUsernameName));
540   ASSERT_FALSE(element.isNull());
541   username_element_ = element.to<blink::WebInputElement>();
542   element = document.getElementById(WebString::fromUTF8(kPasswordName));
543   ASSERT_FALSE(element.isNull());
544   password_element_ = element.to<blink::WebInputElement>();
545
546   // Set the expected form origin and action URLs.
547   UpdateOriginForHTML(kEmptyActionFormHTML);
548   fill_data_.basic_data.action = fill_data_.basic_data.origin;
549
550   // Simulate the browser sending back the login info, it triggers the
551   // autocomplete.
552   SimulateOnFillPasswordForm(fill_data_);
553
554   // The username and password should have been autocompleted.
555   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
556 }
557
558 // Tests that if a password is marked as readonly, neither field is autofilled
559 // on page load.
560 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
561   SetElementReadOnly(password_element_, true);
562
563   // Simulate the browser sending back the login info, it triggers the
564   // autocomplete.
565   SimulateOnFillPasswordForm(fill_data_);
566
567   CheckTextFieldsState(std::string(), false, std::string(), false);
568 }
569
570 // Can still fill a password field if the username is set to a value that
571 // matches.
572 TEST_F(PasswordAutofillAgentTest,
573        AutocompletePasswordForReadonlyUsernameMatched) {
574   username_element_.setValue(username3_);
575   SetElementReadOnly(username_element_, true);
576
577   // Filled even though username is not the preferred match.
578   SimulateOnFillPasswordForm(fill_data_);
579   CheckTextFieldsState(UTF16ToUTF8(username3_), false,
580                        UTF16ToUTF8(password3_), true);
581 }
582
583 // If a username field is empty and readonly, don't autofill.
584 TEST_F(PasswordAutofillAgentTest,
585        NoAutocompletePasswordForReadonlyUsernameUnmatched) {
586   username_element_.setValue(WebString::fromUTF8(""));
587   SetElementReadOnly(username_element_, true);
588
589   SimulateOnFillPasswordForm(fill_data_);
590   CheckTextFieldsState(std::string(), false, std::string(), false);
591 }
592
593 // Tests that having a non-matching username precludes the autocomplete.
594 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
595   username_element_.setValue(WebString::fromUTF8("bogus"));
596
597   // Simulate the browser sending back the login info, it triggers the
598   // autocomplete.
599   SimulateOnFillPasswordForm(fill_data_);
600
601   // Neither field should be autocompleted.
602   CheckTextFieldsState("bogus", false, std::string(), false);
603 }
604
605 // Don't try to complete a prefilled value even if it's a partial match
606 // to a username.
607 TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
608   username_element_.setValue(WebString::fromUTF8("ali"));
609
610   SimulateOnFillPasswordForm(fill_data_);
611
612   CheckTextFieldsState("ali", false, std::string(), false);
613 }
614
615 TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
616   const char kNoFormInputs[] =
617       "<input type='text' id='username'/>"
618       "<input type='password' id='password'/>";
619   LoadHTML(kNoFormInputs);
620
621   SimulateOnFillPasswordForm(fill_data_);
622
623   // Input elements that aren't in a <form> won't autofill.
624   CheckTextFieldsState(std::string(), false, std::string(), false);
625 }
626
627 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
628   const char kTextFieldPasswordFormHTML[] =
629       "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
630       "  <INPUT type='text' id='username'/>"
631       "  <INPUT type='text' id='password'/>"
632       "  <INPUT type='submit' value='Login'/>"
633       "</FORM>";
634   LoadHTML(kTextFieldPasswordFormHTML);
635
636   // Retrieve the input elements so the test can access them.
637   WebDocument document = GetMainFrame()->document();
638   WebElement element =
639       document.getElementById(WebString::fromUTF8(kUsernameName));
640   ASSERT_FALSE(element.isNull());
641   username_element_ = element.to<blink::WebInputElement>();
642   element = document.getElementById(WebString::fromUTF8(kPasswordName));
643   ASSERT_FALSE(element.isNull());
644   password_element_ = element.to<blink::WebInputElement>();
645
646   // Set the expected form origin URL.
647   UpdateOriginForHTML(kTextFieldPasswordFormHTML);
648
649   SimulateOnFillPasswordForm(fill_data_);
650
651   // Fields should still be empty.
652   CheckTextFieldsState(std::string(), false, std::string(), false);
653 }
654
655 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
656   const char kPasswordFieldUsernameFormHTML[] =
657       "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
658       "  <INPUT type='password' id='username'/>"
659       "  <INPUT type='password' id='password'/>"
660       "  <INPUT type='submit' value='Login'/>"
661       "</FORM>";
662   LoadHTML(kPasswordFieldUsernameFormHTML);
663
664   // Retrieve the input elements so the test can access them.
665   WebDocument document = GetMainFrame()->document();
666   WebElement element =
667       document.getElementById(WebString::fromUTF8(kUsernameName));
668   ASSERT_FALSE(element.isNull());
669   username_element_ = element.to<blink::WebInputElement>();
670   element = document.getElementById(WebString::fromUTF8(kPasswordName));
671   ASSERT_FALSE(element.isNull());
672   password_element_ = element.to<blink::WebInputElement>();
673
674   // Set the expected form origin URL.
675   UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
676
677   SimulateOnFillPasswordForm(fill_data_);
678
679   // Fields should still be empty.
680   CheckTextFieldsState(std::string(), false, std::string(), false);
681 }
682
683 // Tests that having a matching username does not preclude the autocomplete.
684 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
685   username_element_.setValue(WebString::fromUTF8(kAliceUsername));
686
687   // Simulate the browser sending back the login info, it triggers the
688   // autocomplete.
689   SimulateOnFillPasswordForm(fill_data_);
690
691   // The username and password should have been autocompleted.
692   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
693 }
694
695 // Tests that editing the password clears the autocompleted password field.
696 TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
697   // Simulate the browser sending back the login info, it triggers the
698   // autocomplete.
699   SimulateOnFillPasswordForm(fill_data_);
700
701   // Simulate the user changing the username to some unknown username.
702   SimulateUsernameChange("alicia", true);
703
704   // The password should have been cleared.
705   CheckTextFieldsState("alicia", false, std::string(), false);
706 }
707
708 // Tests that we only autocomplete on focus lost and with a full username match
709 // when |wait_for_username| is true.
710 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
711   // Simulate the browser sending back the login info.
712   fill_data_.wait_for_username = true;
713   SimulateOnFillPasswordForm(fill_data_);
714
715   // No auto-fill should have taken place.
716   CheckTextFieldsState(std::string(), false, std::string(), false);
717
718   // No autocomplete should happen when text is entered in the username.
719   SimulateUsernameChange("a", true);
720   CheckTextFieldsState("a", false, std::string(), false);
721   SimulateUsernameChange("al", true);
722   CheckTextFieldsState("al", false, std::string(), false);
723   SimulateUsernameChange(kAliceUsername, true);
724   CheckTextFieldsState(kAliceUsername, false, std::string(), false);
725
726   // Autocomplete should happen only when the username textfield is blurred with
727   // a full match.
728   username_element_.setValue("a");
729   static_cast<blink::WebAutofillClient*>(autofill_agent_)
730       ->textFieldDidEndEditing(username_element_);
731   CheckTextFieldsState("a", false, std::string(), false);
732   username_element_.setValue("al");
733   static_cast<blink::WebAutofillClient*>(autofill_agent_)
734       ->textFieldDidEndEditing(username_element_);
735   CheckTextFieldsState("al", false, std::string(), false);
736   username_element_.setValue("alices");
737   static_cast<blink::WebAutofillClient*>(autofill_agent_)
738       ->textFieldDidEndEditing(username_element_);
739   CheckTextFieldsState("alices", false, std::string(), false);
740   username_element_.setValue(ASCIIToUTF16(kAliceUsername));
741   static_cast<blink::WebAutofillClient*>(autofill_agent_)
742       ->textFieldDidEndEditing(username_element_);
743   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
744 }
745
746 // Tests that inline autocompletion works properly.
747 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
748   // Simulate the browser sending back the login info.
749   SimulateOnFillPasswordForm(fill_data_);
750
751   ClearUsernameAndPasswordFields();
752
753   // Simulate the user typing in the first letter of 'alice', a stored
754   // username.
755   SimulateUsernameChange("a", true);
756   // Both the username and password text fields should reflect selection of the
757   // stored login.
758   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
759   // And the selection should have been set to 'lice', the last 4 letters.
760   CheckUsernameSelection(1, 5);
761
762   // Now the user types the next letter of the same username, 'l'.
763   SimulateUsernameChange("al", true);
764   // Now the fields should have the same value, but the selection should have a
765   // different start value.
766   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
767   CheckUsernameSelection(2, 5);
768
769   // Test that deleting does not trigger autocomplete.
770   SimulateKeyDownEvent(username_element_, ui::VKEY_BACK);
771   SimulateUsernameChange("alic", true);
772   CheckTextFieldsState("alic", false, std::string(), false);
773   CheckUsernameSelection(4, 4);  // No selection.
774   // Reset the last pressed key to something other than backspace.
775   SimulateKeyDownEvent(username_element_, ui::VKEY_A);
776
777   // Now lets say the user goes astray from the stored username and types the
778   // letter 'f', spelling 'alf'.  We don't know alf (that's just sad), so in
779   // practice the username should no longer be 'alice' and the selected range
780   // should be empty.
781   SimulateUsernameChange("alf", true);
782   CheckTextFieldsState("alf", false, std::string(), false);
783   CheckUsernameSelection(3, 3);  // No selection.
784
785   // Ok, so now the user removes all the text and enters the letter 'b'.
786   SimulateUsernameChange("b", true);
787   // The username and password fields should match the 'bob' entry.
788   CheckTextFieldsState(kBobUsername, true, kBobPassword, true);
789   CheckUsernameSelection(1, 3);
790
791   // Then, the user again removes all the text and types an uppercase 'C'.
792   SimulateUsernameChange("C", true);
793   // The username and password fields should match the 'Carol' entry.
794   CheckTextFieldsState(kCarolUsername, true, kCarolPassword, true);
795   CheckUsernameSelection(1, 5);
796   // The user removes all the text and types a lowercase 'c'.  We only
797   // want case-sensitive autocompletion, so the username and the selected range
798   // should be empty.
799   SimulateUsernameChange("c", true);
800   CheckTextFieldsState("c", false, std::string(), false);
801   CheckUsernameSelection(1, 1);
802
803   // Check that we complete other_possible_usernames as well.
804   SimulateUsernameChange("R", true);
805   CheckTextFieldsState(kCarolAlternateUsername, true, kCarolPassword, true);
806   CheckUsernameSelection(1, 17);
807 }
808
809 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
810   blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
811   blink::WebFrame* frame;
812
813   LoadHTML(kVisibleFormHTML);
814   frame = GetMainFrame();
815   frame->document().forms(forms1);
816   ASSERT_EQ(1u, forms1.size());
817   EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
818
819   LoadHTML(kEmptyFormHTML);
820   frame = GetMainFrame();
821   frame->document().forms(forms2);
822   ASSERT_EQ(1u, forms2.size());
823   EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
824
825   LoadHTML(kNonVisibleFormHTML);
826   frame = GetMainFrame();
827   frame->document().forms(forms3);
828   ASSERT_EQ(1u, forms3.size());
829   EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
830 }
831
832 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
833   render_thread_->sink().ClearMessages();
834   LoadHTML(kVisibleFormHTML);
835   const IPC::Message* message = render_thread_->sink()
836       .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
837   EXPECT_TRUE(message);
838   Tuple2<std::vector<autofill::PasswordForm>, bool > param;
839   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
840   EXPECT_TRUE(param.a.size());
841
842   render_thread_->sink().ClearMessages();
843   LoadHTML(kEmptyFormHTML);
844   message = render_thread_->sink().GetFirstMessageMatching(
845       AutofillHostMsg_PasswordFormsRendered::ID);
846   EXPECT_TRUE(message);
847   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
848   EXPECT_FALSE(param.a.size());
849
850   render_thread_->sink().ClearMessages();
851   LoadHTML(kNonVisibleFormHTML);
852   message = render_thread_->sink().GetFirstMessageMatching(
853       AutofillHostMsg_PasswordFormsRendered::ID);
854   EXPECT_TRUE(message);
855   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
856   EXPECT_FALSE(param.a.size());
857 }
858
859 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
860   render_thread_->sink().ClearMessages();
861   LoadHTML(kEmptyWebpage);
862   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
863       AutofillHostMsg_PasswordFormsRendered::ID));
864
865   render_thread_->sink().ClearMessages();
866   LoadHTML(kRedirectionWebpage);
867   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
868       AutofillHostMsg_PasswordFormsRendered::ID));
869
870   render_thread_->sink().ClearMessages();
871   LoadHTML(kSimpleWebpage);
872   EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
873       AutofillHostMsg_PasswordFormsRendered::ID));
874
875   render_thread_->sink().ClearMessages();
876   LoadHTML(kWebpageWithDynamicContent);
877   EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
878       AutofillHostMsg_PasswordFormsRendered::ID));
879 }
880
881 // Tests that a password form in an iframe will not be filled in until a user
882 // interaction with the form.
883 TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) {
884   const char kIframeName[] = "iframe";
885   const char kWebpageWithIframeStart[] =
886       "<html>"
887       "   <head>"
888       "       <meta charset='utf-8' />"
889       "       <title>Title</title>"
890       "   </head>"
891       "   <body>"
892       "       <iframe name='iframe' src=\"";
893   const char kWebpageWithIframeEnd[] =
894       "\"></iframe>"
895       "   </body>"
896       "</html>";
897
898   std::string origin("data:text/html;charset=utf-8,");
899   origin += kSimpleWebpage;
900
901   std::string page_html(kWebpageWithIframeStart);
902   page_html += origin;
903   page_html += kWebpageWithIframeEnd;
904
905   LoadHTML(page_html.c_str());
906
907   // Set the expected form origin and action URLs.
908   fill_data_.basic_data.origin = GURL(origin);
909   fill_data_.basic_data.action = GURL(origin);
910
911   SimulateOnFillPasswordForm(fill_data_);
912
913   // Retrieve the input elements from the iframe since that is where we want to
914   // test the autofill.
915   WebFrame* iframe = GetMainFrame()->findChildByName(kIframeName);
916   ASSERT_TRUE(iframe);
917   WebDocument document = iframe->document();
918
919   WebElement username_element = document.getElementById(kUsernameName);
920   WebElement password_element = document.getElementById(kPasswordName);
921   ASSERT_FALSE(username_element.isNull());
922   ASSERT_FALSE(password_element.isNull());
923
924   WebInputElement username_input = username_element.to<WebInputElement>();
925   WebInputElement password_input = password_element.to<WebInputElement>();
926   ASSERT_FALSE(username_element.isNull());
927
928   CheckTextFieldsStateForElements(
929       username_input, "", false, password_input, "", false, false);
930
931   // Simulate the user typing in the username in the iframe which should cause
932   // an autofill.
933   SimulateInputChangeForElement(
934       kAliceUsername, true, iframe, username_input, true);
935
936   CheckTextFieldsStateForElements(username_input,
937                                   kAliceUsername,
938                                   true,
939                                   password_input,
940                                   kAlicePassword,
941                                   true,
942                                   false);
943 }
944
945 // Tests that a password will only be filled as a suggested and will not be
946 // accessible by the DOM until a user gesture has occurred.
947 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
948   // Trigger the initial autocomplete.
949   SimulateOnFillPasswordForm(fill_data_);
950
951   // The username and password should have been autocompleted.
952   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
953
954   // However, it should only have completed with the suggested value, as tested
955   // above, and it should not have completed into the DOM accessible value for
956   // the password field.
957   CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
958
959   // Simulate a user click so that the password field's real value is filled.
960   SimulateElementClick(kUsernameName);
961   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
962 }
963
964 // Verfies that a DOM-activated UI event will not cause an autofill.
965 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
966   // Trigger the initial autocomplete.
967   SimulateOnFillPasswordForm(fill_data_);
968
969   ExecuteJavaScript(kJavaScriptClick);
970   CheckTextFieldsDOMState(kAliceUsername, true, "", true);
971 }
972
973 // Regression test for http://crbug.com/326679
974 TEST_F(PasswordAutofillAgentTest, SelectUsernameWithUsernameAutofillOff) {
975   // Simulate the browser sending back the login info.
976   SimulateOnFillPasswordForm(fill_data_);
977
978   // Set the username element to autocomplete='off'
979   username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
980                                  WebString::fromUTF8("off"));
981
982   // Simulate the user changing the username to some known username.
983   SimulateUsernameChange(kAliceUsername, true);
984
985   ExpectNoSuggestionsPopup();
986 }
987
988 // Regression test for http://crbug.com/326679
989 TEST_F(PasswordAutofillAgentTest,
990        SelectUnknownUsernameWithUsernameAutofillOff) {
991   // Simulate the browser sending back the login info.
992   SimulateOnFillPasswordForm(fill_data_);
993
994   // Set the username element to autocomplete='off'
995   username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
996                                  WebString::fromUTF8("off"));
997
998   // Simulate the user changing the username to some unknown username.
999   SimulateUsernameChange("foo", true);
1000
1001   ExpectNoSuggestionsPopup();
1002 }
1003
1004 // Regression test for http://crbug.com/326679
1005 TEST_F(PasswordAutofillAgentTest, SelectUsernameWithPasswordAutofillOff) {
1006   // Simulate the browser sending back the login info.
1007   SimulateOnFillPasswordForm(fill_data_);
1008
1009   // Set the main password element to autocomplete='off'
1010   password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
1011                                  WebString::fromUTF8("off"));
1012
1013   // Simulate the user changing the username to some known username.
1014   SimulateUsernameChange(kAliceUsername, true);
1015
1016   ExpectNoSuggestionsPopup();
1017 }
1018
1019 // Regression test for http://crbug.com/326679
1020 TEST_F(PasswordAutofillAgentTest,
1021        SelectUnknownUsernameWithPasswordAutofillOff) {
1022   // Simulate the browser sending back the login info.
1023   SimulateOnFillPasswordForm(fill_data_);
1024
1025   // Set the main password element to autocomplete='off'
1026   password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
1027                                  WebString::fromUTF8("off"));
1028
1029   // Simulate the user changing the username to some unknown username.
1030   SimulateUsernameChange("foo", true);
1031
1032   ExpectNoSuggestionsPopup();
1033 }
1034
1035 // Verifies that password autofill triggers onChange events in JavaScript for
1036 // forms that are filled on page load.
1037 TEST_F(PasswordAutofillAgentTest,
1038        PasswordAutofillTriggersOnChangeEventsOnLoad) {
1039   std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
1040   LoadHTML(html.c_str());
1041   UpdateOriginForHTML(html);
1042   UpdateUsernameAndPasswordElements();
1043
1044   // Simulate the browser sending back the login info, it triggers the
1045   // autocomplete.
1046   SimulateOnFillPasswordForm(fill_data_);
1047
1048   // The username and password should have been autocompleted...
1049   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
1050   // ... but since there hasn't been a user gesture yet, the autocompleted
1051   // password should only be visible to the user.
1052   CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
1053
1054   // A JavaScript onChange event should have been triggered for the username,
1055   // but not yet for the password.
1056   int username_onchange_called = -1;
1057   int password_onchange_called = -1;
1058   ASSERT_TRUE(
1059       ExecuteJavaScriptAndReturnIntValue(
1060           ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
1061           &username_onchange_called));
1062   EXPECT_EQ(1, username_onchange_called);
1063   ASSERT_TRUE(
1064       ExecuteJavaScriptAndReturnIntValue(
1065           ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1066           &password_onchange_called));
1067   // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
1068   // EXPECT_EQ(0, password_onchange_called);
1069
1070   // Simulate a user click so that the password field's real value is filled.
1071   SimulateElementClick(kUsernameName);
1072   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1073
1074   // Now, a JavaScript onChange event should have been triggered for the
1075   // password as well.
1076   ASSERT_TRUE(
1077       ExecuteJavaScriptAndReturnIntValue(
1078           ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1079           &password_onchange_called));
1080   EXPECT_EQ(1, password_onchange_called);
1081 }
1082
1083 // Verifies that password autofill triggers onChange events in JavaScript for
1084 // forms that are filled after page load.
1085 TEST_F(PasswordAutofillAgentTest,
1086        PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
1087   std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
1088   LoadHTML(html.c_str());
1089   UpdateOriginForHTML(html);
1090   UpdateUsernameAndPasswordElements();
1091
1092   // Simulate the browser sending back the login info, it triggers the
1093   // autocomplete.
1094   fill_data_.wait_for_username = true;
1095   SimulateOnFillPasswordForm(fill_data_);
1096
1097   // The username and password should not yet have been autocompleted.
1098   CheckTextFieldsState(std::string(), false, std::string(), false);
1099
1100   // Simulate a click just to force a user gesture, since the username value is
1101   // set directly.
1102   SimulateElementClick(kUsernameName);
1103
1104   // Simulate the user entering her username and selecting the matching autofill
1105   // from the dropdown.
1106   SimulateUsernameChange(kAliceUsername, true, true);
1107   SimulateSuggestionChoice(username_element_);
1108
1109   // The username and password should now have been autocompleted.
1110   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1111
1112   // JavaScript onChange events should have been triggered both for the username
1113   // and for the password.
1114   int username_onchange_called = -1;
1115   int password_onchange_called = -1;
1116   ASSERT_TRUE(
1117       ExecuteJavaScriptAndReturnIntValue(
1118           ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
1119           &username_onchange_called));
1120   EXPECT_EQ(1, username_onchange_called);
1121   ASSERT_TRUE(
1122       ExecuteJavaScriptAndReturnIntValue(
1123           ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1124           &password_onchange_called));
1125   EXPECT_EQ(1, password_onchange_called);
1126 }
1127
1128 // Tests that |FillSuggestion| properly fills the username and password.
1129 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
1130   // Simulate the browser sending the login info, but set |wait_for_username|
1131   // to prevent the form from being immediately filled.
1132   fill_data_.wait_for_username = true;
1133   SimulateOnFillPasswordForm(fill_data_);
1134
1135   // Neither field should have been autocompleted.
1136   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1137
1138   // If the password field is not autocompletable, it should not be affected.
1139   SetElementReadOnly(password_element_, true);
1140   EXPECT_FALSE(password_autofill_agent_->FillSuggestion(
1141       username_element_, kAliceUsername, kAlicePassword));
1142   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1143   SetElementReadOnly(password_element_, false);
1144
1145   // After filling with the suggestion, both fields should be autocompleted.
1146   EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1147       username_element_, kAliceUsername, kAlicePassword));
1148   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1149   int username_length = strlen(kAliceUsername);
1150   CheckUsernameSelection(username_length, username_length);
1151
1152   // Try Filling with a suggestion with password different from the one that was
1153   // initially sent to the renderer.
1154   EXPECT_TRUE(password_autofill_agent_->FillSuggestion(
1155       username_element_, kBobUsername, kCarolPassword));
1156   CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
1157   username_length = strlen(kBobUsername);
1158   CheckUsernameSelection(username_length, username_length);
1159 }
1160
1161 // Tests that |PreviewSuggestion| properly previews the username and password.
1162 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
1163   // Simulate the browser sending the login info, but set |wait_for_username|
1164   // to prevent the form from being immediately filled.
1165   fill_data_.wait_for_username = true;
1166   SimulateOnFillPasswordForm(fill_data_);
1167
1168   // Neither field should have been autocompleted.
1169   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1170
1171   // If the password field is not autocompletable, it should not be affected.
1172   SetElementReadOnly(password_element_, true);
1173   EXPECT_FALSE(password_autofill_agent_->PreviewSuggestion(
1174       username_element_, kAliceUsername, kAlicePassword));
1175   EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
1176   EXPECT_FALSE(username_element_.isAutofilled());
1177   EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
1178   EXPECT_FALSE(password_element_.isAutofilled());
1179   SetElementReadOnly(password_element_, false);
1180
1181   // After selecting the suggestion, both fields should be previewed
1182   // with suggested values.
1183   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1184       username_element_, kAliceUsername, kAlicePassword));
1185   EXPECT_EQ(
1186       kAliceUsername,
1187       static_cast<std::string>(username_element_.suggestedValue().utf8()));
1188   EXPECT_TRUE(username_element_.isAutofilled());
1189   EXPECT_EQ(
1190       kAlicePassword,
1191       static_cast<std::string>(password_element_.suggestedValue().utf8()));
1192   EXPECT_TRUE(password_element_.isAutofilled());
1193   int username_length = strlen(kAliceUsername);
1194   CheckUsernameSelection(0, username_length);
1195
1196   // Try previewing with a password different from the one that was initially
1197   // sent to the renderer.
1198   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1199       username_element_, kBobUsername, kCarolPassword));
1200   EXPECT_EQ(
1201       kBobUsername,
1202       static_cast<std::string>(username_element_.suggestedValue().utf8()));
1203   EXPECT_TRUE(username_element_.isAutofilled());
1204   EXPECT_EQ(
1205       kCarolPassword,
1206       static_cast<std::string>(password_element_.suggestedValue().utf8()));
1207   EXPECT_TRUE(password_element_.isAutofilled());
1208   username_length = strlen(kBobUsername);
1209   CheckUsernameSelection(0, username_length);
1210 }
1211
1212 // Tests that |PreviewSuggestion| properly sets the username selection range.
1213 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
1214   username_element_.setValue(WebString::fromUTF8("ali"));
1215   username_element_.setSelectionRange(3, 3);
1216   username_element_.setAutofilled(true);
1217
1218   CheckTextFieldsDOMState("ali", true, std::string(), false);
1219
1220   // Simulate the browser sending the login info, but set |wait_for_username|
1221   // to prevent the form from being immediately filled.
1222   fill_data_.wait_for_username = true;
1223   SimulateOnFillPasswordForm(fill_data_);
1224
1225   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1226       username_element_, kAliceUsername, kAlicePassword));
1227   EXPECT_EQ(
1228       kAliceUsername,
1229       static_cast<std::string>(username_element_.suggestedValue().utf8()));
1230   EXPECT_TRUE(username_element_.isAutofilled());
1231   EXPECT_EQ(
1232       kAlicePassword,
1233       static_cast<std::string>(password_element_.suggestedValue().utf8()));
1234   EXPECT_TRUE(password_element_.isAutofilled());
1235   int username_length = strlen(kAliceUsername);
1236   CheckUsernameSelection(3, username_length);
1237 }
1238
1239 // Tests that |ClearPreview| properly clears previewed username and password
1240 // with password being previously autofilled.
1241 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
1242   password_element_.setValue(WebString::fromUTF8("sec"));
1243   password_element_.setAutofilled(true);
1244
1245   // Simulate the browser sending the login info, but set |wait_for_username|
1246   // to prevent the form from being immediately filled.
1247   fill_data_.wait_for_username = true;
1248   SimulateOnFillPasswordForm(fill_data_);
1249
1250   CheckTextFieldsDOMState(std::string(), false, "sec", true);
1251
1252   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1253       username_element_, kAliceUsername, kAlicePassword));
1254
1255   EXPECT_TRUE(
1256       password_autofill_agent_->DidClearAutofillSelection(username_element_));
1257
1258   EXPECT_TRUE(username_element_.value().isEmpty());
1259   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1260   EXPECT_FALSE(username_element_.isAutofilled());
1261   EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1262   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1263   EXPECT_TRUE(password_element_.isAutofilled());
1264   CheckUsernameSelection(0, 0);
1265 }
1266
1267 // Tests that |ClearPreview| properly clears previewed username and password
1268 // with username being previously autofilled.
1269 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
1270   username_element_.setValue(WebString::fromUTF8("ali"));
1271   username_element_.setSelectionRange(3, 3);
1272   username_element_.setAutofilled(true);
1273
1274   // Simulate the browser sending the login info, but set |wait_for_username|
1275   // to prevent the form from being immediately filled.
1276   fill_data_.wait_for_username = true;
1277   SimulateOnFillPasswordForm(fill_data_);
1278
1279   CheckTextFieldsDOMState("ali", true, std::string(), false);
1280
1281   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1282       username_element_, kAliceUsername, kAlicePassword));
1283
1284   EXPECT_TRUE(
1285       password_autofill_agent_->DidClearAutofillSelection(username_element_));
1286
1287   EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1288   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1289   EXPECT_TRUE(username_element_.isAutofilled());
1290   EXPECT_TRUE(password_element_.value().isEmpty());
1291   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1292   EXPECT_FALSE(password_element_.isAutofilled());
1293   CheckUsernameSelection(3, 3);
1294 }
1295
1296 // Tests that |ClearPreview| properly clears previewed username and password
1297 // with username and password being previously autofilled.
1298 TEST_F(PasswordAutofillAgentTest,
1299        ClearPreviewWithAutofilledUsernameAndPassword) {
1300   username_element_.setValue(WebString::fromUTF8("ali"));
1301   username_element_.setSelectionRange(3, 3);
1302   username_element_.setAutofilled(true);
1303   password_element_.setValue(WebString::fromUTF8("sec"));
1304   password_element_.setAutofilled(true);
1305
1306   // Simulate the browser sending the login info, but set |wait_for_username|
1307   // to prevent the form from being immediately filled.
1308   fill_data_.wait_for_username = true;
1309   SimulateOnFillPasswordForm(fill_data_);
1310
1311   CheckTextFieldsDOMState("ali", true, "sec", true);
1312
1313   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1314       username_element_, kAliceUsername, kAlicePassword));
1315
1316   EXPECT_TRUE(
1317       password_autofill_agent_->DidClearAutofillSelection(username_element_));
1318
1319   EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
1320   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1321   EXPECT_TRUE(username_element_.isAutofilled());
1322   EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
1323   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1324   EXPECT_TRUE(password_element_.isAutofilled());
1325   CheckUsernameSelection(3, 3);
1326 }
1327
1328 // Tests that |ClearPreview| properly clears previewed username and password
1329 // with neither username nor password being previously autofilled.
1330 TEST_F(PasswordAutofillAgentTest,
1331        ClearPreviewWithNotAutofilledUsernameAndPassword) {
1332   // Simulate the browser sending the login info, but set |wait_for_username|
1333   // to prevent the form from being immediately filled.
1334   fill_data_.wait_for_username = true;
1335   SimulateOnFillPasswordForm(fill_data_);
1336
1337   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1338
1339   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1340       username_element_, kAliceUsername, kAlicePassword));
1341
1342   EXPECT_TRUE(
1343       password_autofill_agent_->DidClearAutofillSelection(username_element_));
1344
1345   EXPECT_TRUE(username_element_.value().isEmpty());
1346   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1347   EXPECT_FALSE(username_element_.isAutofilled());
1348   EXPECT_TRUE(password_element_.value().isEmpty());
1349   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1350   EXPECT_FALSE(password_element_.isAutofilled());
1351   CheckUsernameSelection(0, 0);
1352 }
1353
1354 // Tests that |ClearPreview| properly restores the original selection range of
1355 // username field that has initially been filled by inline autocomplete.
1356 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) {
1357   // Simulate the browser sending back the login info.
1358   SimulateOnFillPasswordForm(fill_data_);
1359
1360   // Clear the text fields to start fresh.
1361   ClearUsernameAndPasswordFields();
1362
1363   // Simulate the user typing in the first letter of 'alice', a stored username.
1364   SimulateUsernameChange("a", true);
1365   // Both the username and password text fields should reflect selection of the
1366   // stored login.
1367   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
1368   // The selection should have been set to 'lice', the last 4 letters.
1369   CheckUsernameSelection(1, 5);
1370
1371   EXPECT_TRUE(password_autofill_agent_->PreviewSuggestion(
1372       username_element_, "alicia", "secret"));
1373   EXPECT_EQ(
1374       "alicia",
1375       static_cast<std::string>(username_element_.suggestedValue().utf8()));
1376   EXPECT_TRUE(username_element_.isAutofilled());
1377   EXPECT_EQ(
1378       "secret",
1379       static_cast<std::string>(password_element_.suggestedValue().utf8()));
1380   EXPECT_TRUE(password_element_.isAutofilled());
1381   CheckUsernameSelection(1, 6);
1382
1383   EXPECT_TRUE(
1384       password_autofill_agent_->DidClearAutofillSelection(username_element_));
1385
1386   EXPECT_EQ(kAliceUsername, username_element_.value().utf8());
1387   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
1388   EXPECT_TRUE(username_element_.isAutofilled());
1389   EXPECT_TRUE(password_element_.value().isEmpty());
1390   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
1391   EXPECT_TRUE(password_element_.isAutofilled());
1392   CheckUsernameSelection(1, 5);
1393 }
1394
1395 // Tests that logging is off by default.
1396 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1397   render_thread_->sink().ClearMessages();
1398   SendVisiblePasswordForms();
1399   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1400       AutofillHostMsg_RecordSavePasswordProgress::ID);
1401   EXPECT_FALSE(message);
1402 }
1403
1404 // Test that logging can be turned on by a message.
1405 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1406   // Turn the logging on.
1407   AutofillMsg_SetLoggingState msg_activate(0, true);
1408   // Up-cast to access OnMessageReceived, which is private in the agent.
1409   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1410                   ->OnMessageReceived(msg_activate));
1411
1412   render_thread_->sink().ClearMessages();
1413   SendVisiblePasswordForms();
1414   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1415       AutofillHostMsg_RecordSavePasswordProgress::ID);
1416   EXPECT_TRUE(message);
1417 }
1418
1419 // Test that logging can be turned off by a message.
1420 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1421   // Turn the logging on and then off.
1422   AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
1423   // Up-cast to access OnMessageReceived, which is private in the agent.
1424   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1425                   ->OnMessageReceived(msg_activate));
1426   AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
1427   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_agent_)
1428                   ->OnMessageReceived(msg_deactivate));
1429
1430   render_thread_->sink().ClearMessages();
1431   SendVisiblePasswordForms();
1432   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1433       AutofillHostMsg_RecordSavePasswordProgress::ID);
1434   EXPECT_FALSE(message);
1435 }
1436
1437 // Test that the agent sends an IPC call to get the current activity state of
1438 // password saving logging soon after construction.
1439 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
1440   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1441       AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
1442   EXPECT_TRUE(message);
1443 }
1444
1445 // TODO(gcasto): Re-enabled these tests after crbug.com/423464 has been fixed.
1446 #if !defined(OS_ANDROID)
1447
1448 // Tests that one user click on a username field is sufficient to bring up a
1449 // credential suggestion popup, and the user can autocomplete the password by
1450 // selecting the credential from the popup.
1451 TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
1452   // SimulateElementClick() is called so that a user gesture is actually made
1453   // and the password can be filled. However, SimulateElementClick() does not
1454   // actually lead to the AutofillAgent's InputElementClicked() method being
1455   // called, so SimulateSuggestionChoice has to manually call
1456   // InputElementClicked().
1457   ClearUsernameAndPasswordFields();
1458   SimulateOnFillPasswordForm(fill_data_);
1459   SimulateElementClick(kUsernameName);
1460   SimulateSuggestionChoice(username_element_);
1461   ExpectAllCredentials();
1462
1463   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1464 }
1465
1466 // Tests the autosuggestions that are given when the element is clicked.
1467 // Specifically, tests when the user clicks on the username element after page
1468 // load and the element is autofilled, when the user clicks on an element that
1469 // has a non-matching username, and when the user clicks on an element that's
1470 // already been autofilled and they've already modified.
1471 TEST_F(PasswordAutofillAgentTest, CredentialsOnClick) {
1472   // Simulate the browser sending back the login info.
1473   SimulateOnFillPasswordForm(fill_data_);
1474
1475   // Clear the text fields to start fresh.
1476   ClearUsernameAndPasswordFields();
1477
1478   // Call SimulateElementClick() to produce a user gesture on the page so
1479   // autofill will actually fill.
1480   SimulateElementClick(kUsernameName);
1481
1482   // Simulate a user clicking on the username element. This should produce a
1483   // message with all the usernames.
1484   render_thread_->sink().ClearMessages();
1485   static_cast<PageClickListener*>(autofill_agent_)
1486       ->FormControlElementClicked(username_element_, false);
1487   ExpectAllCredentials();
1488
1489   // Now simulate a user typing in an unrecognized username and then
1490   // clicking on the username element. This should also produce a message with
1491   // all the usernames.
1492   SimulateUsernameChange("baz", true);
1493   render_thread_->sink().ClearMessages();
1494   static_cast<PageClickListener*>(autofill_agent_)
1495       ->FormControlElementClicked(username_element_, true);
1496   ExpectAllCredentials();
1497
1498   // Now simulate a user typing in the first letter of the username and then
1499   // clicking on the username element. While the typing of the first letter will
1500   // inline autocomplete, clicking on the element should still produce a full
1501   // suggestion list.
1502   SimulateUsernameChange("a", true);
1503   render_thread_->sink().ClearMessages();
1504   static_cast<PageClickListener*>(autofill_agent_)
1505       ->FormControlElementClicked(username_element_, true);
1506   ExpectAllCredentials();
1507 }
1508
1509 #endif  // !defined(OS_ANDROID)
1510
1511 // The user types in a password, but then just before sending the form off, a
1512 // script clears that password. This test checks that PasswordAutofillAgent can
1513 // still remember the password typed by the user.
1514 TEST_F(PasswordAutofillAgentTest,
1515        RememberLastNonEmptyPasswordOnSubmit_ScriptCleared) {
1516   SimulateInputChangeForElement(
1517       "temp", true, GetMainFrame(), username_element_, true);
1518   SimulateInputChangeForElement(
1519       "random", true, GetMainFrame(), password_element_, true);
1520
1521   // Simulate that the password value was cleared by the site's JavaScript
1522   // before submit.
1523   password_element_.setValue(WebString());
1524   static_cast<content::RenderViewObserver*>(password_autofill_agent_)
1525       ->WillSubmitForm(GetMainFrame(), username_element_.form());
1526
1527   // Observe that the PasswordAutofillAgent still remembered the last non-empty
1528   // password and sent that to the browser.
1529   ExpectFormSubmittedWithPasswords("random", "");
1530 }
1531
1532 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but this time
1533 // it's the user who clears the password. This test checks that in that case,
1534 // the last non-empty password is not remembered.
1535 TEST_F(PasswordAutofillAgentTest,
1536        RememberLastNonEmptyPasswordOnSubmit_UserCleared) {
1537   SimulateInputChangeForElement(
1538       "temp", true, GetMainFrame(), username_element_, true);
1539   SimulateInputChangeForElement(
1540       "random", true, GetMainFrame(), password_element_, true);
1541
1542   // Simulate that the user actually cleared the password again.
1543   SimulateInputChangeForElement(
1544       "", true, GetMainFrame(), password_element_, true);
1545   static_cast<content::RenderViewObserver*>(password_autofill_agent_)
1546       ->WillSubmitForm(GetMainFrame(), username_element_.form());
1547
1548   // Observe that the PasswordAutofillAgent respects the user having cleared the
1549   // password.
1550   ExpectFormSubmittedWithPasswords("", "");
1551 }
1552
1553 // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the
1554 // new password instead of the current password.
1555 TEST_F(PasswordAutofillAgentTest,
1556        RememberLastNonEmptyPasswordOnSubmit_NewPassword) {
1557   const char kNewPasswordFormHTML[] =
1558       "<FORM name='LoginTestForm'>"
1559       "  <INPUT type='text' id='username' autocomplete='username'/>"
1560       "  <INPUT type='password' id='password' autocomplete='new-password'/>"
1561       "  <INPUT type='submit' value='Login'/>"
1562       "</FORM>";
1563   LoadHTML(kNewPasswordFormHTML);
1564   UpdateUsernameAndPasswordElements();
1565
1566   SimulateInputChangeForElement(
1567       "temp", true, GetMainFrame(), username_element_, true);
1568   SimulateInputChangeForElement(
1569       "random", true, GetMainFrame(), password_element_, true);
1570
1571   // Simulate that the password value was cleared by the site's JavaScript
1572   // before submit.
1573   password_element_.setValue(WebString());
1574   static_cast<content::RenderViewObserver*>(password_autofill_agent_)
1575       ->WillSubmitForm(GetMainFrame(), username_element_.form());
1576
1577   // Observe that the PasswordAutofillAgent still remembered the last non-empty
1578   // password and sent that to the browser.
1579   ExpectFormSubmittedWithPasswords("", "random");
1580 }
1581
1582 // The user first accepts a suggestion, but then overwrites the password. This
1583 // test checks that the overwritten password is not reverted back if the user
1584 // triggers autofill through focusing (but not changing) the username again.
1585 TEST_F(PasswordAutofillAgentTest,
1586        NoopEditingDoesNotOverwriteManuallyEditedPassword) {
1587   // Simulate having credentials which needed to wait until the user starts
1588   // typing the username to be filled (e.g., PSL-matched credentials). Those are
1589   // the ones which can be filled as a result of TextFieldDidEndEditing.
1590   fill_data_.wait_for_username = true;
1591   SimulateOnFillPasswordForm(fill_data_);
1592   // Simulate that the user typed her name to make the autofill work.
1593   SimulateInputChangeForElement(kAliceUsername,
1594                                 /*move_caret_to_end=*/true,
1595                                 GetMainFrame(),
1596                                 username_element_,
1597                                 /*is_user_input=*/true);
1598   SimulateDidEndEditing(GetMainFrame(), username_element_);
1599   const std::string old_username(username_element_.value().utf8());
1600   const std::string old_password(password_element_.value().utf8());
1601   const std::string new_password(old_password + "modify");
1602
1603   // The user changes the password.
1604   SimulateInputChangeForElement(new_password,
1605                                 /*move_caret_to_end=*/true,
1606                                 GetMainFrame(),
1607                                 password_element_,
1608                                 /*is_user_input=*/true);
1609
1610   // The user switches back into the username field, but leaves that without
1611   // changes.
1612   SimulateDidEndEditing(GetMainFrame(), username_element_);
1613
1614   // The password should have stayed as the user changed it.
1615   CheckTextFieldsDOMState(old_username, true, new_password, false);
1616   // The password should not have a suggested value.
1617   CheckTextFieldsState(old_username, true, std::string(), false);
1618 }
1619
1620 TEST_F(PasswordAutofillAgentTest,
1621        InlineAutocompleteOverwritesManuallyEditedPassword) {
1622   // Simulate the browser sending back the login info.
1623   SimulateOnFillPasswordForm(fill_data_);
1624
1625   ClearUsernameAndPasswordFields();
1626
1627   // The user enters a password
1628   SimulateInputChangeForElement("someOtherPassword",
1629                                 /*move_caret_to_end=*/true,
1630                                 GetMainFrame(),
1631                                 password_element_,
1632                                 /*is_user_input=*/true);
1633
1634   // Simulate the user typing a stored username.
1635   SimulateUsernameChange(kAliceUsername, true);
1636   // The autofileld password should replace the typed one.
1637   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1638 }
1639
1640 }  // namespace autofill