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
28using autofill::PasswordForm;
29using base::ASCIIToUTF16;
30using base::UTF16ToUTF8;
31using blink::WebDocument;
32using blink::WebElement;
33using blink::WebFrame;
34using blink::WebInputElement;
35using blink::WebString;
36using blink::WebView;
37
38namespace {
39
40// The name of the username/password element in the form.
41const char kUsernameName[] = "username";
42const char kPasswordName[] = "password";
43
44const char kAliceUsername[] = "alice";
45const char kAlicePassword[] = "password";
46const char kBobUsername[] = "bob";
47const char kBobPassword[] = "secret";
48const char kCarolUsername[] = "Carol";
49const char kCarolPassword[] = "test";
50const char kCarolAlternateUsername[] = "RealCarolUsername";
51
52const 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
59const 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
69const char kEmptyFormHTML[] =
70    "<head> <style> form {display: inline;} </style> </head>"
71    "<body> <form> </form> </body>";
72
73const 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
83const char kEmptyWebpage[] =
84    "<html>"
85    "   <head>"
86    "   </head>"
87    "   <body>"
88    "   </body>"
89    "</html>";
90
91const 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
105const 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
120const 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
137const 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
147const 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|.
160void SetElementReadOnly(WebInputElement& element, bool read_only) {
161  element.setAttribute(WebString::fromUTF8("readonly"),
162                       read_only ? WebString::fromUTF8("true") : WebString());
163}
164
165}  // namespace
166
167namespace autofill {
168
169class 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.
495TEST_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.
527TEST_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.
560TEST_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.
572TEST_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.
584TEST_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.
594TEST_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.
607TEST_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
615TEST_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
627TEST_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
655TEST_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.
684TEST_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.
696TEST_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.
710TEST_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.
747TEST_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
809TEST_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
832TEST_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
859TEST_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.
883TEST_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.
947TEST_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.
965TEST_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
974TEST_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
989TEST_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
1005TEST_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
1020TEST_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.
1037TEST_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.
1085TEST_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.
1129TEST_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.
1162TEST_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.
1213TEST_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.
1241TEST_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.
1269TEST_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.
1298TEST_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.
1330TEST_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.
1356TEST_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.
1396TEST_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.
1405TEST_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.
1420TEST_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.
1439TEST_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.
1451TEST_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.
1471TEST_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.
1514TEST_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.
1535TEST_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.
1555TEST_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.
1585TEST_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
1620TEST_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
1641