Home | History | Annotate | Download | only in autofill
      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 |FillSuggestion| properly fills the username and password.
   1027 TEST_F(PasswordAutofillAgentTest, FillSuggestion) {
   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_->FillSuggestion(
   1039       username_element_, kAliceUsername, kAlicePassword));
   1040   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
   1041   SetElementReadOnly(password_element_, false);
   1042 
   1043   // After filling with the suggestion, both fields should be autocompleted.
   1044   EXPECT_TRUE(password_autofill_->FillSuggestion(
   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 Filling with a suggestion with password different from the one that was
   1051   // initially sent to the renderer.
   1052   EXPECT_TRUE(password_autofill_->FillSuggestion(
   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 |PreviewSuggestion| properly previews the username and password.
   1060 TEST_F(PasswordAutofillAgentTest, PreviewSuggestion) {
   1061   // Simulate the browser sending the login info, but set |wait_for_username|
   1062   // to prevent the form from being immediately filled.
   1063   fill_data_.wait_for_username = true;
   1064   SimulateOnFillPasswordForm(fill_data_);
   1065 
   1066   // Neither field should have been autocompleted.
   1067   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
   1068 
   1069   // If the password field is not autocompletable, it should not be affected.
   1070   SetElementReadOnly(password_element_, true);
   1071   EXPECT_FALSE(password_autofill_->PreviewSuggestion(
   1072       username_element_, kAliceUsername, kAlicePassword));
   1073   EXPECT_EQ(std::string(), username_element_.suggestedValue().utf8());
   1074   EXPECT_FALSE(username_element_.isAutofilled());
   1075   EXPECT_EQ(std::string(), password_element_.suggestedValue().utf8());
   1076   EXPECT_FALSE(password_element_.isAutofilled());
   1077   SetElementReadOnly(password_element_, false);
   1078 
   1079   // After selecting the suggestion, both fields should be previewed
   1080   // with suggested values.
   1081   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1082       username_element_, kAliceUsername, kAlicePassword));
   1083   EXPECT_EQ(
   1084       kAliceUsername,
   1085       static_cast<std::string>(username_element_.suggestedValue().utf8()));
   1086   EXPECT_TRUE(username_element_.isAutofilled());
   1087   EXPECT_EQ(
   1088       kAlicePassword,
   1089       static_cast<std::string>(password_element_.suggestedValue().utf8()));
   1090   EXPECT_TRUE(password_element_.isAutofilled());
   1091   int username_length = strlen(kAliceUsername);
   1092   CheckUsernameSelection(0, username_length);
   1093 
   1094   // Try previewing with a password different from the one that was initially
   1095   // sent to the renderer.
   1096   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1097       username_element_, kBobUsername, kCarolPassword));
   1098   EXPECT_EQ(
   1099       kBobUsername,
   1100       static_cast<std::string>(username_element_.suggestedValue().utf8()));
   1101   EXPECT_TRUE(username_element_.isAutofilled());
   1102   EXPECT_EQ(
   1103       kCarolPassword,
   1104       static_cast<std::string>(password_element_.suggestedValue().utf8()));
   1105   EXPECT_TRUE(password_element_.isAutofilled());
   1106   username_length = strlen(kBobUsername);
   1107   CheckUsernameSelection(0, username_length);
   1108 }
   1109 
   1110 // Tests that |PreviewSuggestion| properly sets the username selection range.
   1111 TEST_F(PasswordAutofillAgentTest, PreviewSuggestionSelectionRange) {
   1112   username_element_.setValue(WebString::fromUTF8("ali"));
   1113   username_element_.setAutofilled(true);
   1114 
   1115   CheckTextFieldsDOMState("ali", true, std::string(), false);
   1116 
   1117   // Simulate the browser sending the login info, but set |wait_for_username|
   1118   // to prevent the form from being immediately filled.
   1119   fill_data_.wait_for_username = true;
   1120   SimulateOnFillPasswordForm(fill_data_);
   1121 
   1122   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1123       username_element_, kAliceUsername, kAlicePassword));
   1124   EXPECT_EQ(
   1125       kAliceUsername,
   1126       static_cast<std::string>(username_element_.suggestedValue().utf8()));
   1127   EXPECT_TRUE(username_element_.isAutofilled());
   1128   EXPECT_EQ(
   1129       kAlicePassword,
   1130       static_cast<std::string>(password_element_.suggestedValue().utf8()));
   1131   EXPECT_TRUE(password_element_.isAutofilled());
   1132   int username_length = strlen(kAliceUsername);
   1133   CheckUsernameSelection(3, username_length);
   1134 }
   1135 
   1136 // Tests that |ClearPreview| properly clears previewed username and password
   1137 // with password being previously autofilled.
   1138 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithPasswordAutofilled) {
   1139   password_element_.setValue(WebString::fromUTF8("sec"));
   1140   password_element_.setAutofilled(true);
   1141 
   1142   // Simulate the browser sending the login info, but set |wait_for_username|
   1143   // to prevent the form from being immediately filled.
   1144   fill_data_.wait_for_username = true;
   1145   SimulateOnFillPasswordForm(fill_data_);
   1146 
   1147   CheckTextFieldsDOMState(std::string(), false, "sec", true);
   1148 
   1149   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1150       username_element_, kAliceUsername, kAlicePassword));
   1151 
   1152   EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
   1153       username_element_));
   1154 
   1155   EXPECT_TRUE(username_element_.value().isEmpty());
   1156   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
   1157   EXPECT_FALSE(username_element_.isAutofilled());
   1158   EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
   1159   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
   1160   EXPECT_TRUE(password_element_.isAutofilled());
   1161   CheckUsernameSelection(0, 0);
   1162 }
   1163 
   1164 // Tests that |ClearPreview| properly clears previewed username and password
   1165 // with username being previously autofilled.
   1166 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithUsernameAutofilled) {
   1167   username_element_.setValue(WebString::fromUTF8("ali"));
   1168   username_element_.setAutofilled(true);
   1169 
   1170   // Simulate the browser sending the login info, but set |wait_for_username|
   1171   // to prevent the form from being immediately filled.
   1172   fill_data_.wait_for_username = true;
   1173   SimulateOnFillPasswordForm(fill_data_);
   1174 
   1175   CheckTextFieldsDOMState("ali", true, std::string(), false);
   1176 
   1177   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1178       username_element_, kAliceUsername, kAlicePassword));
   1179 
   1180   EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
   1181       username_element_));
   1182 
   1183   EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
   1184   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
   1185   EXPECT_TRUE(username_element_.isAutofilled());
   1186   EXPECT_TRUE(password_element_.value().isEmpty());
   1187   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
   1188   EXPECT_FALSE(password_element_.isAutofilled());
   1189   CheckUsernameSelection(3, 3);
   1190 }
   1191 
   1192 // Tests that |ClearPreview| properly clears previewed username and password
   1193 // with username and password being previously autofilled.
   1194 TEST_F(PasswordAutofillAgentTest,
   1195        ClearPreviewWithAutofilledUsernameAndPassword) {
   1196   username_element_.setValue(WebString::fromUTF8("ali"));
   1197   username_element_.setAutofilled(true);
   1198   password_element_.setValue(WebString::fromUTF8("sec"));
   1199   password_element_.setAutofilled(true);
   1200 
   1201   // Simulate the browser sending the login info, but set |wait_for_username|
   1202   // to prevent the form from being immediately filled.
   1203   fill_data_.wait_for_username = true;
   1204   SimulateOnFillPasswordForm(fill_data_);
   1205 
   1206   CheckTextFieldsDOMState("ali", true, "sec", true);
   1207 
   1208   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1209       username_element_, kAliceUsername, kAlicePassword));
   1210 
   1211   EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
   1212       username_element_));
   1213 
   1214   EXPECT_EQ(ASCIIToUTF16("ali"), username_element_.value());
   1215   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
   1216   EXPECT_TRUE(username_element_.isAutofilled());
   1217   EXPECT_EQ(ASCIIToUTF16("sec"), password_element_.value());
   1218   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
   1219   EXPECT_TRUE(password_element_.isAutofilled());
   1220   CheckUsernameSelection(3, 3);
   1221 }
   1222 
   1223 // Tests that |ClearPreview| properly clears previewed username and password
   1224 // with neither username nor password being previously autofilled.
   1225 TEST_F(PasswordAutofillAgentTest,
   1226        ClearPreviewWithNotAutofilledUsernameAndPassword) {
   1227   // Simulate the browser sending the login info, but set |wait_for_username|
   1228   // to prevent the form from being immediately filled.
   1229   fill_data_.wait_for_username = true;
   1230   SimulateOnFillPasswordForm(fill_data_);
   1231 
   1232   CheckTextFieldsDOMState(std::string(), false, std::string(), false);
   1233 
   1234   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1235       username_element_, kAliceUsername, kAlicePassword));
   1236 
   1237   EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
   1238       username_element_));
   1239 
   1240   EXPECT_TRUE(username_element_.value().isEmpty());
   1241   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
   1242   EXPECT_FALSE(username_element_.isAutofilled());
   1243   EXPECT_TRUE(password_element_.value().isEmpty());
   1244   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
   1245   EXPECT_FALSE(password_element_.isAutofilled());
   1246   CheckUsernameSelection(0, 0);
   1247 }
   1248 
   1249 // Tests that |ClearPreview| properly restores the original selection range of
   1250 // username field that has initially been filled by inline autocomplete.
   1251 TEST_F(PasswordAutofillAgentTest, ClearPreviewWithInlineAutocompletedUsername) {
   1252   // Simulate the browser sending back the login info.
   1253   SimulateOnFillPasswordForm(fill_data_);
   1254 
   1255   // Clear the text fields to start fresh.
   1256   ClearUsernameAndPasswordFields();
   1257 
   1258   // Simulate the user typing in the first letter of 'alice', a stored username.
   1259   SimulateUsernameChange("a", true);
   1260   // Both the username and password text fields should reflect selection of the
   1261   // stored login.
   1262   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
   1263   // The selection should have been set to 'lice', the last 4 letters.
   1264   CheckUsernameSelection(1, 5);
   1265 
   1266   EXPECT_TRUE(password_autofill_->PreviewSuggestion(
   1267       username_element_, "alicia", "secret"));
   1268   EXPECT_EQ(
   1269       "alicia",
   1270       static_cast<std::string>(username_element_.suggestedValue().utf8()));
   1271   EXPECT_TRUE(username_element_.isAutofilled());
   1272   EXPECT_EQ(
   1273       "secret",
   1274       static_cast<std::string>(password_element_.suggestedValue().utf8()));
   1275   EXPECT_TRUE(password_element_.isAutofilled());
   1276   CheckUsernameSelection(1, 6);
   1277 
   1278   EXPECT_TRUE(password_autofill_->DidClearAutofillSelection(
   1279       username_element_));
   1280 
   1281   EXPECT_EQ(kAliceUsername, username_element_.value().utf8());
   1282   EXPECT_TRUE(username_element_.suggestedValue().isEmpty());
   1283   EXPECT_TRUE(username_element_.isAutofilled());
   1284   EXPECT_TRUE(password_element_.value().isEmpty());
   1285   EXPECT_TRUE(password_element_.suggestedValue().isEmpty());
   1286   EXPECT_TRUE(password_element_.isAutofilled());
   1287   CheckUsernameSelection(1, 5);
   1288 }
   1289 
   1290 // Tests that logging is off by default.
   1291 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_NoMessage) {
   1292   render_thread_->sink().ClearMessages();
   1293   SendVisiblePasswordForms();
   1294   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
   1295       AutofillHostMsg_RecordSavePasswordProgress::ID);
   1296   EXPECT_FALSE(message);
   1297 }
   1298 
   1299 // Test that logging can be turned on by a message.
   1300 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Activated) {
   1301   // Turn the logging on.
   1302   AutofillMsg_SetLoggingState msg_activate(0, true);
   1303   // Up-cast to access OnMessageReceived, which is private in the agent.
   1304   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
   1305                   ->OnMessageReceived(msg_activate));
   1306 
   1307   render_thread_->sink().ClearMessages();
   1308   SendVisiblePasswordForms();
   1309   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
   1310       AutofillHostMsg_RecordSavePasswordProgress::ID);
   1311   EXPECT_TRUE(message);
   1312 }
   1313 
   1314 // Test that logging can be turned off by a message.
   1315 TEST_F(PasswordAutofillAgentTest, OnChangeLoggingState_Deactivated) {
   1316   // Turn the logging on and then off.
   1317   AutofillMsg_SetLoggingState msg_activate(0, /*active=*/true);
   1318   // Up-cast to access OnMessageReceived, which is private in the agent.
   1319   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
   1320                   ->OnMessageReceived(msg_activate));
   1321   AutofillMsg_SetLoggingState msg_deactivate(0, /*active=*/false);
   1322   EXPECT_TRUE(static_cast<IPC::Listener*>(password_autofill_)
   1323                   ->OnMessageReceived(msg_deactivate));
   1324 
   1325   render_thread_->sink().ClearMessages();
   1326   SendVisiblePasswordForms();
   1327   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
   1328       AutofillHostMsg_RecordSavePasswordProgress::ID);
   1329   EXPECT_FALSE(message);
   1330 }
   1331 
   1332 // Test that the agent sends an IPC call to get the current activity state of
   1333 // password saving logging soon after construction.
   1334 TEST_F(PasswordAutofillAgentTest, SendsLoggingStateUpdatePingOnConstruction) {
   1335   const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
   1336       AutofillHostMsg_PasswordAutofillAgentConstructed::ID);
   1337   EXPECT_TRUE(message);
   1338 }
   1339 
   1340 }  // namespace autofill
   1341