Upstream version 7.36.149.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     password_autofill_->OnMessageReceived(msg);
181   }
182
183   void SendVisiblePasswordForms() {
184     password_autofill_->SendPasswordForms(GetMainFrame(),
185                                           true /* only_visible */);
186   }
187
188   virtual void SetUp() {
189     ChromeRenderViewTest::SetUp();
190
191     // Add a preferred login and an additional login to the FillData.
192     username1_ = ASCIIToUTF16(kAliceUsername);
193     password1_ = ASCIIToUTF16(kAlicePassword);
194     username2_ = ASCIIToUTF16(kBobUsername);
195     password2_ = ASCIIToUTF16(kBobPassword);
196     username3_ = ASCIIToUTF16(kCarolUsername);
197     password3_ = ASCIIToUTF16(kCarolPassword);
198     alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
199
200     FormFieldData username_field;
201     username_field.name = ASCIIToUTF16(kUsernameName);
202     username_field.value = username1_;
203     fill_data_.basic_data.fields.push_back(username_field);
204
205     FormFieldData password_field;
206     password_field.name = ASCIIToUTF16(kPasswordName);
207     password_field.value = password1_;
208     password_field.form_control_type = "password";
209     fill_data_.basic_data.fields.push_back(password_field);
210
211     PasswordAndRealm password2;
212     password2.password = password2_;
213     fill_data_.additional_logins[username2_] = password2;
214     PasswordAndRealm password3;
215     password3.password = password3_;
216     fill_data_.additional_logins[username3_] = password3;
217
218     UsernamesCollectionKey key;
219     key.username = username3_;
220     key.password = password3_;
221     key.realm = "google.com";
222     fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
223
224     // We need to set the origin so it matches the frame URL and the action so
225     // it matches the form action, otherwise we won't autocomplete.
226     UpdateOriginForHTML(kFormHTML);
227     fill_data_.basic_data.action = GURL("http://www.bidule.com");
228
229     LoadHTML(kFormHTML);
230
231     // Now retrieve the input elements so the test can access them.
232     UpdateUsernameAndPasswordElements();
233   }
234
235   virtual void TearDown() {
236     username_element_.reset();
237     password_element_.reset();
238     ChromeRenderViewTest::TearDown();
239   }
240
241   void UpdateOriginForHTML(const std::string& html) {
242     std::string origin = "data:text/html;charset=utf-8," + html;
243     fill_data_.basic_data.origin = GURL(origin);
244   }
245
246   void UpdateUsernameAndPasswordElements() {
247     WebDocument document = GetMainFrame()->document();
248     WebElement element =
249         document.getElementById(WebString::fromUTF8(kUsernameName));
250     ASSERT_FALSE(element.isNull());
251     username_element_ = element.to<blink::WebInputElement>();
252     element = document.getElementById(WebString::fromUTF8(kPasswordName));
253     ASSERT_FALSE(element.isNull());
254     password_element_ = element.to<blink::WebInputElement>();
255   }
256
257   void ClearUsernameAndPasswordFields() {
258     username_element_.setValue("");
259     username_element_.setAutofilled(false);
260     password_element_.setValue("");
261     password_element_.setAutofilled(false);
262   }
263
264   void SimulateUsernameChangeForElement(const std::string& username,
265                                         bool move_caret_to_end,
266                                         WebFrame* input_frame,
267                                         WebInputElement& username_input) {
268     username_input.setValue(WebString::fromUTF8(username));
269     // The field must have focus or AutofillAgent will think the
270     // change should be ignored.
271     while (!username_input.focused())
272       input_frame->document().frame()->view()->advanceFocus(false);
273     if (move_caret_to_end)
274       username_input.setSelectionRange(username.length(), username.length());
275     autofill_agent_->textFieldDidChange(username_input);
276     // Processing is delayed because of a Blink bug:
277     // https://bugs.webkit.org/show_bug.cgi?id=16976
278     // See PasswordAutofillAgent::TextDidChangeInTextField() for details.
279
280     // Autocomplete will trigger a style recalculation when we put up the next
281     // frame, but we don't want to wait that long. Instead, trigger a style
282     // recalcuation manually after TextFieldDidChangeImpl runs.
283     base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
284         &PasswordAutofillAgentTest::LayoutMainFrame, base::Unretained(this)));
285
286     base::MessageLoop::current()->RunUntilIdle();
287   }
288
289   void LayoutMainFrame() {
290     GetMainFrame()->view()->layout();
291   }
292
293   void SimulateUsernameChange(const std::string& username,
294                               bool move_caret_to_end) {
295     SimulateUsernameChangeForElement(username, move_caret_to_end,
296                                      GetMainFrame(), username_element_);
297   }
298
299   // Tests that no suggestion popup is generated when the username_element_ is
300   // edited.
301   void ExpectNoSuggestionsPopup() {
302     // The first test below ensures that the suggestions have been handled by
303     // the password_autofill_agent, even though autocomplete='off' is set. The
304     // second check ensures that, although handled, no "show suggestions" IPC to
305     // the browser was generated.
306     //
307     // This is interesting in the specific case of an autocomplete='off' form
308     // that also has a remembered username and password
309     // (http://crbug.com/326679). To fix the DCHECK that this case used to hit,
310     // |true| is returned from ShowSuggestions for all forms with valid
311     // usersnames that are autocomplete='off', prentending that a selection box
312     // has been shown to the user. Of course, it hasn't, so a message is never
313     // sent to the browser on acceptance, and the DCHECK isn't hit (and nothing
314     // is filled).
315     //
316     // These tests only make sense in the context of not ignoring
317     // autocomplete='off', so only test them if the disable autocomplete='off'
318     // flag is not enabled.
319     // TODO(jww): Remove this function and callers once autocomplete='off' is
320     // permanently ignored.
321     if (!ShouldIgnoreAutocompleteOffForPasswordFields()) {
322       EXPECT_TRUE(autofill_agent_->password_autofill_agent_->ShowSuggestions(
323           username_element_));
324
325       EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
326           AutofillHostMsg_ShowPasswordSuggestions::ID));
327     }
328   }
329
330   void SimulateKeyDownEvent(const WebInputElement& element,
331                             ui::KeyboardCode key_code) {
332     blink::WebKeyboardEvent key_event;
333     key_event.windowsKeyCode = key_code;
334     autofill_agent_->textFieldDidReceiveKeyDown(element, key_event);
335   }
336
337   void CheckTextFieldsStateForElements(const WebInputElement& username_element,
338                                        const std::string& username,
339                                        bool username_autofilled,
340                                        const WebInputElement& password_element,
341                                        const std::string& password,
342                                        bool password_autofilled,
343                                        bool checkSuggestedValue = true) {
344     EXPECT_EQ(username,
345               static_cast<std::string>(username_element.value().utf8()));
346     EXPECT_EQ(username_autofilled, username_element.isAutofilled());
347     EXPECT_EQ(password,
348               static_cast<std::string>(
349                   checkSuggestedValue ? password_element.suggestedValue().utf8()
350                                       : password_element.value().utf8()));
351     EXPECT_EQ(password_autofilled, password_element.isAutofilled());
352   }
353
354   // Checks the DOM-accessible value of the username element and the
355   // *suggested* value of the password element.
356   void CheckTextFieldsState(const std::string& username,
357                             bool username_autofilled,
358                             const std::string& password,
359                             bool password_autofilled) {
360     CheckTextFieldsStateForElements(username_element_, username,
361                                     username_autofilled, password_element_,
362                                     password, password_autofilled);
363   }
364
365   // Checks the DOM-accessible value of the username element and the
366   // DOM-accessible value of the password element.
367   void CheckTextFieldsDOMState(const std::string& username,
368                                bool username_autofilled,
369                                const std::string& password,
370                                bool password_autofilled) {
371     CheckTextFieldsStateForElements(username_element_,
372                                     username,
373                                     username_autofilled,
374                                     password_element_,
375                                     password,
376                                     password_autofilled,
377                                     false);
378   }
379
380   void CheckUsernameSelection(int start, int end) {
381     EXPECT_EQ(start, username_element_.selectionStart());
382     EXPECT_EQ(end, username_element_.selectionEnd());
383   }
384
385   base::string16 username1_;
386   base::string16 username2_;
387   base::string16 username3_;
388   base::string16 password1_;
389   base::string16 password2_;
390   base::string16 password3_;
391   base::string16 alternate_username3_;
392   PasswordFormFillData fill_data_;
393
394   WebInputElement username_element_;
395   WebInputElement password_element_;
396
397  private:
398   DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
399 };
400
401 // Tests that the password login is autocompleted as expected when the browser
402 // sends back the password info.
403 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
404   /*
405    * Right now we are not sending the message to the browser because we are
406    * loading a data URL and the security origin canAccessPasswordManager()
407    * returns false.  May be we should mock URL loading to cirmcuvent this?
408    TODO(jcivelli): find a way to make the security origin not deny access to the
409                    password manager and then reenable this code.
410
411   // The form has been loaded, we should have sent the browser a message about
412   // the form.
413   const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
414       AutofillHostMsg_PasswordFormsParsed::ID);
415   ASSERT_TRUE(msg != NULL);
416
417   Tuple1<std::vector<PasswordForm> > forms;
418   AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
419   ASSERT_EQ(1U, forms.a.size());
420   PasswordForm password_form = forms.a[0];
421   EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
422   EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
423   EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
424   */
425
426   // Simulate the browser sending back the login info, it triggers the
427   // autocomplete.
428   SimulateOnFillPasswordForm(fill_data_);
429
430   // The username and password should have been autocompleted.
431   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
432 }
433
434 // Tests that we correctly fill forms having an empty 'action' attribute.
435 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
436   const char kEmptyActionFormHTML[] =
437       "<FORM name='LoginTestForm'>"
438       "  <INPUT type='text' id='username'/>"
439       "  <INPUT type='password' id='password'/>"
440       "  <INPUT type='submit' value='Login'/>"
441       "</FORM>";
442   LoadHTML(kEmptyActionFormHTML);
443
444   // Retrieve the input elements so the test can access them.
445   WebDocument document = GetMainFrame()->document();
446   WebElement element =
447       document.getElementById(WebString::fromUTF8(kUsernameName));
448   ASSERT_FALSE(element.isNull());
449   username_element_ = element.to<blink::WebInputElement>();
450   element = document.getElementById(WebString::fromUTF8(kPasswordName));
451   ASSERT_FALSE(element.isNull());
452   password_element_ = element.to<blink::WebInputElement>();
453
454   // Set the expected form origin and action URLs.
455   UpdateOriginForHTML(kEmptyActionFormHTML);
456   fill_data_.basic_data.action = fill_data_.basic_data.origin;
457
458   // Simulate the browser sending back the login info, it triggers the
459   // autocomplete.
460   SimulateOnFillPasswordForm(fill_data_);
461
462   // The username and password should have been autocompleted.
463   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
464 }
465
466 // Tests that if a password is marked as readonly, neither field is autofilled
467 // on page load.
468 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnlyPassword) {
469   SetElementReadOnly(password_element_, true);
470
471   // Simulate the browser sending back the login info, it triggers the
472   // autocomplete.
473   SimulateOnFillPasswordForm(fill_data_);
474
475   CheckTextFieldsState(std::string(), false, std::string(), false);
476 }
477
478 // Can still fill a password field if the username is set to a value that
479 // matches.
480 TEST_F(PasswordAutofillAgentTest,
481        AutocompletePasswordForReadonlyUsernameMatched) {
482   username_element_.setValue(username3_);
483   SetElementReadOnly(username_element_, true);
484
485   // Filled even though username is not the preferred match.
486   SimulateOnFillPasswordForm(fill_data_);
487   CheckTextFieldsState(UTF16ToUTF8(username3_), false,
488                        UTF16ToUTF8(password3_), true);
489 }
490
491 // If a username field is empty and readonly, don't autofill.
492 TEST_F(PasswordAutofillAgentTest,
493        NoAutocompletePasswordForReadonlyUsernameUnmatched) {
494   username_element_.setValue(WebString::fromUTF8(""));
495   SetElementReadOnly(username_element_, true);
496
497   SimulateOnFillPasswordForm(fill_data_);
498   CheckTextFieldsState(std::string(), false, std::string(), false);
499 }
500
501 // Tests that having a non-matching username precludes the autocomplete.
502 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForFilledFieldUnmatched) {
503   username_element_.setValue(WebString::fromUTF8("bogus"));
504
505   // Simulate the browser sending back the login info, it triggers the
506   // autocomplete.
507   SimulateOnFillPasswordForm(fill_data_);
508
509   // Neither field should be autocompleted.
510   CheckTextFieldsState("bogus", false, std::string(), false);
511 }
512
513 // Don't try to complete a prefilled value even if it's a partial match
514 // to a username.
515 TEST_F(PasswordAutofillAgentTest, NoPartialMatchForPrefilledUsername) {
516   username_element_.setValue(WebString::fromUTF8("ali"));
517
518   SimulateOnFillPasswordForm(fill_data_);
519
520   CheckTextFieldsState("ali", false, std::string(), false);
521 }
522
523 TEST_F(PasswordAutofillAgentTest, InputWithNoForms) {
524   const char kNoFormInputs[] =
525       "<input type='text' id='username'/>"
526       "<input type='password' id='password'/>";
527   LoadHTML(kNoFormInputs);
528
529   SimulateOnFillPasswordForm(fill_data_);
530
531   // Input elements that aren't in a <form> won't autofill.
532   CheckTextFieldsState(std::string(), false, std::string(), false);
533 }
534
535 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
536   const char kTextFieldPasswordFormHTML[] =
537       "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
538       "  <INPUT type='text' id='username'/>"
539       "  <INPUT type='text' id='password'/>"
540       "  <INPUT type='submit' value='Login'/>"
541       "</FORM>";
542   LoadHTML(kTextFieldPasswordFormHTML);
543
544   // Retrieve the input elements so the test can access them.
545   WebDocument document = GetMainFrame()->document();
546   WebElement element =
547       document.getElementById(WebString::fromUTF8(kUsernameName));
548   ASSERT_FALSE(element.isNull());
549   username_element_ = element.to<blink::WebInputElement>();
550   element = document.getElementById(WebString::fromUTF8(kPasswordName));
551   ASSERT_FALSE(element.isNull());
552   password_element_ = element.to<blink::WebInputElement>();
553
554   // Set the expected form origin URL.
555   UpdateOriginForHTML(kTextFieldPasswordFormHTML);
556
557   SimulateOnFillPasswordForm(fill_data_);
558
559   // Fields should still be empty.
560   CheckTextFieldsState(std::string(), false, std::string(), false);
561 }
562
563 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
564   const char kPasswordFieldUsernameFormHTML[] =
565       "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
566       "  <INPUT type='password' id='username'/>"
567       "  <INPUT type='password' id='password'/>"
568       "  <INPUT type='submit' value='Login'/>"
569       "</FORM>";
570   LoadHTML(kPasswordFieldUsernameFormHTML);
571
572   // Retrieve the input elements so the test can access them.
573   WebDocument document = GetMainFrame()->document();
574   WebElement element =
575       document.getElementById(WebString::fromUTF8(kUsernameName));
576   ASSERT_FALSE(element.isNull());
577   username_element_ = element.to<blink::WebInputElement>();
578   element = document.getElementById(WebString::fromUTF8(kPasswordName));
579   ASSERT_FALSE(element.isNull());
580   password_element_ = element.to<blink::WebInputElement>();
581
582   // Set the expected form origin URL.
583   UpdateOriginForHTML(kPasswordFieldUsernameFormHTML);
584
585   SimulateOnFillPasswordForm(fill_data_);
586
587   // Fields should still be empty.
588   CheckTextFieldsState(std::string(), false, std::string(), false);
589 }
590
591 // Tests that having a matching username does not preclude the autocomplete.
592 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
593   username_element_.setValue(WebString::fromUTF8(kAliceUsername));
594
595   // Simulate the browser sending back the login info, it triggers the
596   // autocomplete.
597   SimulateOnFillPasswordForm(fill_data_);
598
599   // The username and password should have been autocompleted.
600   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
601 }
602
603 // Tests that editing the password clears the autocompleted password field.
604 TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
605   // Simulate the browser sending back the login info, it triggers the
606   // autocomplete.
607   SimulateOnFillPasswordForm(fill_data_);
608
609   // Simulate the user changing the username to some unknown username.
610   SimulateUsernameChange("alicia", true);
611
612   // The password should have been cleared.
613   CheckTextFieldsState("alicia", false, std::string(), false);
614 }
615
616 // Tests that we only autocomplete on focus lost and with a full username match
617 // when |wait_for_username| is true.
618 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
619   // Simulate the browser sending back the login info.
620   fill_data_.wait_for_username = true;
621   SimulateOnFillPasswordForm(fill_data_);
622
623   // No auto-fill should have taken place.
624   CheckTextFieldsState(std::string(), false, std::string(), false);
625
626   // No autocomplete should happen when text is entered in the username.
627   SimulateUsernameChange("a", true);
628   CheckTextFieldsState("a", false, std::string(), false);
629   SimulateUsernameChange("al", true);
630   CheckTextFieldsState("al", false, std::string(), false);
631   SimulateUsernameChange(kAliceUsername, true);
632   CheckTextFieldsState(kAliceUsername, false, std::string(), false);
633
634   // Autocomplete should happen only when the username textfield is blurred with
635   // a full match.
636   username_element_.setValue("a");
637   autofill_agent_->textFieldDidEndEditing(username_element_);
638   CheckTextFieldsState("a", false, std::string(), false);
639   username_element_.setValue("al");
640   autofill_agent_->textFieldDidEndEditing(username_element_);
641   CheckTextFieldsState("al", false, std::string(), false);
642   username_element_.setValue("alices");
643   autofill_agent_->textFieldDidEndEditing(username_element_);
644   CheckTextFieldsState("alices", false, std::string(), false);
645   username_element_.setValue(ASCIIToUTF16(kAliceUsername));
646   autofill_agent_->textFieldDidEndEditing(username_element_);
647   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
648 }
649
650 // Tests that inline autocompletion works properly.
651 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
652   // Simulate the browser sending back the login info.
653   SimulateOnFillPasswordForm(fill_data_);
654
655   // Clear the text fields to start fresh.
656   ClearUsernameAndPasswordFields();
657
658   // Simulate the user typing in the first letter of 'alice', a stored username.
659   SimulateUsernameChange("a", true);
660   // Both the username and password text fields should reflect selection of the
661   // stored login.
662   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
663   // And the selection should have been set to 'lice', the last 4 letters.
664   CheckUsernameSelection(1, 5);
665
666   // Now the user types the next letter of the same username, 'l'.
667   SimulateUsernameChange("al", true);
668   // Now the fields should have the same value, but the selection should have a
669   // different start value.
670   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
671   CheckUsernameSelection(2, 5);
672
673   // Test that deleting does not trigger autocomplete.
674   SimulateKeyDownEvent(username_element_, ui::VKEY_BACK);
675   SimulateUsernameChange("alic", true);
676   CheckTextFieldsState("alic", false, std::string(), false);
677   CheckUsernameSelection(4, 4);  // No selection.
678   // Reset the last pressed key to something other than backspace.
679   SimulateKeyDownEvent(username_element_, ui::VKEY_A);
680
681   // Now lets say the user goes astray from the stored username and types the
682   // letter 'f', spelling 'alf'.  We don't know alf (that's just sad), so in
683   // practice the username should no longer be 'alice' and the selected range
684   // should be empty.
685   SimulateUsernameChange("alf", true);
686   CheckTextFieldsState("alf", false, std::string(), false);
687   CheckUsernameSelection(3, 3);  // No selection.
688
689   // Ok, so now the user removes all the text and enters the letter 'b'.
690   SimulateUsernameChange("b", true);
691   // The username and password fields should match the 'bob' entry.
692   CheckTextFieldsState(kBobUsername, true, kBobPassword, true);
693   CheckUsernameSelection(1, 3);
694
695   // Then, the user again removes all the text and types an uppercase 'C'.
696   SimulateUsernameChange("C", true);
697   // The username and password fields should match the 'Carol' entry.
698   CheckTextFieldsState(kCarolUsername, true, kCarolPassword, true);
699   CheckUsernameSelection(1, 5);
700   // The user removes all the text and types a lowercase 'c'.  We only
701   // want case-sensitive autocompletion, so the username and the selected range
702   // should be empty.
703   SimulateUsernameChange("c", true);
704   CheckTextFieldsState("c", false, std::string(), false);
705   CheckUsernameSelection(1, 1);
706
707   // Check that we complete other_possible_usernames as well.
708   SimulateUsernameChange("R", true);
709   CheckTextFieldsState(kCarolAlternateUsername, true, kCarolPassword, true);
710   CheckUsernameSelection(1, 17);
711 }
712
713 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
714   blink::WebVector<blink::WebFormElement> forms1, forms2, forms3;
715   blink::WebFrame* frame;
716
717   LoadHTML(kVisibleFormHTML);
718   frame = GetMainFrame();
719   frame->document().forms(forms1);
720   ASSERT_EQ(1u, forms1.size());
721   EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
722
723   LoadHTML(kEmptyFormHTML);
724   frame = GetMainFrame();
725   frame->document().forms(forms2);
726   ASSERT_EQ(1u, forms2.size());
727   EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
728
729   LoadHTML(kNonVisibleFormHTML);
730   frame = GetMainFrame();
731   frame->document().forms(forms3);
732   ASSERT_EQ(1u, forms3.size());
733   EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
734 }
735
736 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
737   render_thread_->sink().ClearMessages();
738   LoadHTML(kVisibleFormHTML);
739   const IPC::Message* message = render_thread_->sink()
740       .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
741   EXPECT_TRUE(message);
742   Tuple1<std::vector<autofill::PasswordForm> > param;
743   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
744   EXPECT_TRUE(param.a.size());
745
746   render_thread_->sink().ClearMessages();
747   LoadHTML(kEmptyFormHTML);
748   message = render_thread_->sink().GetFirstMessageMatching(
749       AutofillHostMsg_PasswordFormsRendered::ID);
750   EXPECT_TRUE(message);
751   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
752   EXPECT_FALSE(param.a.size());
753
754   render_thread_->sink().ClearMessages();
755   LoadHTML(kNonVisibleFormHTML);
756   message = render_thread_->sink().GetFirstMessageMatching(
757       AutofillHostMsg_PasswordFormsRendered::ID);
758   EXPECT_TRUE(message);
759   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
760   EXPECT_FALSE(param.a.size());
761 }
762
763 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
764   render_thread_->sink().ClearMessages();
765   LoadHTML(kEmptyWebpage);
766   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
767       AutofillHostMsg_PasswordFormsRendered::ID));
768
769   render_thread_->sink().ClearMessages();
770   LoadHTML(kRedirectionWebpage);
771   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
772       AutofillHostMsg_PasswordFormsRendered::ID));
773
774   render_thread_->sink().ClearMessages();
775   LoadHTML(kSimpleWebpage);
776   EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
777       AutofillHostMsg_PasswordFormsRendered::ID));
778
779   render_thread_->sink().ClearMessages();
780   LoadHTML(kWebpageWithDynamicContent);
781   EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
782       AutofillHostMsg_PasswordFormsRendered::ID));
783 }
784
785 // Tests that a password form in an iframe will not be filled in until a user
786 // interaction with the form.
787 TEST_F(PasswordAutofillAgentTest, IframeNoFillTest) {
788   const char kIframeName[] = "iframe";
789   const char kWebpageWithIframeStart[] =
790       "<html>"
791       "   <head>"
792       "       <meta charset='utf-8' />"
793       "       <title>Title</title>"
794       "   </head>"
795       "   <body>"
796       "       <iframe name='iframe' src=\"";
797   const char kWebpageWithIframeEnd[] =
798       "\"></iframe>"
799       "   </body>"
800       "</html>";
801
802   std::string origin("data:text/html;charset=utf-8,");
803   origin += kSimpleWebpage;
804
805   std::string page_html(kWebpageWithIframeStart);
806   page_html += origin;
807   page_html += kWebpageWithIframeEnd;
808
809   LoadHTML(page_html.c_str());
810
811   // Set the expected form origin and action URLs.
812   fill_data_.basic_data.origin = GURL(origin);
813   fill_data_.basic_data.action = GURL(origin);
814
815   SimulateOnFillPasswordForm(fill_data_);
816
817   // Retrieve the input elements from the iframe since that is where we want to
818   // test the autofill.
819   WebFrame* iframe = GetMainFrame()->findChildByName(kIframeName);
820   ASSERT_TRUE(iframe);
821   WebDocument document = iframe->document();
822
823   WebElement username_element = document.getElementById(kUsernameName);
824   WebElement password_element = document.getElementById(kPasswordName);
825   ASSERT_FALSE(username_element.isNull());
826   ASSERT_FALSE(password_element.isNull());
827
828   WebInputElement username_input = username_element.to<WebInputElement>();
829   WebInputElement password_input = password_element.to<WebInputElement>();
830   ASSERT_FALSE(username_element.isNull());
831
832   CheckTextFieldsStateForElements(username_input, "", false,
833                                   password_input, "", false);
834
835   // Simulate the user typing in the username in the iframe, which should cause
836   // an autofill.
837   SimulateUsernameChangeForElement(kAliceUsername, true,
838                                    iframe, username_input);
839
840   CheckTextFieldsStateForElements(username_input, kAliceUsername, true,
841                                   password_input, kAlicePassword, true);
842 }
843
844 // Tests that a password will only be filled as a suggested and will not be
845 // accessible by the DOM until a user gesture has occurred.
846 TEST_F(PasswordAutofillAgentTest, GestureRequiredTest) {
847   // Trigger the initial autocomplete.
848   SimulateOnFillPasswordForm(fill_data_);
849
850   // The username and password should have been autocompleted.
851   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
852
853   // However, it should only have completed with the suggested value, as tested
854   // above, and it should not have completed into the DOM accessible value for
855   // the password field.
856   CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
857
858   // Simulate a user click so that the password field's real value is filled.
859   SimulateElementClick(kUsernameName);
860   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
861 }
862
863 // Verfies that a DOM-activated UI event will not cause an autofill.
864 TEST_F(PasswordAutofillAgentTest, NoDOMActivationTest) {
865   // Trigger the initial autocomplete.
866   SimulateOnFillPasswordForm(fill_data_);
867
868   ExecuteJavaScript(kJavaScriptClick);
869   CheckTextFieldsDOMState(kAliceUsername, true, "", true);
870 }
871
872 // Regression test for http://crbug.com/326679
873 TEST_F(PasswordAutofillAgentTest, SelectUsernameWithUsernameAutofillOff) {
874   // Simulate the browser sending back the login info.
875   SimulateOnFillPasswordForm(fill_data_);
876
877   // Set the username element to autocomplete='off'
878   username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
879                                  WebString::fromUTF8("off"));
880
881   // Simulate the user changing the username to some known username.
882   SimulateUsernameChange(kAliceUsername, true);
883
884   ExpectNoSuggestionsPopup();
885 }
886
887 // Regression test for http://crbug.com/326679
888 TEST_F(PasswordAutofillAgentTest,
889        SelectUnknownUsernameWithUsernameAutofillOff) {
890   // Simulate the browser sending back the login info.
891   SimulateOnFillPasswordForm(fill_data_);
892
893   // Set the username element to autocomplete='off'
894   username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
895                                  WebString::fromUTF8("off"));
896
897   // Simulate the user changing the username to some unknown username.
898   SimulateUsernameChange("foo", true);
899
900   ExpectNoSuggestionsPopup();
901 }
902
903 // Regression test for http://crbug.com/326679
904 TEST_F(PasswordAutofillAgentTest, SelectUsernameWithPasswordAutofillOff) {
905   // Simulate the browser sending back the login info.
906   SimulateOnFillPasswordForm(fill_data_);
907
908   // Set the main password element to autocomplete='off'
909   password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
910                                  WebString::fromUTF8("off"));
911
912  // Simulate the user changing the username to some known username.
913   SimulateUsernameChange(kAliceUsername, true);
914
915   ExpectNoSuggestionsPopup();
916 }
917
918 // Regression test for http://crbug.com/326679
919 TEST_F(PasswordAutofillAgentTest,
920        SelectUnknownUsernameWithPasswordAutofillOff) {
921   // Simulate the browser sending back the login info.
922   SimulateOnFillPasswordForm(fill_data_);
923
924   // Set the main password element to autocomplete='off'
925   password_element_.setAttribute(WebString::fromUTF8("autocomplete"),
926                                  WebString::fromUTF8("off"));
927
928   // Simulate the user changing the username to some unknown username.
929   SimulateUsernameChange("foo", true);
930
931   ExpectNoSuggestionsPopup();
932 }
933
934 // Verifies that password autofill triggers onChange events in JavaScript for
935 // forms that are filled on page load.
936 TEST_F(PasswordAutofillAgentTest,
937        PasswordAutofillTriggersOnChangeEventsOnLoad) {
938   std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
939   LoadHTML(html.c_str());
940   UpdateOriginForHTML(html);
941   UpdateUsernameAndPasswordElements();
942
943   // Simulate the browser sending back the login info, it triggers the
944   // autocomplete.
945   SimulateOnFillPasswordForm(fill_data_);
946
947   // The username and password should have been autocompleted...
948   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
949   // ... but since there hasn't been a user gesture yet, the autocompleted
950   // password should only be visible to the user.
951   CheckTextFieldsDOMState(kAliceUsername, true, std::string(), true);
952
953   // A JavaScript onChange event should have been triggered for the username,
954   // but not yet for the password.
955   int username_onchange_called = -1;
956   int password_onchange_called = -1;
957   ASSERT_TRUE(
958       ExecuteJavaScriptAndReturnIntValue(
959           ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
960           &username_onchange_called));
961   EXPECT_EQ(1, username_onchange_called);
962   ASSERT_TRUE(
963       ExecuteJavaScriptAndReturnIntValue(
964           ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
965           &password_onchange_called));
966   // TODO(isherman): Re-enable this check once http://crbug.com/333144 is fixed.
967   // EXPECT_EQ(0, password_onchange_called);
968
969   // Simulate a user click so that the password field's real value is filled.
970   SimulateElementClick(kUsernameName);
971   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
972
973   // Now, a JavaScript onChange event should have been triggered for the
974   // password as well.
975   ASSERT_TRUE(
976       ExecuteJavaScriptAndReturnIntValue(
977           ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
978           &password_onchange_called));
979   EXPECT_EQ(1, password_onchange_called);
980 }
981
982 // Verifies that password autofill triggers onChange events in JavaScript for
983 // forms that are filled after page load.
984 TEST_F(PasswordAutofillAgentTest,
985        PasswordAutofillTriggersOnChangeEventsWaitForUsername) {
986   std::string html = std::string(kFormHTML) + kOnChangeDetectionScript;
987   LoadHTML(html.c_str());
988   UpdateOriginForHTML(html);
989   UpdateUsernameAndPasswordElements();
990
991   // Simulate the browser sending back the login info, it triggers the
992   // autocomplete.
993   fill_data_.wait_for_username = true;
994   SimulateOnFillPasswordForm(fill_data_);
995
996   // The username and password should not yet have been autocompleted.
997   CheckTextFieldsState(std::string(), false, std::string(), false);
998
999   // Simulate a click just to force a user gesture, since the username value is
1000   // set directly.
1001   SimulateElementClick(kUsernameName);
1002
1003   // Simulate the user entering her username.
1004   username_element_.setValue(ASCIIToUTF16(kAliceUsername), true);
1005   autofill_agent_->textFieldDidEndEditing(username_element_);
1006
1007   // The username and password should now have been autocompleted.
1008   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1009
1010   // JavaScript onChange events should have been triggered both for the username
1011   // and for the password.
1012   int username_onchange_called = -1;
1013   int password_onchange_called = -1;
1014   ASSERT_TRUE(
1015       ExecuteJavaScriptAndReturnIntValue(
1016           ASCIIToUTF16("usernameOnchangeCalled ? 1 : 0"),
1017           &username_onchange_called));
1018   EXPECT_EQ(1, username_onchange_called);
1019   ASSERT_TRUE(
1020       ExecuteJavaScriptAndReturnIntValue(
1021           ASCIIToUTF16("passwordOnchangeCalled ? 1 : 0"),
1022           &password_onchange_called));
1023   EXPECT_EQ(1, password_onchange_called);
1024 }
1025
1026 // Tests that |AcceptSuggestion| properly fills the username and password.
1027 TEST_F(PasswordAutofillAgentTest, AcceptSuggestion) {
1028   // Simulate the browser sending the login info, but set |wait_for_username|
1029   // to prevent the form from being immediately filled.
1030   fill_data_.wait_for_username = true;
1031   SimulateOnFillPasswordForm(fill_data_);
1032
1033   // Neither field should have been autocompleted.
1034   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1035
1036   // If the password field is not autocompletable, it should not be affected.
1037   SetElementReadOnly(password_element_, true);
1038   EXPECT_FALSE(password_autofill_->AcceptSuggestion(
1039       username_element_, kAliceUsername, kAlicePassword));
1040   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
1041   SetElementReadOnly(password_element_, false);
1042
1043   // After accepting the suggestion, both fields should be autocompleted.
1044   EXPECT_TRUE(password_autofill_->AcceptSuggestion(
1045       username_element_, kAliceUsername, kAlicePassword));
1046   CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
1047   int username_length = strlen(kAliceUsername);
1048   CheckUsernameSelection(username_length, username_length);
1049
1050   // Try accepting a suggestion with a password different from the one that was
1051   // initially sent to the renderer.
1052   EXPECT_TRUE(password_autofill_->AcceptSuggestion(
1053       username_element_, kBobUsername, kCarolPassword));
1054   CheckTextFieldsDOMState(kBobUsername, true, kCarolPassword, true);
1055   username_length = strlen(kBobUsername);
1056   CheckUsernameSelection(username_length, username_length);
1057 }
1058
1059 // Tests that logging is off by default.
1060 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
1061   render_thread_->sink().ClearMessages();
1062   SendVisiblePasswordForms();
1063   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1064       AutofillHostMsg_RecordSavePasswordProgress::ID);
1065   EXPECT_FALSE(message);
1066 }
1067
1068 // Test that logging can be turned on by a message.
1069 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
1070   // Turn the logging on.
1071   AutofillMsg_ChangeLoggingState msg_activate(0, true);
1072   // Up-cast to access OnMessageReceived, which is private in the agent.
1073   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
1074                   ->OnMessageReceived(msg_activate));
1075
1076   render_thread_->sink().ClearMessages();
1077   SendVisiblePasswordForms();
1078   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1079       AutofillHostMsg_RecordSavePasswordProgress::ID);
1080   EXPECT_TRUE(message);
1081 }
1082
1083 // Test that logging can be turned off by a message.
1084 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
1085   // Turn the logging on and then off.
1086   AutofillMsg_ChangeLoggingState msg_activate(0, /*active=*/true);
1087   // Up-cast to access OnMessageReceived, which is private in the agent.
1088   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
1089                   ->OnMessageReceived(msg_activate));
1090   AutofillMsg_ChangeLoggingState msg_deactivate(0, /*active=*/false);
1091   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
1092                   ->OnMessageReceived(msg_deactivate));
1093
1094   render_thread_->sink().ClearMessages();
1095   SendVisiblePasswordForms();
1096   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
1097       AutofillHostMsg_RecordSavePasswordProgress::ID);
1098   EXPECT_FALSE(message);
1099 }
1100
1101 }  // namespace autofill