- add sources.
[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/renderer/autofill_agent.h"
9 #include "components/autofill/content/renderer/form_autofill_util.h"
10 #include "components/autofill/content/renderer/password_autofill_agent.h"
11 #include "components/autofill/content/renderer/test_password_autofill_agent.h"
12 #include "components/autofill/core/common/autofill_messages.h"
13 #include "components/autofill/core/common/form_data.h"
14 #include "components/autofill/core/common/form_field_data.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebString.h"
17 #include "third_party/WebKit/public/platform/WebVector.h"
18 #include "third_party/WebKit/public/web/WebDocument.h"
19 #include "third_party/WebKit/public/web/WebElement.h"
20 #include "third_party/WebKit/public/web/WebFormElement.h"
21 #include "third_party/WebKit/public/web/WebInputElement.h"
22 #include "third_party/WebKit/public/web/WebNode.h"
23 #include "third_party/WebKit/public/web/WebView.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
25
26 using autofill::PasswordForm;
27 using WebKit::WebDocument;
28 using WebKit::WebElement;
29 using WebKit::WebFrame;
30 using WebKit::WebInputElement;
31 using WebKit::WebString;
32 using WebKit::WebView;
33
34 namespace {
35
36 // The name of the username/password element in the form.
37 const char kUsernameName[] = "username";
38 const char kPasswordName[] = "password";
39
40 const char kAliceUsername[] = "alice";
41 const char kAlicePassword[] = "password";
42 const char kBobUsername[] = "bob";
43 const char kBobPassword[] = "secret";
44 const char kCarolUsername[] = "Carol";
45 const char kCarolPassword[] = "test";
46 const char kCarolAlternateUsername[] = "RealCarolUsername";
47
48
49 const char kFormHTML[] =
50     "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
51     "  <INPUT type='text' id='username'/>"
52     "  <INPUT type='password' id='password'/>"
53     "  <INPUT type='submit' value='Login'/>"
54     "</FORM>";
55
56 const char kVisibleFormHTML[] =
57     "<head> <style> form {display: inline;} </style> </head>"
58     "<body>"
59     "  <form>"
60     "    <div>"
61     "      <input type='password' id='password'/>"
62     "    </div>"
63     "  </form>"
64     "</body>";
65
66 const char kEmptyFormHTML[] =
67     "<head> <style> form {display: inline;} </style> </head>"
68     "<body> <form> </form> </body>";
69
70 const char kNonVisibleFormHTML[] =
71     "<head> <style> form {display: none;} </style> </head>"
72     "<body>"
73     "  <form>"
74     "    <div>"
75     "      <input type='password' id='password'/>"
76     "    </div>"
77     "  </form>"
78     "</body>";
79
80 const char kEmptyWebpage[] =
81     "<html>"
82     "   <head>"
83     "   </head>"
84     "   <body>"
85     "   </body>"
86     "</html>";
87
88 const char kRedirectionWebpage[] =
89     "<html>"
90     "   <head>"
91     "       <meta http-equiv='Content-Type' content='text/html'>"
92     "       <title>Redirection page</title>"
93     "       <script></script>"
94     "   </head>"
95     "   <body>"
96     "       <script type='text/javascript'>"
97     "         function test(){}"
98     "       </script>"
99     "   </body>"
100     "</html>";
101
102 const char kSimpleWebpage[] =
103     "<html>"
104     "   <head>"
105     "       <meta charset='utf-8' />"
106     "       <title>Title</title>"
107     "   </head>"
108     "   <body>"
109     "       <form name='LoginTestForm'>"
110     "           <input type='text' id='username'/>"
111     "           <input type='password' id='password'/>"
112     "           <input type='submit' value='Login'/>"
113     "       </form>"
114     "   </body>"
115     "</html>";
116
117 const char kWebpageWithDynamicContent[] =
118     "<html>"
119     "   <head>"
120     "       <meta charset='utf-8' />"
121     "       <title>Title</title>"
122     "   </head>"
123     "   <body>"
124     "       <script type='text/javascript'>"
125     "           function addParagraph() {"
126     "             var p = document.createElement('p');"
127     "             document.body.appendChild(p);"
128     "            }"
129     "           window.onload = addParagraph;"
130     "       </script>"
131     "   </body>"
132     "</html>";
133
134 }  // namespace
135
136 namespace autofill {
137
138 class PasswordAutofillAgentTest : public ChromeRenderViewTest {
139  public:
140   PasswordAutofillAgentTest() {
141   }
142
143   // Simulates the fill password form message being sent to the renderer.
144   // We use that so we don't have to make RenderView::OnFillPasswordForm()
145   // protected.
146   void SimulateOnFillPasswordForm(
147       const PasswordFormFillData& fill_data) {
148     AutofillMsg_FillPasswordForm msg(0, fill_data);
149     password_autofill_->OnMessageReceived(msg);
150   }
151
152   virtual void SetUp() {
153     ChromeRenderViewTest::SetUp();
154
155     // Add a preferred login and an additional login to the FillData.
156     username1_ = ASCIIToUTF16(kAliceUsername);
157     password1_ = ASCIIToUTF16(kAlicePassword);
158     username2_ = ASCIIToUTF16(kBobUsername);
159     password2_ = ASCIIToUTF16(kBobPassword);
160     username3_ = ASCIIToUTF16(kCarolUsername);
161     password3_ = ASCIIToUTF16(kCarolPassword);
162     alternate_username3_ = ASCIIToUTF16(kCarolAlternateUsername);
163
164     FormFieldData username_field;
165     username_field.name = ASCIIToUTF16(kUsernameName);
166     username_field.value = username1_;
167     fill_data_.basic_data.fields.push_back(username_field);
168
169     FormFieldData password_field;
170     password_field.name = ASCIIToUTF16(kPasswordName);
171     password_field.value = password1_;
172     password_field.form_control_type = "password";
173     fill_data_.basic_data.fields.push_back(password_field);
174
175     PasswordAndRealm password2;
176     password2.password = password2_;
177     fill_data_.additional_logins[username2_] = password2;
178     PasswordAndRealm password3;
179     password3.password = password3_;
180     fill_data_.additional_logins[username3_] = password3;
181
182     UsernamesCollectionKey key;
183     key.username = username3_;
184     key.password = password3_;
185     key.realm = "google.com";
186     fill_data_.other_possible_usernames[key].push_back(alternate_username3_);
187
188     // We need to set the origin so it matches the frame URL and the action so
189     // it matches the form action, otherwise we won't autocomplete.
190     std::string origin("data:text/html;charset=utf-8,");
191     origin += kFormHTML;
192     fill_data_.basic_data.origin = GURL(origin);
193     fill_data_.basic_data.action = GURL("http://www.bidule.com");
194
195     LoadHTML(kFormHTML);
196
197     // Now retrieves the input elements so the test can access them.
198     WebDocument document = GetMainFrame()->document();
199     WebElement element =
200         document.getElementById(WebString::fromUTF8(kUsernameName));
201     ASSERT_FALSE(element.isNull());
202     username_element_ = element.to<WebKit::WebInputElement>();
203     element = document.getElementById(WebString::fromUTF8(kPasswordName));
204     ASSERT_FALSE(element.isNull());
205     password_element_ = element.to<WebKit::WebInputElement>();
206   }
207
208   virtual void TearDown() {
209     username_element_.reset();
210     password_element_.reset();
211     ChromeRenderViewTest::TearDown();
212   }
213
214   void ClearUsernameAndPasswordFields() {
215     username_element_.setValue("");
216     username_element_.setAutofilled(false);
217     password_element_.setValue("");
218     password_element_.setAutofilled(false);
219   }
220
221   void SimulateUsernameChange(const std::string& username,
222                               bool move_caret_to_end) {
223     username_element_.setValue(WebString::fromUTF8(username));
224     // The field must have focus or AutofillAgent will think the
225     // change should be ignored.
226     while (!username_element_.focused())
227       GetMainFrame()->document().frame()->view()->advanceFocus(false);
228     if (move_caret_to_end)
229       username_element_.setSelectionRange(username.length(), username.length());
230     autofill_agent_->textFieldDidChange(username_element_);
231     // Processing is delayed because of a WebKit bug, see
232     // PasswordAutocompleteManager::TextDidChangeInTextField() for details.
233     base::MessageLoop::current()->RunUntilIdle();
234   }
235
236   void SimulateKeyDownEvent(const WebInputElement& element,
237                             ui::KeyboardCode key_code) {
238     WebKit::WebKeyboardEvent key_event;
239     key_event.windowsKeyCode = key_code;
240     autofill_agent_->textFieldDidReceiveKeyDown(element, key_event);
241   }
242
243   void CheckTextFieldsState(const std::string& username,
244                             bool username_autofilled,
245                             const std::string& password,
246                             bool password_autofilled) {
247     EXPECT_EQ(username,
248               static_cast<std::string>(username_element_.value().utf8()));
249     EXPECT_EQ(username_autofilled, username_element_.isAutofilled());
250     EXPECT_EQ(password,
251               static_cast<std::string>(password_element_.value().utf8()));
252     EXPECT_EQ(password_autofilled, password_element_.isAutofilled());
253   }
254
255   void CheckUsernameSelection(int start, int end) {
256     EXPECT_EQ(start, username_element_.selectionStart());
257     EXPECT_EQ(end, username_element_.selectionEnd());
258   }
259
260   string16 username1_;
261   string16 username2_;
262   string16 username3_;
263   string16 password1_;
264   string16 password2_;
265   string16 password3_;
266   string16 alternate_username3_;
267   PasswordFormFillData fill_data_;
268
269   WebInputElement username_element_;
270   WebInputElement password_element_;
271
272  private:
273   DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgentTest);
274 };
275
276 // Tests that the password login is autocompleted as expected when the browser
277 // sends back the password info.
278 TEST_F(PasswordAutofillAgentTest, InitialAutocomplete) {
279   /*
280    * Right now we are not sending the message to the browser because we are
281    * loading a data URL and the security origin canAccessPasswordManager()
282    * returns false.  May be we should mock URL loading to cirmcuvent this?
283    TODO(jcivelli): find a way to make the security origin not deny access to the
284                    password manager and then reenable this code.
285
286   // The form has been loaded, we should have sent the browser a message about
287   // the form.
288   const IPC::Message* msg = render_thread_.sink().GetFirstMessageMatching(
289       AutofillHostMsg_PasswordFormsParsed::ID);
290   ASSERT_TRUE(msg != NULL);
291
292   Tuple1<std::vector<PasswordForm> > forms;
293   AutofillHostMsg_PasswordFormsParsed::Read(msg, &forms);
294   ASSERT_EQ(1U, forms.a.size());
295   PasswordForm password_form = forms.a[0];
296   EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form.scheme);
297   EXPECT_EQ(ASCIIToUTF16(kUsernameName), password_form.username_element);
298   EXPECT_EQ(ASCIIToUTF16(kPasswordName), password_form.password_element);
299   */
300
301   // Simulate the browser sending back the login info, it triggers the
302   // autocomplete.
303   SimulateOnFillPasswordForm(fill_data_);
304
305   // The username and password should have been autocompleted.
306   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
307 }
308
309 // Tests that we correctly fill forms having an empty 'action' attribute.
310 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
311   const char kEmptyActionFormHTML[] =
312       "<FORM name='LoginTestForm'>"
313       "  <INPUT type='text' id='username'/>"
314       "  <INPUT type='password' id='password'/>"
315       "  <INPUT type='submit' value='Login'/>"
316       "</FORM>";
317   LoadHTML(kEmptyActionFormHTML);
318
319   // Retrieve the input elements so the test can access them.
320   WebDocument document = GetMainFrame()->document();
321   WebElement element =
322       document.getElementById(WebString::fromUTF8(kUsernameName));
323   ASSERT_FALSE(element.isNull());
324   username_element_ = element.to<WebKit::WebInputElement>();
325   element = document.getElementById(WebString::fromUTF8(kPasswordName));
326   ASSERT_FALSE(element.isNull());
327   password_element_ = element.to<WebKit::WebInputElement>();
328
329   // Set the expected form origin and action URLs.
330   std::string origin("data:text/html;charset=utf-8,");
331   origin += kEmptyActionFormHTML;
332   fill_data_.basic_data.origin = GURL(origin);
333   fill_data_.basic_data.action = GURL(origin);
334
335   // Simulate the browser sending back the login info, it triggers the
336   // autocomplete.
337   SimulateOnFillPasswordForm(fill_data_);
338
339   // The username and password should have been autocompleted.
340   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
341 }
342
343 // Tests that if a password or input element is marked as readonly, neither
344 // field is autofilled on page load.
345 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForReadOnly) {
346   password_element_.setAttribute(WebString::fromUTF8("readonly"),
347                                  WebString::fromUTF8("true"));
348
349   // Simulate the browser sending back the login info, it triggers the
350   // autocomplete.
351   SimulateOnFillPasswordForm(fill_data_);
352
353   CheckTextFieldsState(std::string(), false, std::string(), false);
354 }
355
356 // Tests that having a non-matching username precludes the autocomplete.
357 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForFilledField) {
358   username_element_.setValue(WebString::fromUTF8("bogus"));
359
360   // Simulate the browser sending back the login info, it triggers the
361   // autocomplete.
362   SimulateOnFillPasswordForm(fill_data_);
363
364   // Neither field should be autocompleted.
365   CheckTextFieldsState("bogus", false, std::string(), false);
366 }
367
368 // Tests that we do not autofill username/passwords if marked as
369 // autocomplete="off".
370 TEST_F(PasswordAutofillAgentTest, NoInitialAutocompleteForAutocompleteOff) {
371   username_element_.setAttribute(WebString::fromUTF8("autocomplete"),
372                                  WebString::fromUTF8("off"));
373
374   // Simulate the browser sending back the login info, it triggers the
375   // autocomplete.
376   SimulateOnFillPasswordForm(fill_data_);
377
378   CheckTextFieldsState(std::string(), false, std::string(), false);
379 }
380
381 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForTextFieldPasswords) {
382   const char kTextFieldPasswordFormHTML[] =
383       "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
384       "  <INPUT type='text' id='username'/>"
385       "  <INPUT type='text' id='password'/>"
386       "  <INPUT type='submit' value='Login'/>"
387       "</FORM>";
388   LoadHTML(kTextFieldPasswordFormHTML);
389
390   // Retrieve the input elements so the test can access them.
391   WebDocument document = GetMainFrame()->document();
392   WebElement element =
393       document.getElementById(WebString::fromUTF8(kUsernameName));
394   ASSERT_FALSE(element.isNull());
395   username_element_ = element.to<WebKit::WebInputElement>();
396   element = document.getElementById(WebString::fromUTF8(kPasswordName));
397   ASSERT_FALSE(element.isNull());
398   password_element_ = element.to<WebKit::WebInputElement>();
399
400   // Set the expected form origin URL.
401   std::string origin("data:text/html;charset=utf-8,");
402   origin += kTextFieldPasswordFormHTML;
403   fill_data_.basic_data.origin = GURL(origin);
404
405   SimulateOnFillPasswordForm(fill_data_);
406
407   // Fields should still be empty.
408   CheckTextFieldsState(std::string(), false, std::string(), false);
409 }
410
411 TEST_F(PasswordAutofillAgentTest, NoAutocompleteForPasswordFieldUsernames) {
412   const char kPasswordFieldUsernameFormHTML[] =
413       "<FORM name='LoginTestForm' action='http://www.bidule.com'>"
414       "  <INPUT type='password' id='username'/>"
415       "  <INPUT type='password' id='password'/>"
416       "  <INPUT type='submit' value='Login'/>"
417       "</FORM>";
418   LoadHTML(kPasswordFieldUsernameFormHTML);
419
420   // Retrieve the input elements so the test can access them.
421   WebDocument document = GetMainFrame()->document();
422   WebElement element =
423       document.getElementById(WebString::fromUTF8(kUsernameName));
424   ASSERT_FALSE(element.isNull());
425   username_element_ = element.to<WebKit::WebInputElement>();
426   element = document.getElementById(WebString::fromUTF8(kPasswordName));
427   ASSERT_FALSE(element.isNull());
428   password_element_ = element.to<WebKit::WebInputElement>();
429
430   // Set the expected form origin URL.
431   std::string origin("data:text/html;charset=utf-8,");
432   origin += kPasswordFieldUsernameFormHTML;
433   fill_data_.basic_data.origin = GURL(origin);
434
435   SimulateOnFillPasswordForm(fill_data_);
436
437   // Fields should still be empty.
438   CheckTextFieldsState(std::string(), false, std::string(), false);
439 }
440
441 // Tests that having a matching username does not preclude the autocomplete.
442 TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForMatchingFilledField) {
443   username_element_.setValue(WebString::fromUTF8(kAliceUsername));
444
445   // Simulate the browser sending back the login info, it triggers the
446   // autocomplete.
447   SimulateOnFillPasswordForm(fill_data_);
448
449   // The username and password should have been autocompleted.
450   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
451 }
452
453 // Tests that editing the password clears the autocompleted password field.
454 TEST_F(PasswordAutofillAgentTest, PasswordClearOnEdit) {
455   // Simulate the browser sending back the login info, it triggers the
456   // autocomplete.
457   SimulateOnFillPasswordForm(fill_data_);
458
459   // Simulate the user changing the username to some unknown username.
460   SimulateUsernameChange("alicia", true);
461
462   // The password should have been cleared.
463   CheckTextFieldsState("alicia", false, std::string(), false);
464 }
465
466 // Tests that we only autocomplete on focus lost and with a full username match
467 // when |wait_for_username| is true.
468 TEST_F(PasswordAutofillAgentTest, WaitUsername) {
469   // Simulate the browser sending back the login info.
470   fill_data_.wait_for_username = true;
471   SimulateOnFillPasswordForm(fill_data_);
472
473   // No auto-fill should have taken place.
474   CheckTextFieldsState(std::string(), false, std::string(), false);
475
476   // No autocomplete should happen when text is entered in the username.
477   SimulateUsernameChange("a", true);
478   CheckTextFieldsState("a", false, std::string(), false);
479   SimulateUsernameChange("al", true);
480   CheckTextFieldsState("al", false, std::string(), false);
481   SimulateUsernameChange(kAliceUsername, true);
482   CheckTextFieldsState(kAliceUsername, false, std::string(), false);
483
484   // Autocomplete should happen only when the username textfield is blurred with
485   // a full match.
486   username_element_.setValue("a");
487   autofill_agent_->textFieldDidEndEditing(username_element_);
488   CheckTextFieldsState("a", false, std::string(), false);
489   username_element_.setValue("al");
490   autofill_agent_->textFieldDidEndEditing(username_element_);
491   CheckTextFieldsState("al", false, std::string(), false);
492   username_element_.setValue("alices");
493   autofill_agent_->textFieldDidEndEditing(username_element_);
494   CheckTextFieldsState("alices", false, std::string(), false);
495   username_element_.setValue(ASCIIToUTF16(kAliceUsername));
496   autofill_agent_->textFieldDidEndEditing(username_element_);
497   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
498 }
499
500 // Tests that inline autocompletion works properly.
501 TEST_F(PasswordAutofillAgentTest, InlineAutocomplete) {
502   // Simulate the browser sending back the login info.
503   SimulateOnFillPasswordForm(fill_data_);
504
505   // Clear the text fields to start fresh.
506   ClearUsernameAndPasswordFields();
507
508   // Simulate the user typing in the first letter of 'alice', a stored username.
509   SimulateUsernameChange("a", true);
510   // Both the username and password text fields should reflect selection of the
511   // stored login.
512   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
513   // And the selection should have been set to 'lice', the last 4 letters.
514   CheckUsernameSelection(1, 5);
515
516   // Now the user types the next letter of the same username, 'l'.
517   SimulateUsernameChange("al", true);
518   // Now the fields should have the same value, but the selection should have a
519   // different start value.
520   CheckTextFieldsState(kAliceUsername, true, kAlicePassword, true);
521   CheckUsernameSelection(2, 5);
522
523   // Test that deleting does not trigger autocomplete.
524   SimulateKeyDownEvent(username_element_, ui::VKEY_BACK);
525   SimulateUsernameChange("alic", true);
526   CheckTextFieldsState("alic", false, std::string(), false);
527   CheckUsernameSelection(4, 4);  // No selection.
528   // Reset the last pressed key to something other than backspace.
529   SimulateKeyDownEvent(username_element_, ui::VKEY_A);
530
531   // Now lets say the user goes astray from the stored username and types the
532   // letter 'f', spelling 'alf'.  We don't know alf (that's just sad), so in
533   // practice the username should no longer be 'alice' and the selected range
534   // should be empty.
535   SimulateUsernameChange("alf", true);
536   CheckTextFieldsState("alf", false, std::string(), false);
537   CheckUsernameSelection(3, 3);  // No selection.
538
539   // Ok, so now the user removes all the text and enters the letter 'b'.
540   SimulateUsernameChange("b", true);
541   // The username and password fields should match the 'bob' entry.
542   CheckTextFieldsState(kBobUsername, true, kBobPassword, true);
543   CheckUsernameSelection(1, 3);
544
545   // Then, the user again removes all the text and types an uppercase 'C'.
546   SimulateUsernameChange("C", true);
547   // The username and password fields should match the 'Carol' entry.
548   CheckTextFieldsState(kCarolUsername, true, kCarolPassword, true);
549   CheckUsernameSelection(1, 5);
550   // The user removes all the text and types a lowercase 'c'.  We only
551   // want case-sensitive autocompletion, so the username and the selected range
552   // should be empty.
553   SimulateUsernameChange("c", true);
554   CheckTextFieldsState("c", false, std::string(), false);
555   CheckUsernameSelection(1, 1);
556
557   // Check that we complete other_possible_usernames as well.
558   SimulateUsernameChange("R", true);
559   CheckTextFieldsState(kCarolAlternateUsername, true, kCarolPassword, true);
560   CheckUsernameSelection(1, 17);
561 }
562
563 // Tests that selecting an item in the suggestion drop-down no-ops.
564 TEST_F(PasswordAutofillAgentTest, SuggestionSelect) {
565   // Simulate the browser sending back the login info.
566   SimulateOnFillPasswordForm(fill_data_);
567
568   // Clear the text fields to start fresh.
569   ClearUsernameAndPasswordFields();
570
571   // To simulate accepting an item in the suggestion drop-down we just mimic
572   // what the WebView does: it sets the element value then calls
573   // didSelectAutofillSuggestion on the renderer.
574   autofill_agent_->didSelectAutofillSuggestion(username_element_,
575                                                ASCIIToUTF16(kAliceUsername),
576                                                WebKit::WebString(),
577                                                0);
578   // Autocomplete should not have kicked in.
579   CheckTextFieldsState(std::string(), false, std::string(), false);
580 }
581
582 TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) {
583   WebKit::WebVector<WebKit::WebFormElement> forms1, forms2, forms3;
584   WebKit::WebFrame* frame;
585
586   LoadHTML(kVisibleFormHTML);
587   frame = GetMainFrame();
588   frame->document().forms(forms1);
589   ASSERT_EQ(1u, forms1.size());
590   EXPECT_TRUE(IsWebNodeVisible(forms1[0]));
591
592   LoadHTML(kEmptyFormHTML);
593   frame = GetMainFrame();
594   frame->document().forms(forms2);
595   ASSERT_EQ(1u, forms2.size());
596   EXPECT_FALSE(IsWebNodeVisible(forms2[0]));
597
598   LoadHTML(kNonVisibleFormHTML);
599   frame = GetMainFrame();
600   frame->document().forms(forms3);
601   ASSERT_EQ(1u, forms3.size());
602   EXPECT_FALSE(IsWebNodeVisible(forms3[0]));
603 }
604
605 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest) {
606   render_thread_->sink().ClearMessages();
607   LoadHTML(kVisibleFormHTML);
608   const IPC::Message* message = render_thread_->sink()
609       .GetFirstMessageMatching(AutofillHostMsg_PasswordFormsRendered::ID);
610   EXPECT_TRUE(message);
611   Tuple1<std::vector<autofill::PasswordForm> > param;
612   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
613   EXPECT_TRUE(param.a.size());
614
615   render_thread_->sink().ClearMessages();
616   LoadHTML(kEmptyFormHTML);
617   message = render_thread_->sink().GetFirstMessageMatching(
618       AutofillHostMsg_PasswordFormsRendered::ID);
619   EXPECT_TRUE(message);
620   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
621   EXPECT_FALSE(param.a.size());
622
623   render_thread_->sink().ClearMessages();
624   LoadHTML(kNonVisibleFormHTML);
625   message = render_thread_->sink().GetFirstMessageMatching(
626       AutofillHostMsg_PasswordFormsRendered::ID);
627   EXPECT_TRUE(message);
628   AutofillHostMsg_PasswordFormsRendered::Read(message, &param);
629   EXPECT_FALSE(param.a.size());
630 }
631
632 TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_Redirection) {
633   render_thread_->sink().ClearMessages();
634   LoadHTML(kEmptyWebpage);
635   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
636       AutofillHostMsg_PasswordFormsRendered::ID));
637
638   render_thread_->sink().ClearMessages();
639   LoadHTML(kRedirectionWebpage);
640   EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
641       AutofillHostMsg_PasswordFormsRendered::ID));
642
643   render_thread_->sink().ClearMessages();
644   LoadHTML(kSimpleWebpage);
645   EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
646       AutofillHostMsg_PasswordFormsRendered::ID));
647
648   render_thread_->sink().ClearMessages();
649   LoadHTML(kWebpageWithDynamicContent);
650   EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
651       AutofillHostMsg_PasswordFormsRendered::ID));
652 }
653
654 }  // namespace autofill