Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / autofill / password_generation_agent_browsertest.cc
1 // Copyright 2013 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 <string.h>
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/test/base/chrome_render_view_test.h"
10 #include "components/autofill/content/common/autofill_messages.h"
11 #include "components/autofill/content/renderer/autofill_agent.h"
12 #include "components/autofill/content/renderer/test_password_generation_agent.h"
13 #include "components/autofill/core/common/form_data.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/platform/WebString.h"
16 #include "third_party/WebKit/public/web/WebDocument.h"
17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
18 #include "third_party/WebKit/public/web/WebWidget.h"
19
20 using blink::WebDocument;
21 using blink::WebElement;
22 using blink::WebInputElement;
23 using blink::WebNode;
24 using blink::WebString;
25
26 namespace autofill {
27
28 class PasswordGenerationAgentTest : public ChromeRenderViewTest {
29  public:
30   PasswordGenerationAgentTest() {}
31
32   virtual void TearDown() {
33     LoadHTML("");
34     ChromeRenderViewTest::TearDown();
35   }
36
37   void SetNotBlacklistedMessage(const char* form_str) {
38     autofill::PasswordForm form;
39     form.origin =
40         GURL(base::StringPrintf("data:text/html;charset=utf-8,%s", form_str));
41     AutofillMsg_FormNotBlacklisted msg(0, form);
42     password_generation_->OnMessageReceived(msg);
43   }
44
45   void SetAccountCreationFormsDetectedMessage(const char* form_str) {
46     autofill::FormData form;
47     form.origin =
48         GURL(base::StringPrintf("data:text/html;charset=utf-8,%s", form_str));
49     std::vector<autofill::FormData> forms;
50     forms.push_back(form);
51     AutofillMsg_AccountCreationFormsDetected msg(0, forms);
52     password_generation_->OnMessageReceived(msg);
53   }
54
55   void ExpectPasswordGenerationAvailable(const char* element_id,
56                                          bool available) {
57     WebDocument document = GetMainFrame()->document();
58     WebElement element =
59         document.getElementById(WebString::fromUTF8(element_id));
60     ASSERT_FALSE(element.isNull());
61     WebInputElement target_element = element.to<WebInputElement>();
62     ExecuteJavaScript(
63         base::StringPrintf("document.getElementById('%s').focus();",
64                            element_id).c_str());
65     if (available) {
66       ASSERT_EQ(1u, password_generation_->messages().size());
67       EXPECT_EQ(AutofillHostMsg_ShowPasswordGenerationPopup::ID,
68                 password_generation_->messages()[0]->type());
69     } else {
70       EXPECT_EQ(0u, password_generation_->messages().size());
71     }
72     password_generation_->clear_messages();
73   }
74
75  private:
76   DISALLOW_COPY_AND_ASSIGN(PasswordGenerationAgentTest);
77 };
78
79 const char kSigninFormHTML[] =
80     "<FORM name = 'blah' action = 'http://www.random.com/'> "
81     "  <INPUT type = 'text' id = 'username'/> "
82     "  <INPUT type = 'password' id = 'password'/> "
83     "  <INPUT type = 'submit' value = 'LOGIN' />"
84     "</FORM>";
85
86 const char kAccountCreationFormHTML[] =
87     "<FORM name = 'blah' action = 'http://www.random.com/'> "
88     "  <INPUT type = 'text' id = 'username'/> "
89     "  <INPUT type = 'password' id = 'first_password' "
90     "         autocomplete = 'off' size = 5/>"
91     "  <INPUT type = 'password' id = 'second_password' size = 5/> "
92     "  <INPUT type = 'text' id = 'address'/> "
93     "  <INPUT type = 'submit' value = 'LOGIN' />"
94     "</FORM>";
95
96 const char kHiddenPasswordAccountCreationFormHTML[] =
97     "<FORM name = 'blah' action = 'http://www.random.com/'> "
98     "  <INPUT type = 'text' id = 'username'/> "
99     "  <INPUT type = 'password' id = 'first_password'/> "
100     "  <INPUT type = 'password' id = 'second_password' style='display:none'/> "
101     "  <INPUT type = 'submit' value = 'LOGIN' />"
102     "</FORM>";
103
104 const char kInvalidActionAccountCreationFormHTML[] =
105     "<FORM name = 'blah' action = 'invalid'> "
106     "  <INPUT type = 'text' id = 'username'/> "
107     "  <INPUT type = 'password' id = 'first_password'/> "
108     "  <INPUT type = 'password' id = 'second_password'/> "
109     "  <INPUT type = 'submit' value = 'LOGIN' />"
110     "</FORM>";
111
112 TEST_F(PasswordGenerationAgentTest, DetectionTest) {
113   // Don't shown the icon for non account creation forms.
114   LoadHTML(kSigninFormHTML);
115   ExpectPasswordGenerationAvailable("password", false);
116
117   // We don't show the decoration yet because the feature isn't enabled.
118   LoadHTML(kAccountCreationFormHTML);
119   ExpectPasswordGenerationAvailable("first_password", false);
120
121   // Pretend like We have received message indicating site is not blacklisted,
122   // and we have received message indicating the form is classified as
123   // ACCOUNT_CREATION_FORM form Autofill server. We should show the icon.
124   LoadHTML(kAccountCreationFormHTML);
125   SetNotBlacklistedMessage(kAccountCreationFormHTML);
126   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
127   ExpectPasswordGenerationAvailable("first_password", true);
128
129   // This doesn't trigger because hidden password fields are ignored.
130   LoadHTML(kHiddenPasswordAccountCreationFormHTML);
131   SetNotBlacklistedMessage(kHiddenPasswordAccountCreationFormHTML);
132   SetAccountCreationFormsDetectedMessage(
133       kHiddenPasswordAccountCreationFormHTML);
134   ExpectPasswordGenerationAvailable("first_password", false);
135
136   // This doesn't trigger because the form action is invalid.
137   LoadHTML(kInvalidActionAccountCreationFormHTML);
138   SetNotBlacklistedMessage(kInvalidActionAccountCreationFormHTML);
139   SetAccountCreationFormsDetectedMessage(kInvalidActionAccountCreationFormHTML);
140   ExpectPasswordGenerationAvailable("first_password", false);
141 }
142
143 TEST_F(PasswordGenerationAgentTest, FillTest) {
144   // Make sure that we are enabled before loading HTML.
145   LoadHTML(kAccountCreationFormHTML);
146
147   WebDocument document = GetMainFrame()->document();
148   WebElement element =
149       document.getElementById(WebString::fromUTF8("first_password"));
150   ASSERT_FALSE(element.isNull());
151   WebInputElement first_password_element = element.to<WebInputElement>();
152   element = document.getElementById(WebString::fromUTF8("second_password"));
153   ASSERT_FALSE(element.isNull());
154   WebInputElement second_password_element = element.to<WebInputElement>();
155
156   // Both password fields should be empty.
157   EXPECT_TRUE(first_password_element.value().isNull());
158   EXPECT_TRUE(second_password_element.value().isNull());
159
160   base::string16 password = base::ASCIIToUTF16("random_password");
161   AutofillMsg_GeneratedPasswordAccepted msg(0, password);
162   password_generation_->OnMessageReceived(msg);
163
164   // Password fields are filled out and set as being autofilled.
165   EXPECT_EQ(password, first_password_element.value());
166   EXPECT_EQ(password, second_password_element.value());
167   EXPECT_TRUE(first_password_element.isAutofilled());
168   EXPECT_TRUE(second_password_element.isAutofilled());
169
170   // Focus moved to the next input field.
171   // TODO(zysxqn): Change this back to the address element once Bug 90224
172   // https://bugs.webkit.org/show_bug.cgi?id=90224 has been fixed.
173   element = document.getElementById(WebString::fromUTF8("first_password"));
174   ASSERT_FALSE(element.isNull());
175   EXPECT_EQ(element, document.focusedElement());
176 }
177
178 TEST_F(PasswordGenerationAgentTest, EditingTest) {
179   LoadHTML(kAccountCreationFormHTML);
180   SetNotBlacklistedMessage(kAccountCreationFormHTML);
181   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
182
183   WebDocument document = GetMainFrame()->document();
184   WebElement element =
185       document.getElementById(WebString::fromUTF8("first_password"));
186   ASSERT_FALSE(element.isNull());
187   WebInputElement first_password_element = element.to<WebInputElement>();
188   element = document.getElementById(WebString::fromUTF8("second_password"));
189   ASSERT_FALSE(element.isNull());
190   WebInputElement second_password_element = element.to<WebInputElement>();
191
192   base::string16 password = base::ASCIIToUTF16("random_password");
193   AutofillMsg_GeneratedPasswordAccepted msg(0, password);
194   password_generation_->OnMessageReceived(msg);
195
196   // Passwords start out the same.
197   EXPECT_EQ(password, first_password_element.value());
198   EXPECT_EQ(password, second_password_element.value());
199
200   // After editing the first field they are still the same.
201   base::string16 edited_password = base::ASCIIToUTF16("edited_password");
202   first_password_element.setValue(edited_password);
203   // Cast to WebAutofillClient where textFieldDidChange() is public.
204   static_cast<blink::WebAutofillClient*>(autofill_agent_)->textFieldDidChange(
205       first_password_element);
206   // textFieldDidChange posts a task, so we need to wait until it's been
207   // processed.
208   base::MessageLoop::current()->RunUntilIdle();
209
210   EXPECT_EQ(edited_password, first_password_element.value());
211   EXPECT_EQ(edited_password, second_password_element.value());
212 }
213
214 TEST_F(PasswordGenerationAgentTest, BlacklistedTest) {
215   // Did not receive not blacklisted message. Don't show password generation
216   // icon.
217   LoadHTML(kAccountCreationFormHTML);
218   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
219   ExpectPasswordGenerationAvailable("first_password", false);
220
221   // Receive one not blacklisted message for non account creation form. Don't
222   // show password generation icon.
223   LoadHTML(kAccountCreationFormHTML);
224   SetNotBlacklistedMessage(kSigninFormHTML);
225   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
226   ExpectPasswordGenerationAvailable("first_password", false);
227
228   // Receive one not blackliste message for account creation form. Show password
229   // generation icon.
230   LoadHTML(kAccountCreationFormHTML);
231   SetNotBlacklistedMessage(kAccountCreationFormHTML);
232   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
233   ExpectPasswordGenerationAvailable("first_password", true);
234
235   // Receive two not blacklisted messages, one is for account creation form and
236   // the other is not. Show password generation icon.
237   LoadHTML(kAccountCreationFormHTML);
238   SetNotBlacklistedMessage(kAccountCreationFormHTML);
239   SetNotBlacklistedMessage(kSigninFormHTML);
240   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
241   ExpectPasswordGenerationAvailable("first_password", true);
242 }
243
244 TEST_F(PasswordGenerationAgentTest, AccountCreationFormsDetectedTest) {
245   // Did not receive account creation forms detected messege. Don't show
246   // password generation icon.
247   LoadHTML(kAccountCreationFormHTML);
248   SetNotBlacklistedMessage(kAccountCreationFormHTML);
249   ExpectPasswordGenerationAvailable("first_password", false);
250
251   // Receive the account creation forms detected message. Show password
252   // generation icon.
253   LoadHTML(kAccountCreationFormHTML);
254   SetNotBlacklistedMessage(kAccountCreationFormHTML);
255   SetAccountCreationFormsDetectedMessage(kAccountCreationFormHTML);
256   ExpectPasswordGenerationAvailable("first_password", true);
257 }
258
259 }  // namespace autofill